如何解决Verilog:如何在生成块中定义参数并在外部访问它们?
我想定义一些本地参数,它们的值由在此模块之外分配的参数决定。在这里,我使用了一个生成块。就像下面这样:
module doppler_fft_cluster # (
parameter CORE_TYPE = "DOPPLER_FFT_D0"
) (
clk,rst_,i_tvalid,i_tdata,i_tready,i_tlast
// and more ports
);
input clk;
input rst_;
generate
case (CORE_TYPE)
"DOPPLER_FFT_D0": begin
localparam FFT_XN_DATA_WIDTH = 42;
localparam FFT_XK_DATA_WIDTH = 66;
localparam FFT_LENGTH = 2048;
end
"DOPPLER_FFT_D1": begin
localparam FFT_XN_DATA_WIDTH = 64;
localparam FFT_XK_DATA_WIDTH = 66;
localparam FFT_LENGTH = 512;
end
endcase
endgenerate
input i_tvalid;
input i_tdata;
output i_tready;
input i_tlast;
input [FFT_XN_DATA_WIDTH-1:0] i_tdata; // Boom!
// ... ...
endmodule
我尝试使用 ModelSim 来模拟这个模块,但它说那些本地参数未定义。
Error: ./demo.v(31): (vlog-2730) Undefined variable: 'FFT_XN_DATA_WIDTH'.
这个localparams好像不能进入模块级作用域。
那么,我如何在模块级别访问它们?或者,还有其他方法可以实现这样的功能吗?
更新 0616
我最后选择了 Ehab Ibrahim 的方法,因为我的项目需要 Xilinx ISE 或 XST 合成器,它不能接受带有点语法的 parameter
或 localparam
赋值。但是,如果您不受 EDA 工具的限制,请随时尝试使用 dave_59 的方法。
谢谢!
解决方法
错误的原因是您在未命名的 localparam
块中定义了 begin/end
。您需要为它们命名才能从外部访问它们。
module doppler_fft_cluster # (
parameter CORE_TYPE = "DOPPLER_FFT_D0"
) (
clk,rst_,i_tvalid,i_tdata,i_tready,i_tlast
// and more ports
);
case (CORE_TYPE)
"DOPPLER_FFT_D0": begin : FFT
localparam XN_DATA_WIDTH = 42;
localparam XK_DATA_WIDTH = 66;
localparam LENGTH = 2048;
end
"DOPPLER_FFT_D1": begin : FFT
localparam XN_DATA_WIDTH = 64;
localparam XK_DATA_WIDTH = 66;
localparam LENGTH = 512;
end
endcase
input clk;
input rst_;
input i_tvalid;
input i_tdata;
output i_tready;
input i_tlast;
input [FFT.XN_DATA_WIDTH-1:0] i_tdata; // Boom!
initial $display("%m FFT.LENGTH = ",FFT.LENGTH);
endmodule
module top;
doppler_fft_cluster #() D0(,);
doppler_fft_cluster #("DOPPLER_FFT_D1") D1(,);
endmodule
,
您不需要在 generate 语句中定义本地参数。有几种方法可以解决这个问题,您可以像这样以 if-else 方式定义本地参数:
localparam FFT_XN_DATA_WIDTH = (CORE_TYPE=="DOPPLER_FFT_DO") ? 42
: (CORE_TYPE=="DOPPLER_FFT_D1") ? 64
: 24; // Equivalent to case "default"
localparam FFT_XK_DATA_WIDTH = (CORE_TYPE=="DOPPLER_FFT_DO") ? 66
: (CORE_TYPE=="DOPPLER_FFT_D1") ? 66
: 24; // Equivalent to case "default"
localparam FFT_LENGTH = (CORE_TYPE=="DOPPLER_FFT_DO") ? 2048
: (CORE_TYPE=="DOPPLER_FFT_D1") ? 512
: 256; // Equivalent to case "default"
或者,如果太复杂,你可以定义一个实现功能的函数,并使用本地参数实例化调用该函数:
function automatic int get_xn_width(input string core_type);
if(core_type == "DOPPLER_FFT_DO") return 42;
else if(core_type == "DOPPLER_FFT_DO") return 64;
else return 24;
endfunction
// Define similar functions for the other local parameters
module doppler_fft_cluster # (
parameter CORE_TYPE = "DOPPLER_FFT_D0"
) (
clk,i_tlast
// and more ports
);
// port definitions
-------------
localparam FFT_XN_DATA_WIDTH = get_xn_width(CORE_TYPE);
// Same for other localparams
-------------
// Rest of module
endmodule
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。