0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在SpinalHDL中如何优雅地例化端口?

FPGA之家 来源:Spinal FPGA 作者:Spinal FPGA 2021-06-16 17:19 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在编写Verilog代码时最痛苦的事情便是例化模块时端口的连接,这时候的你我便成了连线工程师,本节就在SpinalHDL中如何像软件调用方法那样优雅地例化端口进行探讨。

习惯了写Verilog的小伙伴们在做大型工程时是否有遇到过连续数天时间化身“连线工程师”去例化模块、为端口赋值连接的场景(关键是这些工作量老板他也不认)。尽管在SystemVerilog中提供了Interface接口的概念,但是从事FPGA的小伙伴都清楚无论是Xilinx的Vivado还是Intel Quartus虽然支持SystemVerilog但远没有做到像软件代码编辑器那般做到自动联想与提示。最近分析一个Intel的大型源码工程其中用到了大量的SystemVerilog中的interface及struct,但自动关联提示做的真是一团糟,导致阅读体验真是差的一匹…… 本文以一个简单的加法器的例子来看如何在SpinalHDL中如何避免成为连线工程师。 加法器端口列表如下所示:端口名方向位宽说明

valid_ininput1输入有效标志

data1input8输入数据

data2input8输入数据

sumoutput8和

sum_validoutput1和有效标志

初阶

刚开始接触SpinalHDL时这个加法器我们可能会这么来写:

class add(dataWidth:Int) extends Component{ val validIn=in Bool() val data1=in UInt(dataWidth bits) val data2=in UInt(dataWidth bits) val sum=out UInt(dataWidth bits) val sumValid=out Bool() sum:=RegNextWhen(data1+data2,validIn) sumValid:=RegNext(validIn,False)}

这里针对端口的实现形式和我们在Verilog中的方式基本相同。那么当我们在例化这个模块时,我们可能会这么来写:

class addInst(dataWidth:Int) extends Component { val io=new Bundle{ val validIn_0=in Bool() val data1_0=in UInt(dataWidth bits) val data2_0=in UInt(dataWidth bits) val sum_0=out UInt(dataWidth bits) val sumValid_0=out Bool()

val validIn_1=in Bool() val data1_1=in UInt(dataWidth bits) val data2_1=in UInt(dataWidth bits) val sum_1=out UInt(dataWidth bits) val sumValid_1=out Bool() } val add0=new add(dataWidth) val add1=new add(dataWidth) add0.validIn《》io.validIn_0 add0.data1《》io.data1_0 add0.data2《》io.data2_0 add0.sum《》io.sum_0 add0.sumValid《》io.sumValid_0 add1.validIn《》io.validIn_1 add1.data1《》io.data1_1 add1.data2《》io.data2_1 add1.sum《》io.sum_1 add1.sumValid《》io.sumValid_1}

这里例化了两个加法器,可以看到,这里如同我们写Verilog代码般一根根连线,当有众多模块需要去例化时还是蛮痛苦的。

中阶

在SystemVerilog中提供了Interface的概念用于封装接口,在SpinalHDL中,我们可以借助软件面向对象的思想把接口给抽象出来:

case class sumPort(dataWidth:Int=8) extends Bundle with IMasterSlave{ case class dataPort(dataWidth:Int=8) extends Bundle{ val data1=UInt(dataWidth bits) val data2=UInt(dataWidth bits) } val dataIn=Flow(dataPort(dataWidth)) val sum=Flow(UInt(dataWidth bits))

override def asMaster(): Unit = { master(dataIn) slave(sum) }}

这里我们将加法器的端口抽象成sumPort端口。其中包含两个Flow类型:dataIn、sum。并声明当作为master端口时dataIn为master、sum为slave。这样,我们的加法器便可以这么来写:

case class add2(dataWidth:Int=8)extends Component{ val io=new Bundle{ val sumport=slave(sumPort(dataWidth)) } io.sumport.sum.payload:=RegNextWhen(io.sumport.dataIn.data1+io.sumport.dataIn.data2,io.sumport.dataIn.valid) io.sumport.sum.valid:=RegNext(io.sumport.dataIn.valid,False)}

而我们在例化时,便可以简洁地例化:

class addInst1(dataWidth:Int) extends Component{ val io=new Bundle{ val sumport0=slave(sumPort(dataWidth)) val sumport1=slave(sumPort(dataWidth)) } val addInst_0=add2(dataWidth) val addInst_1=add2(dataWidth) io.sumport0《》addInst_0.io.sumport io.sumport1《》addInst_1.io.sumport}

如此我们便能简洁地例化加法器。虽然这里地做法思想和SystemVerilog中地思想基本一致,但好处是我们能够在IDEA中像阅读软件代码那般快速地跳转和定位,相较于厂商工具中那样分析工程地痛苦实在是好太多。

高阶

在中阶例,我们采用了类似SystemVerilog中Interface及struct概念,但可以发现,我们这里依旧存在连线行为。一个模块例化一次要连线一次,要例化N次还是要……

在软件代码中,调用一个方法或者模块往往一行代码了事:声明调用函数并将参数放在括号列表里。那么在这里,我们能否像软件调用那样一行代码搞定呢?

可以的!由于SpinalHDL是基于Scala的,因此我们可以将端口列表当成参数列表来传递。这里我们先为我们的加法器定义一个伴生对象:

