Verilog测试台代码

时间:2013-03-20 07:38:16

标签: verilog

任何人都可以帮我编写以下代码的verilog测试平台代码! 我试过但它不起作用!

module top(clock_in, Reset, Hold, up_down, Led_Out, f);     
  input clock_in, Reset, Hold, up_down;
  output      [6:0] Led_Out;        
  output wire [3:0] f;

  wire pulse;

  clock_design temp0(clock_in, pulse);
  up_down_counter temp1(pulse, Reset, Hold, up_down, f);
  led7 temp2(Led_Out, f);
endmodule

led7:<​​/ p>

module led7(iOut, iQ);
  output reg [6:0] iOut;
  input      [3:0] iQ;

  always @(iQ)
    case (iQ)
      4'b0000: iOut = 7'b0000001; //0
      4'b0001: iOut = 7'b1001111; //1
      4'b0010: iOut = 7'b0010010; //2
      4'b0011: iOut = 7'b0000110; //3
      4'b0100: iOut = 7'b1001100; //4
      4'b0101: iOut = 7'b0100100; //5
      4'b0110: iOut = 7'b0100000; //6
      4'b0111: iOut = 7'b0001111; //7
      4'b1000: iOut = 7'b0000000; //8
      4'b1001: iOut = 7'b0000100; //9
      default: iOut = 7'b0000000; //default
    endcase  
  endmodule

up_down_counter:

 module up_down_counter (Clock,Reset,Hold,up_down,Q);
   input Clock,Reset,Hold,up_down;
   output reg [3:0] Q;
   integer direction;


    always @(posedge Clock)
    begin
      if(up_down)
        direction = 1;
      else
        direction = -1;

     if (!Reset && direction == 1)
        Q <= 0;
      else if(!Reset && direction == -1)
        Q <= 1001;
      else if (!Hold)           
        Q <= Q + direction; 

      if (direction==1  && Q[0]==1 && Q[1]==0 &&Q[1]==0 && Q[3]==1)
        Q <= 0; 
      else if (direction==-1 && Q[0]==0 && Q[1]==0 &&Q[2]==0 && Q[3]==0)
        Q <= 1001;
      end
    endmodule

clock_design:

module clock_design (clock_in,clock_out);
  input clock_in;
  output clock_out;
  parameter which_clock=1;
  reg [31:0] divided_clocks=0;

  always @(posedge clock_in)
    divided_clocks = divided_clocks +1;

  assign clock_out = divided_clocks[which_clock];
endmodule

我的测试台代码

module counter_tb;
  reg  [6:0] Led_Out_tb;
  wire [3:0] f_tb;
  reg  clock_in_tb, Reset_tb, Hold_tb, up_down_tb;

  top dut(clock_in_tb, Reset_tb,Hold_tb, up_down_tb, Led_Out_tb, f_tb);

  initial begin
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 1;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 1;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
    #10 clock_in_tb = 0;Hold_tb = 0;Reset_tb = 1; up_down_tb = 0;
  end
endmodule

1 个答案:

答案 0 :(得分:6)

Testbench明智地我会设置一个时钟并重置如下:

reg clk ; //Rising edge every 10 timesteps
initial begin
  clk = 0;
  #5; 
  forever begin
    #5 clk = ~clk;
  end
end

// TB Reset_tb
reg Reset_tb
initial begin
  Reset_tb = 0;
  @(posedge clk);
  @(posedge clk);
  Reset_tb = 1;
end

对于实际测试,例如:

//The actual test
initial begin
  Hold_tb    = 0;
  up_down_tb = 1;
  repeat (50) begin
    @(posedge clk);
  end
  up_down_tb = 1;
  repeat (50) begin
    @(posedge clk);
  end
  $finish();
end

关于守则

你有一段看起来应该是always @(posedge clk)块中的组合逻辑。

always @(posedge Clock)
begin
  if(up_down)
    direction = 1;
  else
    direction = -1;

我认为这应该是:

 always @* begin
   if(up_down)begin
     direction = 1;
   end
   else begin
     direction = -1;
   end
 end

如果您不包含begin end,则if语句仅适用于下一行。我会更频繁地使用开始结束,因此您的代码会明确显示您的意图。

您有以下代码部分:

  if (!Reset && direction == 1)
    Q <= 0;
  else if(!Reset && direction == -1)
    Q <= 1001;
  else if (!Hold)           
    Q <= Q + direction; 

  if (direction==1  && Q[0]==1 && Q[1]==0 &&Q[1]==0 && Q[3]==1)
    Q <= 0; 
  else if (direction==-1 && Q[0]==0 && Q[1]==0 &&Q[2]==0 && Q[3]==0)
    Q <= 1001;

4号是否还缺少其他? if (direction==1 && Q[0]==1 && Q[1]==0 &&Q[1]==0 && Q[3]==1)

我会避免在RTL中使用整数类型,因为它们通常是矫枉过正的,特别是在这里你只是存储1或-1,实际上只需要1位值。注册和电线可以签名:

reg signed signed_reg ;
reg signed [7:0] signed_reg8;

您也可以将常量声明为signed:

reg_signed = 1'sd-1 ; //1Bit Signed Decimal value -1

我发现使用混合大小写信号名称是不好的做法,我总是使用小写。参数和localparams等常量都是大写的。这会使拼写错误的可能性降低,你可能会花费多年时间来尝试锻炼为什么某些东西不起作用然后你意识到其中一个连接是使用小写而不是大写第一个字符。