我正在尝试用 verilog 制作一个可综合的滤波器。我在文本文件中有定点滤波器系数。我正在寻找一种优雅且可扩展的方式来传递这些滤波器系数。过滤器不会是一个简单的野兽:它将包含多个子模块,并且每个子模块可能需要一个系数。
由于滤波器系数是恒定的,我希望它们被硬编码,即在实现中不消耗任何寄存器。
我有以下一些选择/愿望,以及它们可能的缺点:
readmemh
或一些类似的技巧将系数读入封闭模块中的内存 (reg [15:0] coeff [0:1023]
),并使用生成块将系数从内存传递到 FIR 阶段。它应该看起来像:generate
for (i = 0; i < 3 ; i = i + 1) begin: k
filter_stage(input[k], coeff[k], output[k]);
end
endgenerate
缺点是内存必须位于包含过滤器阶段的模块中,否则我将不得不经历端口列表地狱。
使用systemverilog打包数组作为模块端口。 缺点是 systemverilog 对某些综合工具的支持不是最佳的。
这是一个愿望:每个模块都可以访问某种全局查找结构,因此我不必手动包装模块并调整端口列表只是为了将系数传递到正确的位置。
我想知道选项 3 是否可行。如果没有的话我还能做什么?
谢谢。
如果您能够使用SystemVerilog,那么您可以将常量(可能是常量数组)放入包中,然后
import
(不是include
)将包放入其他需要访问的模块中。SystemVerilog 包是可综合的,它们不仅仅是用于验证。
我已经将它们用于 Vivado RTL 工作好几年了,似乎是从 Vivado 2016 开始。
此链接表示 2012 年 Quartus Synthesis 支持软件包Altera 对 SV 的支持
您可能遇到综合支持问题的唯一地方是 ISE;最后一次发布是 2014 年。我不了解 Microsemi 或其他中小型 FPGA 供应商。
您不需要选项 1,不需要 2 中提到的端口,也不必包装任何内容或使用 3 中提到的端口。
包中的常量数组应该可以很好地工作。
包语法是轻量级的,您可以使用 Matlab 或 Python 或任何用于系数生成的工具,用常量写出 SystemVerilog 包。
示例包
// Write me out with Python or Matlab generated coefficients
package my_coef_pk;
// type int is 32 bit, treated as signed
localparam int my_coef_array [4:0] =
'{
2**16,
1,
2,
-1,
-(2**16)
};
endpackage
示例测试平台导入包
module tb ();
// import the contents of the package here
import my_coef_pk::*;
// example access the localparam array defined in the package
initial
foreach(my_coef_array [i])
$display("my_coef_array = %d", my_coef_array [i]);
endmodule
产品
my_coef_array = 65536
my_coef_array = 1
my_coef_array = 2
my_coef_array = -1
my_coef_array = -65536
关于全局查找结构:在Verilog仿真中,几乎所有东西都是“全局”的。您可以使用分层引用来访问任何模块中的任何变量。但在综合中,用户定义的变量不是也不可能是全局的。每个状态变量都需要一条路线将其值从一个地方移动到另一个地方。
您在这里的选择有限,根据我的理解,传递
coeff
是将值发送到过滤器的最简单方法。或者,您可以在顶部模块中使用参数数组并将这些参数传递到底部模块。
此外,您可以在此处查看此包含文件方法