object add2{ def apply(dataWidth: Int,port Unit = { val addInst=new add2(dataWidth) addInst.io.sumport《》port }}

这里我们为加法器add2定义了一个伴生对象(伴生对象声明为object,名字与类名相同)。并在其中定义了一个apply方法,传入两个参数:位宽dataWidth及端口port,并在apply实现中完成模块例化及端口连接(一次连线,终身使用)。随后我们在例化时便可以像软件调用方法那样例化模块了:

class addInst1(dataWidth:Int) extends Component{ val io=new Bundle{ val sumport0=slave(sumPort(dataWidth)) val sumport1=slave(sumPort(dataWidth)) } add2(dataWidth,io.sumport0) add2(dataWidth,io.sumport0)}

一行代码搞定一个模块的一次例化和端口连接!

原文标题:SpinalHDL—像软件调用方法般例化模块

文章出处:【微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 软件
    +关注

    关注

    69

    文章

    5297

    浏览量

    90869
  • Verilog
    +关注

    关注

    30

    文章

    1370

    浏览量

    114138

原文标题:SpinalHDL—像软件调用方法般例化模块

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    verilog testbench运行测试用时,运行到make run_test出错怎么解决?

    按照胡老师书上的verilog testbench运行测试用时,在运行到make run_test步骤时出错,查了很多方案没有解决。
    发表于 11-11 06:52

    E203外设的与编译配置

    e203_subsys_perips层与icb总线进⾏连接。e203_subsys_perips同样e203_subsys_main
    发表于 10-24 07:14

    Xilinx BRAM IP核配置及其

    )的,所以通过合理分配BRAM的大小,可以提高片上block的利用率。 完成以后,进行综合,可以通过report utilization来查看资源消耗情况 可以看到使用的板子
    发表于 10-24 06:10

    NVMe高速传输之摆脱XDMA设计33:初始功能验证与分析

    模型。 在这里以最小存储子系统模型为说明对初始功能的验证与分析。 本节测试用, 设置桥设备模型不启用 BAR 空间, 设置 NVM
    发表于 10-08 08:02

    Leiditech数据端口电路保护使用TVS ESD

    端口
    上海雷卯电子
    发布于 :2025年08月21日 17:28:49

    EtherCAT与Profinet协议转换工业自动的应用:以汇川伺服驱动器为

    工业自动领域,实现不同协议设备间的无缝通信是提升生产效率的关键。以EtherCAT主站通过Profinet网关连接汇川伺服驱动器的场景为,这一技术组合不仅解决了异构网络协同的难题,更通过精准的速度控制为生产线注入了智能
    的头像 发表于 07-08 15:49 624次阅读
    EtherCAT与Profinet协议转换<b class='flag-5'>在</b>工业自动<b class='flag-5'>化</b><b class='flag-5'>中</b>的应用:以汇川伺服驱动器为<b class='flag-5'>例</b>

    基于瑞萨电子RA8T2 sensorless方案的样工程 可对电流环进行TCM设置

    基于瑞萨电子RA8T2 sensorless方案的样工程 可对电流环进行TCM设置
    的头像 发表于 06-04 18:29 932次阅读

    推荐!如何优雅地摆好PCB丝印?

    很多画PCB的人,会认为丝印不影响电路的性能,所以,对丝印并不重视。但是,对于一个专业的硬件工程师来说,必须重视这些细节。 下面介绍如何优雅地弄好PCB丝印。 1 摆放的位置 一般来说,电阻、电容
    发表于 04-08 14:59

    信号端口滤波器的基本知识

    电路,信号输入端口是一个非常重要的组成部分。它允许电路接收和处理来自外部环境的信号,从而实现各种不同的功能。通常情况下,信号输入端口是指电路
    的头像 发表于 02-11 11:42 1045次阅读
    信号<b class='flag-5'>端口</b>滤波器的基本知识

    I/O接口与I/O端口的区别

    计算机系统,I/O接口与I/O端口是实现CPU与外部设备数据交换的关键组件,它们功能、结构、作用及运作机制上均存在显著差异,却又相互协同工作,共同构建起CPU与外部设备之间的桥梁
    的头像 发表于 02-02 16:00 2806次阅读

    光纤传感器工业自动的应用

    能力强、响应速度快等优点,工业自动得到了广泛应用。 2. 光纤传感器的基本原理 光纤传感器的工作原理基于光波光纤的传输特性。当光纤
    的头像 发表于 01-18 10:34 1594次阅读

    电源技术工业自动的应用

    电源技术工业自动的应用至关重要,它不仅是工业自动系统稳定运行的基础,还直接影响到系统的性能、效率和可靠性。以下是对电源技术工业自动
    的头像 发表于 01-08 10:12 1229次阅读

    云电脑打印机设置策略:端口自动设置为VM端口怎么办

    晚上10点,老师突然群里布置学习单,得赶紧打印。   咦,云桌面怎么无法使用USB打印机?     救命啊,怎么才能连上啊?! 别着急,这时候可以查看打印机属性端口是不是自动设成了VM开头
    的头像 发表于 01-03 11:02 1269次阅读
    云电脑打印机设置策略:<b class='flag-5'>端口</b>自动设置为VM<b class='flag-5'>端口</b>怎么办

    CAN总线工业自动的作用

    CAN(Controller Area Network)总线工业自动中发挥着至关重要的作用。它是一种高效的现场总线系统,以其高速、可靠和灵活的特点,成为连接工业自动系统各种设备
    的头像 发表于 12-23 09:12 1930次阅读

    Verilog说明

    (或说是调用)。一个FPGA项目工程,其输入、输出端口命名通常在设计前期就已确定下来,但会存在一些中间变量,一个工程可能会让不同的
    的头像 发表于 12-17 11:29 3122次阅读
    Verilog<b class='flag-5'>例</b><b class='flag-5'>化</b>说明