Verilog 参数化位宽转换设计实例

   本设计包含一个位宽转换单元(如:将输入的4位的数据转换为8位数据输出),一个向上计数器模块,一个top层,一个testbench。全部采用参数化设计。

    位宽转换单元converter.v代码如下:

    本文引用自:https://blog.csdn.net/llxxyy507/article/details/82790808

module converter #(parameter WIDTH = 4, PAD_NUM = 1) // parameter defaults.
       (output[WIDTH-1+PAD_NUM:0] out_bus,  // default variable type: wire 
        input [WIDTH-1:0]         in_bus,   // header port IEEE1364-2001 
        input                     enable
       );
  
  reg[WIDTH-1+PAD_NUM:0] bus_reg;      // internal variables; Retains current count value.
  reg[WIDTH-1+PAD_NUM:0] out_bus_gate; // Retains three-state.
  
  // --------------main code --------------------------------------------------------
  // Keep bus_reg always updated (combinational circuit): assign, always@(level_list)
  always@(in_bus) // list sensitivity
  begin
    // This could be done by concatenation, a later topic:
    // bus_reg[WIDTH-1:0] = in_bus;
    if (PAD_NUM!=1'b0) begin
      bus_reg[(WIDTH-1+PAD_NUM):WIDTH] = 'b0; // PAD with 0.
      bus_reg[WIDTH-1:0] = in_bus;
    end
    else // syn-RTL coding style, if not => latch
      bus_reg[WIDTH-1:0] = in_bus;

  end
  
  // Next block controls the state of the output drivers:
  always@(enable, bus_reg) // IEEE-1364 1995 "," => "or'
  begin
    if (enable==1'b1)
         #2 out_bus_gate = bus_reg;
    else #1 out_bus_gate = 'bz; // Set high-impedance.
  end

     converter.v将输入的 input [WIDTH-1:0]    in_bus,转换为 output[WIDTH-1+PAD_NUM:0]   out_bus,多余的位直接补零。

    计数器counter.v模块代码如下:

module counter #(parameter WIDTH = 4)    // default parameter
                (output[WIDTH-1:0] count, 
                 input clk, count_enable, count_reset
                );
  // ------------ internal variables --------------------------
  reg[WIDTH-1:0] count_reg;   // Store the count. Outputs are always registed.
  wire           clock_wire;  // To gate the clock during disable.
 
  //-------------- main code -----------------------------------
  // Keep the count wired to the output:
  assign #1 count = count_reg;
  
  // Don't count while disabled: clock gating
  assign clock_wire = (count_enable==1'b1)? clk : 1'b0;
  
  // Do the counter: sequential circuit, async-reset
  always@(posedge clock_wire, posedge count_reset)
  begin
    if (count_reset==1'b1) 
           count_reg <= 'b0; // Ignore width.
    else count_reg <= count_reg + 1'b1;
  end
  
endmodule // counter

  计数器counter.v实现 2^WIDTH 向上计数。

   设计的top层param_counter_top.v代码如下:

`define PADWIDTH 3  // Global width; controls parameter values.
                    // No reference to PADWIDTH except at top.

module param_counter_top  // Top-level params in ANSI format:
      #(parameter WIDTH = `PADWIDTH,  // Saves repeated "-1".
                  PAD_NUM = 5         // The Count width control.
       )
       ( output[WIDTH-1+PAD_NUM:0] count,
         input  clk, count_enable, count_reset, out_enable);
  
  wire[WIDTH-1:0] Xfer;  // Local bus to connect module instances.
 
  // instance - hirarchy (XMR)
  // Pass parameter values by name (position):
  counter #(.WIDTH(WIDTH)) 
          u_counter( .count        (Xfer        ), 
                     .clk          (clk         ), 
                     .count_enable (count_enable), 
                     .count_reset  (count_reset )
                   );
  
  converter #(.WIDTH(WIDTH), .PAD_NUM(PAD_NUM))  
            u_converter01( .out_bus    (count), 
                           .in_bus     (Xfer), 
                           .enable     (out_enable)
                         );
  
endmodule // param_counter_top.

      top层中例化了上面两个模块,且定义了一个宏 `define PADWIDTH 3 ,但在接下来的tb.v中又重新定义了 `PADWIDTH ,使用synopsys公司 vcs仿真时,会显示后面定义的 PADWIDTH 会把前面的覆盖,即 最终仿真的时候 PADWIDTH 为5。

     本设计的tb.v模块代码如下:

`define PADWIDTH 5  // Global width; controls parameter values.
                    // No reference to PADWIDTH except at top.
module tb;
  
  // The parameter definitions in TestBench are redundant,
  // because testbench will not be synthesized.
  // Changing testbench param values will override the
  // values in the design, which become defaults when
  // the design is instantiated in the testbench module:
  //
  parameter WIDTH = `PADWIDTH , PAD_NUM = 3;
  //
  wire[WIDTH-1+PAD_NUM:0] CountTest;
  reg count_enableTest,
      clockTest,    
      CountResetTest,
      OutEnableTest;
  
  // Design instance:
  param_counter_top
      #(.WIDTH(WIDTH), .PAD_NUM(PAD_NUM)) // Pass testbench size to design.
    u_param_counter_top (
         .count         (CountTest        ),
         .count_enable  (count_enableTest ),
         .clk           (clockTest        ),
         .count_reset   (CountResetTest   ),
         .out_enable    (OutEnableTest    )
       );
  
  initial
    begin
    #01 clockTest        = 1'b0;
        count_enableTest = 1'b0;
        CountResetTest   = 1'b0;
        OutEnableTest    = 1'b0;
    #02 CountResetTest   = 1'b1;
    #02 CountResetTest   = 1'b0;
    //
    #01 count_enableTest = 1'b1;
    #02 OutEnableTest    = 1'b1;
    // Later, we shall see better ways to
    // define a clock:
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #01 OutEnableTest    = 1'b0;
    #02 OutEnableTest    = 1'b1;
    #05 clockTest        = 1'b1;  // clock skips #3 here.
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #05 clockTest        = 1'b0;
    #05 clockTest        = 1'b1;
    #10 $finish;
    end
    initial begin
      $vcdpluson();
    end
  
endmodule // tb

本设计的testbench与top连接的时候,将参数也传递过去了,所以整个设计的参数值全来自testbench,

`define PADWIDTH 5 

parameter WIDTH = `PADWIDTH , PAD_NUM = 3;

尽管在前面的模块中有定义,但最终仿真中的数据WIDTH 为5,PAD_NUM为3。

猜你喜欢

转载自blog.csdn.net/llxxyy507/article/details/82790808