【问题标题】:How can I assign module arguments in Verilog?如何在 Verilog 中分配模块参数?
【发布时间】:2020-02-10 04:22:01
【问题描述】:

我有一个 verilog 模块,其中包含很长的所需输入和输出列表。

module mymodule(clock,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16,S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24);

我正在尝试为此模块编写一个测试平台。是否有一种聪明的方法可以将参数作为数组提供。大约一半的参数是输入,另一半是输出。根据我有限的verilog经验,我尝试做这样的事情。

reg clk = 0;
reg inputs[16:0] = 0;
wire outputs[23:0];

mymodule tc(clk, inputs, outputs);     

我希望变量“inputs”充当一个包含所有输入的数组,并且“outputs”也将这样做。

我还希望能够将所有输入设置为随机

inputs = $random; 

有没有办法在 Verilog 中做到这一点,还是我必须手动初始化所​​有变量?

【问题讨论】:

    标签: verilog hdl iverilog


    【解决方案1】:

    由于模块是用单独的端口定义的,因此每个端口都必须单独连接。 Verilog 不提供自动连接端口的内置方式。

    SystemVerilog 有.* 连接,但它仅在 net/var 名称与端口名称匹配时才有效。因此,使用 SystemVerilog,您可以连接中间分配。 (注意:所有现代 Verilog 模拟器都支持大部分(如果不是全部)SystemVerilog 功能。只需将文件灭绝从 .v 更改为 .sv 即可启用)

    logic clock;
    logic [15:0] inputs;
    wire [22:0] outputs;
    wire m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16;
    wire S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24;
    assign {m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16} = inputs;
    assign outputs = {S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24};
    mymodule tc( .* );
    

    为了更简洁的解决方案,我推荐 Emacs 插件 Verilog-Mode (vim wrapper exists)。该工具是专门为简化 Verilog 项目常见的长端口列表连接和其他重复性任务而创建的。例如,下面将扩展为索引到索引连接

    /* mymodule AUTO_TEMPLATE (
      .m@       (inputs[\1]),
      .S@       (outputs[\1]),
    ); */
    mymodule dut (/*AUTOINST*/);
    

    除了m18 明确连接到inputs[13] 之外,以下两个模板将扩展一个偏移量。 (我选择了m18,因为我注意到没有m14,它被定义在m13m15之间)

    /* mymodule AUTO_TEMPLATE (
      .m@       (inputs[@"(- \1 1)"]),
      .S@       (outputs[@"(- \1 6)"]),
    ); */
    mymodule dut (
      .m18      (inputs[13]),
       /*AUTOINST*/);
    

    /* mymodule AUTO_TEMPLATE (
      .m18      (inputs[13]),
      .m@       (inputs[@"(- \1 1)"]),
      .S@       (outputs[@"(- \1 6)"]),
    ); */
    mymodule dut (/*AUTOINST*/);
    

    【讨论】:

      【解决方案2】:

      除了使用某种代码生成之外,在常规 Verilog 中,您必须单独连接所有端口。您可以执行以下操作:

      reg  [2:0] inp = $random;
      wire [2:0] outp;
      
      mymodule my (clk, inp[1:0], inp[2], outp[1:0], outp[2], ...);
      

      将所有内容分配给同一个向量,但仍需要输入所有内容。

      【讨论】:

      • 只是不要将您的输入变量命名为input。它是一个verilog 关键字
      • 好的,将所有输入设置为随机怎么样?我是否也必须单独执行此操作?
      • @ched 如果你使用数组作为输入,你可以用 for 循环填充它:tci tc(clk, in[0], in[1], in[2]... for (i=0; i<16; i=i+1) in[i] = $random;
      【解决方案3】:

      您可以使用 `define 指令将各个位连接到测试台中的数组中:

      `define inputs {m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m18,m15,m16}
      `define outputs {S26,S25,S22,S27,S14,S11,S17,S10,S13,S16,S6,S12,S19,S18,S15,S7,S9,S20,S28,S23,S8,S21,S24}
      

      然后,你可以使用 $random 任务:

      initial
      begin
      
      ...
      
      `inputs = $random;
      
      ...
      
      end
      

      【讨论】:

        猜你喜欢
        • 2019-10-06
        • 1970-01-01
        • 1970-01-01
        • 2020-03-18
        • 1970-01-01
        • 2015-06-09
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        相关资源
        最近更新 更多