SpinalHDL之RegIf(下篇)

本文作为SpinalHDL学习笔记第二十二篇,介绍SpinalHDL RegIf相关API。

SpinalHDL学习笔记总纲链接如下:

SpinalHDL 学习笔记_spinalhdl blackbox-CSDN博客

目录:

6.典型例子

7.中断生成器

8.默认读取值

6.典型例子

批量创建 REG-Address 和字段寄存器:

import spinal.lib.bus.regif._
class RegBank extends Component {
val io = new Bundle {
val apb = slave(Apb3(Apb3Config(16, 32)))
val stats = in Vec(Bits(16 bit), 10)
val IQ = out Vec(Bits(16 bit), 10)
}
val busif = Apb3BusInterface(io.apb, (0x000, 100 Byte), regPre = "AP")
(0 to 9).map { i =>
//here use setName give REG uniq name for Docs usage
val REG = busif.newReg(doc = s"Register${i}").setName(s"REG${i}")
val real = REG.field(SInt(8 bit), AccessType.RW, 0, "Complex real")
val imag = REG.field(SInt(8 bit), AccessType.RW, 0, "Complex imag")
val stat = REG.field(Bits(16 bit), AccessType.RO, 0, "Accelerator status")
io.IQ(i)( 7 downto 0) := real.asBits
io.IQ(i)(15 downto 8) := imag.asBits
stat := io.stats(i)
}
def genDocs() = {
busif.accept(CHeaderGenerator("regbank", "AP"))
busif.accept(HtmlGenerator("regbank", "Interupt Example"))
busif.accept(JsonGenerator("regbank"))
busif.accept(RalfGenerator("regbank"))
busif.accept(SystemRdlGenerator("regbank", "AP"))
}
this.genDocs()
}
SpinalVerilog(new RegBank())

7.中断生成器

手动写中断:

