设计ROM以在verilog中保存滤波器系数

design ROM to save filter coefficients in verilog

我想在ROM中存储滤波器系数(固定值)使用verilog.Below是ROM使用案例的代码。


module rom_using_case (
address , // Address input
data    , // Data output
read_en , // Read Enable 
ce        // Chip Enable
);
input [3:0] address;
output [7:0] data;
input read_en;
input ce;

reg [7:0] data ;

always @ (ce or read_en or address)
begin
  case (address)
    0 : data = 10;
    1 : data = 55;
    2 : data = 244;
    3 : data = 0;
    4 : data = 1;
    5 : data = 8'hff;
    6 : data = 8'h11;
    7 : data = 8'h1;
    8 : data = 8'h10;
    9 : data = 8'h0;
    10 : data = 8'h10;
    11 : data = 8'h15;
    12 : data = 8'h60;
    13 : data = 8'h90;
    14 : data = 8'h70;
    15 : data = 8'h90;
  endcase
end

endmodule

上面代码中的 case 块做了什么? 我可以将滤波器系数存储在 case 块的数据变量中吗? 我可以访问那些滤波器系数吗?

如您所述,系数将存储在 RAM LUT 或 ROM 块中。 该代码(有点)是自描述的,alwaysaddress 敏感,然后每次地址更改其值时,存储的值将分配给 datacase 是内存块位置将被分配给数据的选择器。

您的实现对于小型滤波器来说已经足够了,但如果您需要大量系数,将很难维护。

为此,您可以使用 $readmemh$readmemb。这些是verilog intrisic tasks.

发件人:https://www.csee.umbc.edu/~tinoosh/cmpe415/slides/Rom-LUT-verilog.pdf

$readmemh 系统任务期望命名文件的内容是 由空格或换行符分隔的十六进制数序列。 同样,$readmemb 期望文件包含二进制序列。

下面是一个展示如何使用它的片段:

reg [19:0] data_ROM [0:511];
...
initial $readmemh("rom.data", data_ROM); 
always @(address)
  if (ce & read_en)
    d_out = data_ROM[address];

"rom.data" 包含文本中的系数。例如,在您的情况下:

8'hA
8'h37
8'hF4
8'h0
8'h1
8'hff
8'h11
8'h1
8'h10
8'h0
8'h10
8'h15
8'h60
8'h90
8'h70
8'h90