简体   繁体   English

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

[英]Verilog module parameters in seperate config file?

The Lattice FPGA I am using has embedded RAMs, which can be preloaded with data through the configuration binary.我使用的莱迪思 FPGA 具有嵌入式 RAM,可以通过配置二进制文件预加载数据。

The predefined Verilog modules for these RAMs implement this by providing Parameters named INIT_0 , INIT_1 , INIT_2 , ... , each a 256-bit value, to do this.这些 RAM 的预定义 Verilog 模块通过提供名为 INIT_0 、 INIT_1 、 INIT_2 、 ... 的参数(每个参数为 256 位值)来实现这一点。

So my code to instantiate the RAM looks like this:所以我实例化 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]}),
                ......
        );

While it works, I would like to pull in the data from some other file as it is generated by other programs in the make process.虽然它有效,但我想从其他文件中提取数据,因为它是由其他程序在 make 过程中生成的。 Modifying the .v file in the build is not nice as it is git-tracked.在构建中修改 .v 文件并不好,因为它是 git-tracked。

Is there a way to pull in module parameters from another file or some other way to feed them into the compiler?有没有办法从另一个文件中提取模块参数或以其他方式将它们输入编译器?

Currently I generate the data, paste it into the .v source, and then build and load it.目前我生成数据,将其粘贴到 .v 源中,然后构建并加载它。 It works for now but is not nice.它现在有效,但不是很好。

Of course, there are several instances of this SB_RAM40_4KNRNW module.当然,这个 SB_RAM40_4KNRNW 模块有几个实例。 The device has 30 of them.该设备有 30 个。

(I am using the open-source tools yosys/nextpnr/icepack) (我正在使用开源工具 yosys/nextpnr/icepack)

Thanks for your help!谢谢你的帮助!

I had a similar issue with using TSMC memories.我在使用 TSMC 内存时遇到了类似的问题。 TSMC has an "INIT" parameter/`define where you can set a text file to read in the verilog hex values. TSMC 有一个“INIT”参数/`define,您可以在其中设置文本文件以读取 verilog 十六进制值。 The issue was, I had multiple memories, so I would need multiple files, with multiple parameters on each instance of the memory (but I was trying to keep the code clean with an index of memories based on a parameter).问题是,我有多个内存,所以我需要多个文件,每个内存实例都有多个参数(但我试图通过基于参数的内存索引来保持代码干净)。 This however was easier said than done, and also with the `define it would require a re-compile during regressions.然而,这说起来容易做起来难,而且使用 `define 时,它​​需要在回归期间重新编译。

So what I did was create a Python script that would read in my disassembled code (or whatever data you want to read) and constructed assign statements that get executed right after time 0 (to account for the memory init).因此,我所做的是创建一个 Python 脚本,该脚本将读取我的反汇编代码(或您想要读取的任何数据)并构造在时间 0 之后立即执行的赋值语句(以考虑内存初始化)。 This file would be created as part of my make flow for CPU SW, so it was always up to date.该文件将作为我的 CPU SW 生成流程的一部分创建,因此它始终是最新的。 I opted for this as we already had some scripts that were generating other portions for design and testing, and we just needed a way to force memory contents during quick debug testing instead of waiting for the memories to be programmed.我选择了这个,因为我们已经有一些脚本可以生成用于设计和测试的其他部分,我们只需要一种在快速调试测试期间强制内存内容的方法,而不是等待对内存进行编程。

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...

The syntax would be different according to your memory structure.根据您的内存结构,语法会有所不同。

Some other ways to possibly do what you are asking:其他一些方法可能会做你所要求的:

  • You could make the params a `define, provided you have one per instance您可以将参数设为 `define,前提是每个实例都有一个
  • You could make the RAM instantiation an `include您可以将 RAM 实例化为 `include

I personally do not like `defines or `includes in my RTL.我个人不喜欢在我的 RTL 中定义或包含。 I'm ok with them in verification.我可以接受他们的验证。 So it boils down to what you are comfortable with.所以它归结为你对什么感到舒服。

Is there a way to pull in module parameters from another file or some other way to feed them into the compiler?有没有办法从另一个文件中提取模块参数或以其他方式将它们输入编译器?

Variations on `include , param , localparam is what I think you want. `includeparamlocalparam是我认为你想要的。
To give an example: Assume data can be generated on the following form:举个例子:假设数据可以按以下形式生成:

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

and written to the file from_other_programs.hv .并写入文件from_other_programs.hv Assume the following test program in a git-traced file:假设在 git-traced 文件中有以下测试程序:

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

This is but one of possible variations on this theme.这只是该主题的可能变体之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM