risc-v中文社区

 找回密码
 立即注册
查看: 1130|回复: 0

[原创] SpinalHDL—Area

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-6-6 16:13:12 | 显示全部楼层 |阅读模式
 在我们编写Verilog或者SysytemVerilog时,我们的代码基本都以module来进行组织,而针对一些比较通用的模块组件,我们或组织成一个单独的model,或者放在一个function中(仅限于纯组合逻辑)。本篇介绍SpinalHDL中的Area的概念。
Area

    在SpinalHDKL里,与Verilog、SystemVerilog中相对应的概念是Component,当我们的类继承了Component后,与之相应的我们就要定义端口及参数。以我们上篇所提到的例子,我们在例化一个加法器模块时从初阶、到中阶再到高阶,我们仍避免不了连线的话题,只不过是在伴生对象中做了一次封装从而一劳永逸。
    为了解决过于细致的模块划分(不断的端口连线)及兼顾代码尽可能复用的准则,SpinalHDL里设计了Area的概念。通过类扩展集成Area,可以有效的避免上述问题。介绍Area之前,先介绍一个概念:
        在Scala中,参数的传递均为引用类型,而我们定义的电路对象本身也是一个scala类的实例化对象,作为类的参数传递在类中是可以直接定义电路对象的动作的。


    有了Area概念的引入,《SpinalHDL—像软件调用方法般例化模块》中所用到的加法器我们可以这么来定义:

case class addArea(port:sumPort)extends Area{
  port.sum.payload:=RegNextWhen(port.dataIn.data1+port.dataIn.data2,port.dataIn.valid)
  port.sum.valid:=RegNext(port.dataIn.valid,False)
}
    这里我们定义了一个addArea类,其继承了Area,电路对象sumPort作为类的一个参数来传递,在类的实现里,我们实现了对加法器的实现。这种方式我们无需定义伴生对象(object)便可以方便的实现加法器单元的例化:

class addInst2(dataWidth:Int) extends Component{
  val io=new Bundle{
    val sumport0=slave(sumPort(dataWidth))
    val sumport1=slave(sumPort(dataWidth))
  }
  addArea(io.sumport0)
  addArea(io.sumport1)
}
    而生成的SystemVerilog代码如下所示:

module addInst2 (
  input               io_sumport0_dataIn_valid,
  input      [7:0]    io_sumport0_dataIn_payload_data1,
  input      [7:0]    io_sumport0_dataIn_payload_data2,
  output              io_sumport0_sum_valid,
  output     [7:0]    io_sumport0_sum_payload,
  input               io_sumport1_dataIn_valid,
  input      [7:0]    io_sumport1_dataIn_payload_data1,
  input      [7:0]    io_sumport1_dataIn_payload_data2,
  output              io_sumport1_sum_valid,
  output     [7:0]    io_sumport1_sum_payload,
  input               clk,
  input               reset
);
  reg        [7:0]    _zz_1;
  reg                 io_sumport0_dataIn_valid_regNext;
  reg        [7:0]    _zz_2;
  reg                 io_sumport1_dataIn_valid_regNext;

  assign io_sumport0_sum_payload = _zz_1;
  assign io_sumport0_sum_valid = io_sumport0_dataIn_valid_regNext;
  assign io_sumport1_sum_payload = _zz_2;
  assign io_sumport1_sum_valid = io_sumport1_dataIn_valid_regNext;
  always @ (posedge clk) begin
    if(io_sumport0_dataIn_valid)begin
      _zz_1 <= (io_sumport0_dataIn_payload_data1 + io_sumport0_dataIn_payload_data2);
    end
    if(io_sumport1_dataIn_valid)begin
      _zz_2 <= (io_sumport1_dataIn_payload_data1 + io_sumport1_dataIn_payload_data2);
    end
  end
  always @ (posedge clk or posedge reset) begin
    if (reset) begin
      io_sumport0_dataIn_valid_regNext <= 1'b0;
      io_sumport1_dataIn_valid_regNext <= 1'b0;
    end else begin
      io_sumport0_dataIn_valid_regNext <= io_sumport0_dataIn_valid;
      io_sumport1_dataIn_valid_regNext <= io_sumport1_dataIn_valid;
    end
  end
endmodule

    可以看到,继承了Area的类在例化时对应的RTL代码也是没有对应的module分层的。

Area“副作用”

    Area除了可以用于将通用代码从Component中抽取出来的用处之外其另外一个特性便是我们可以在我们的Component代码实现里将我们的代码按模块放置在Area里进行按功能分类,而在生成Verilog时我们定义在Area中的变量也会加上Area的前缀,如此我们可以在仿真或上板抓线时方便的进行信号提取。如下代码:

class  areaDeom extends Component{
  val io = new Bundle{
    val clear = in Bool
    val value = out UInt(8 bits)
  }
  val cntArea=new Area{
    val register = Reg(UInt(8 bits)) init(0)
    register := register + 1
    when(io.clear){
      register := 0
    }
    io.value := register
  }
}
    其生成的RTL代码如下所示:

module areaDeom (
  input               io_clear,
  output     [7:0]    io_value,
  input               clk,
  input               reset
);
  reg        [7:0]    cntArea_register;

  assign io_value = cntArea_register;
  always @ (posedge clk or posedge reset) begin
    if (reset) begin
      cntArea_register <= 8'h0;
    end else begin
      cntArea_register <= (cntArea_register + 8'h01);
      if(io_clear)begin
        cntArea_register <= 8'h0;
      end
    end
  end
endmodule
    可以看到,我们定义的register寄存器在RTL代码中加上了Area名前缀cntArea。

本帖来源微信公从号:Spinal FPGA

网页地址:链接

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-19 21:26 , Processed in 0.014694 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表