微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Verilog:如何在生成块中定义参数并在外部访问它们?

如何解决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 合成器,它不能接受带有点语法的 parameterlocalparam 赋值。但是,如果您不受 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 举报,一经查实,本站将立刻删除。