单独配置文件中的Verilog模块参数?

时间:2020-01-17 11:33:42

标签: parameters configuration verilog

我正在使用的Lattice FPGA具有嵌入式RAM,可以通过配置二进制文件将其预加载数据。

这些RAM的预定义Verilog模块通过提供名为INIT_0,INIT_1,INIT_2,...的参数(每个参数为256位值)来实现此目的。

所以我实例化RAM的代码如下:

        SB_RAM40_4KNRNW #(
                .INIT_0(256'h00000FA00BB807D003E859E905E2F529486300000000000059E099E3404219E2),
                .INIT_1(256'h0123456701234567012345670123456701234567012345670123456701234567),
                .READ_MODE(0) ,
                .WRITE_MODE(0)
        ) buf0L
        (
                .RDATA(readline0[15:0]),
                .RADDR({3'b0,RAMadr[7:0]}),
                ......
        );

虽然它可以工作,但我想从其他文件中提取数据,因为这些文件是在制作过程中由其他程序生成的。修改版本中的.v文件不是很好,因为它是git跟踪的。

是否有一种方法可以从另一个文件中提取模块参数,或者以其他方式将其输入到编译器中?

当前,我生成数据,将其粘贴到.v源中,然后构建并加载它。它目前可以使用,但效果不佳。

当然,此SB_RAM40_4KNRNW模块有多个实例。该设备有30个。

(我正在使用开源工具yosys / nextpnr / icepack)

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我在使用台积电存储器时遇到类似的问题。台积电有一个“ INIT”参数/`define,您可以在其中设置一个文本文件以读取verilog十六进制值。问题是,我有多个内存,因此我需要多个文件,并且每个内存实例上都有多个参数(但是我试图通过基于参数的内存索引来保持代码整洁)。但是,这说起来容易做起来难,而且通过“定义”,在回归过程中将需要重新编译。

所以我要做的是创建一个Python脚本,该脚本将读取我的反汇编代码(或您想要读取的任何数据),并构造在时间0之后立即执行的assign语句(以考虑内存初始化)。该文件将作为我的CPU SW生成流程的一部分创建,因此它始终是最新的。我之所以选择它,是因为我们已经有了一些脚本,这些脚本会生成其他部分用于设计和测试,我们只需要一种在快速调试测试期间强制存储内容的方法,而不必等待对存储器进行编程。

initial begin
        // Instruction
        $display("INFO: Starting to directly program Instruction Memory!");
        #1ns;
        {`RISCV_CPU.u_instr_mem_TSMC[0].row_tmp, `RISCV_CPU.u_instr_mem_TSMC[0].col_tmp} = 0;
        `RISCV_CPU.u_instr_mem_TSMC[0].MEMORY[`RISCV_CPU.u_instr_mem_TSMC[0].row_tmp][`RISCV_CPU.u_instr_mem_TSMC[0].col_tmp] = 32'h00000013;
        {`RISCV_CPU.u_instr_mem_TSMC[0].row_tmp, `RISCV_CPU.u_instr_mem_TSMC[0].col_tmp} = 1;
        `RISCV_CPU.u_instr_mem_TSMC[0].MEMORY[`RISCV_CPU.u_instr_mem_TSMC[0].row_tmp][`RISCV_CPU.u_instr_mem_TSMC[0].col_tmp] = 32'h00000013;
        {`RISCV_CPU.u_instr_mem_TSMC[0].row_tmp, `RISCV_CPU.u_instr_mem_TSMC[0].col_tmp} = 2;
        `RISCV_CPU.u_instr_mem_TSMC[0].MEMORY[`RISCV_CPU.u_instr_mem_TSMC[0].row_tmp][`RISCV_CPU.u_instr_mem_TSMC[0].col_tmp] = 32'h00000013;
        {`RISCV_CPU.u_instr_mem_TSMC[0].row_tmp, `RISCV_CPU.u_instr_mem_TSMC[0].col_tmp} = 3;
//lots more...

根据您的内存结构,语法会有所不同。

某些其他方式可以完成您要问的事情:

  • 您可以将params定义为“`,只要每个实例有一个
  • 您可以将RAM实例化为`include

我个人不喜欢RTL中的“定义”或“包含”。我可以接受他们的验证。因此归根结底就是您满意的地方。

答案 1 :(得分:0)

是否有一种方法可以从另一个文件中提取模块参数,或者以其他方式将其输入到编译器中?

`includeparamlocalparam的变化是我想要的。
举个例子:假设可以采用以下形式生成数据:

// Generated from an assembler or whatever
localparam prg0 = 256'hdeadbeef;
localparam prg1 = 256'h0;
// etc ...

并写入文件from_other_programs.hv。在git跟踪的文件中假定以下测试程序:

module top
  (
   input         clk,
   input [7:0]   RAMadr,
   output [15:0] readline0
   );
`include "from_other_programs.hv"

   SB_RAM40_4KNRNW #(.INIT_0(prg0), .INIT_1(prg1),
                     .READ_MODE(0),.WRITE_MODE(0)
                     ) buf0L
     (  .RDATA(readline0[15:0]),
        .RADDR({3'b0,RAMadr[7:0]}));
endmodule

这只是该主题的可能变体之一。

相关问题