Reputation: 702
The Lattice FPGA I am using has embedded RAMs, which can be preloaded with data through the configuration binary.
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.
So my code to instantiate the RAM looks like this:
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. Modifying the .v file in the build is not nice as it is 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. It works for now but is not nice.
Of course, there are several instances of this SB_RAM40_4KNRNW module. The device has 30 of them.
(I am using the open-source tools yosys/nextpnr/icepack)
Thanks for your help!
Upvotes: 0
Views: 1460
Reputation: 829
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.
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
. Assume the following test program in a git-traced file:
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.
Upvotes: 0
Reputation: 538
I had a similar issue with using TSMC memories. TSMC has an "INIT" parameter/`define where you can set a text file to read in the verilog hex values. 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.
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). This file would be created as part of my make flow for CPU SW, so it was always up to date. 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:
I personally do not like `defines or `includes in my RTL. I'm ok with them in verification. So it boils down to what you are comfortable with.
Upvotes: 1