class cpInterruptExample extends Component {
val io = new Bundle {
val tx_done, rx_done, frame_end = in Bool()
val interrupt = out Bool()
val apb = slave(Apb3(Apb3Config(16, 32)))
}
val busif = Apb3BusInterface(io.apb, (0x000, 100 Byte), regPre = "AP")
val M_CP_INT_RAW = busif.newReg(doc="cp int raw register")
val tx_int_raw = M_CP_INT_RAW.field(Bool(), W1C, doc="tx interrupt enable␣
,→register")
val rx_int_raw = M_CP_INT_RAW.field(Bool(), W1C, doc="rx interrupt enable␣
,→register")
val frame_int_raw = M_CP_INT_RAW.field(Bool(), W1C, doc="frame interrupt enable register")
val M_CP_INT_FORCE = busif.newReg(doc="cp int force register\n for debug use")
val tx_int_force = M_CP_INT_FORCE.field(Bool(), RW, doc="tx interrupt␣
,→enable register")
val rx_int_force = M_CP_INT_FORCE.field(Bool(), RW, doc="rx interrupt␣
,→enable register")
val frame_int_force = M_CP_INT_FORCE.field(Bool(), RW, doc="frame interrupt␣
,→enable register")
val M_CP_INT_MASK = busif.newReg(doc="cp int mask register")
val tx_int_mask = M_CP_INT_MASK.field(Bool(), RW, doc="tx interrupt mask␣
,→register")
val rx_int_mask = M_CP_INT_MASK.field(Bool(), RW, doc="rx interrupt mask␣
,→register")
val frame_int_mask = M_CP_INT_MASK.field(Bool(), RW, doc="frame interrupt␣
,→mask register")
val M_CP_INT_STATUS = busif.newReg(doc="cp int state register")
val tx_int_status = M_CP_INT_STATUS.field(Bool(), RO, doc="tx interrupt␣
,→state register")
val rx_int_status = M_CP_INT_STATUS.field(Bool(), RO, doc="rx interrupt␣
,→state register")
val frame_int_status = M_CP_INT_STATUS.field(Bool(), RO, doc="frame interrupt␣
,→state register")
rx_int_raw.setWhen(io.rx_done)
tx_int_raw.setWhen(io.tx_done)
frame_int_raw.setWhen(io.frame_end)
rx_int_status := (rx_int_raw || rx_int_force) && (!rx_int_mask)
tx_int_status := (tx_int_raw || rx_int_force) && (!rx_int_mask)
frame_int_status := (frame_int_raw || frame_int_force) && (!frame_int_mask)
io.interrupt := rx_int_status || tx_int_status || frame_int_status
}

这是一项非常繁琐且重复的工作,更好的方法是使用“生成器 (factory)”范例来自动生成每个信号的文档。现在 InterruptFactory 可以做到这一点。

创建中断的简单方法:

class EasyInterrupt extends Component {
val io = new Bundle {
val apb = slave(Apb3(Apb3Config(16,32)))
val a, b, c, d, e = in Bool()
}
val busif = BusInterface(io.apb,(0x000,1 KiB), 0, regPre = "AP")
busif.interruptFactory("T", io.a, io.b, io.c, io.d, io.e)
busif.accept(CHeaderGenerator("intrreg","AP"))
busif.accept(HtmlGenerator("intrreg", "Interupt Example"))
busif.accept(JsonGenerator("intrreg"))
busif.accept(RalfGenerator("intrreg"))
busif.accept(SystemRdlGenerator("intrreg", "AP"))
}

 

IP 级中断生成器

寄存器

访问类型

描述

RAW

W1C

中断原始状态 (int raw) 寄存器,由 int 事件设置,总线写 1 时清零

FORCE

RW

中断强制寄存器,用于软件调试

MASK

RW

中断掩码寄存器, 1:关闭; 0:打开;默认 1 中断关闭

STATUS

RO

中断状态,只读, status = raw && ! mask

 

Spinal 用法:

busif.interruptFactory("T", io.a, io.b, io.c, io.d, io.e) 

SYS 级中断合并

寄存器

访问类型

描述

MASK

RW

中断掩码寄存器, 1:关闭; 0:打开;默认 1 中断关闭

STATUS

RO

中断状态, RO, status = int_level && ! mask

 

busif.interruptLevelFactory("T", sys_int0, sys_int1)

Spinal 的生成器

总线接口方法

描述

InterruptFactory(regNamePre: String,triggers: Bool*)

为 脉 冲 事 件 创 建RAW/FORCE/MASK/STATUS

InterruptFactoryNoForce(regNamePre: String,
triggers: Bool*)

为 脉 冲 事 件 创 建RAW/MASK/STATUS

InterruptFactory(regNamePre: String,triggers: Bool*)

为 level_int 合 并 创 建MASK/STATUS

InterruptFactoryAt(addrOffset: Int,regNamePre: String, triggers: Bool*)

在 addrOffset 处 为 脉 冲 事 件 创 建RAW/FORCE/MASK/STATUS

InterruptFactoryNoForceAt(addrOffset: Int,
regNamePre: String, triggers: Bool*)

在 addrOffset 处 为 脉 冲 事 件 创 建RAW/MASK/STATUS

InterruptFactoryAt(addrOffset: Int,regNamePre: String, triggers: Bool*)

在 addrOffset 处为 level_int 合并创建MASK/STATUS

示例:

class RegFileIntrExample extends Component {
val io = new Bundle {
val apb = slave(Apb3(Apb3Config(16,32)))
val int_pulse0, int_pulse1, int_pulse2, int_pulse3 = in Bool()
val int_level0, int_level1, int_level2 = in Bool()
val sys_int = out Bool()
val gpio_int = out Bool()
}
val busif = BusInterface(io.apb, (0x000,1 KiB), 0, regPre = "AP")
io.sys_int := busif.interruptFactory("SYS",io.int_pulse0, io.int_pulse1, io.
,→int_pulse2, io.int_pulse3)
io.gpio_int := busif.interruptLevelFactory("GPIO",io.int_level0, io.int_level1,␣
,→io.int_level2, io.sys_int)
def genDoc() = {
busif.accept(CHeaderGenerator("intrreg","Intr"))
busif.accept(HtmlGenerator("intrreg", "Interupt Example"))
busif.accept(JsonGenerator("intrreg"))
busif.accept(RalfGenerator("intrreg"))
busif.accept(SystemRdlGenerator("intrreg", "Intr"))
this
}
this.genDoc()
}

8.默认读取值

当软件读取保留地址时,当前的策略是正常返回, readerror=0。为了方便软件调试,可以配置回读值,默

认为 0。

busif.setReservedAddressReadValue(0x0000EF00)

 

default: begin
busif_rdata <= 32'h0000EF00 ;
busif_rderr <= 1'b0 ;
end

相关推荐

  1. SpinalHDL实用工具(下篇

    2024-07-20 21:28:01       37 阅读
  2. SpinalHDLFlow

    2024-07-20 21:28:01       31 阅读
  3. SpinalHDL总线

    2024-07-20 21:28:01       21 阅读
  4. SpinalHDL寄存器库函数

    2024-07-20 21:28:01       37 阅读
  5. SpinalHDL实用工具(上篇)

    2024-07-20 21:28:01       35 阅读
  6. SpinalHDLVHDL 和 Verilog 生成

    2024-07-20 21:28:01       35 阅读
  7. SpinalHDL】1. Getting Started

    2024-07-20 21:28:01       59 阅读
  8. spinalhdl,vivado,fpga

    2024-07-20 21:28:01       51 阅读
  9. SpinalHDL】2.数据类型SpinalEnum

    2024-07-20 21:28:01       63 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 21:28:01       138 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 21:28:01       152 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 21:28:01       128 阅读
  4. Python语言-面向对象

    2024-07-20 21:28:01       140 阅读

热门阅读

  1. Python正则表达式

    2024-07-20 21:28:01       25 阅读
  2. 【SpringBoot】SpringAOP实现公共字段自动填充

    2024-07-20 21:28:01       23 阅读
  3. Netty的线程模型是怎么样的

    2024-07-20 21:28:01       22 阅读
  4. python入门教程,小白10分钟快速入门

    2024-07-20 21:28:01       25 阅读
  5. 【Webpack】HMR 热更新

    2024-07-20 21:28:01       23 阅读
  6. Fisher-Yates 算法-数组元素随机交换

    2024-07-20 21:28:01       30 阅读
  7. C++ 中值传递和引用传递的区别?

    2024-07-20 21:28:01       23 阅读
  8. MATLAB的基础知识

    2024-07-20 21:28:01       26 阅读
  9. 【Vue】vue2 vue-awesome-swiper 刷新无法自动滚动解决

    2024-07-20 21:28:01       25 阅读
  10. 【Go系列】模块和协同开发

    2024-07-20 21:28:01       25 阅读