0

谁能帮我为以下代码编写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:

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

时钟设计:

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
4

1 回答 1

8

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 endif 语句,则仅适用于下一行。我会更频繁地使用开始结束,以便您的代码明确显示您的意图。

您有以下代码部分:

  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有没有遗漏?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;

您还可以将常量声明为有符号:

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

我发现使用混合大小写的信号名称是不好的做法,我总是使用小写。像参数和局部参数这样的常量都是大写的。这使拼写错误的可能性降低了,您可能会花费很长时间来尝试确定某些内容无法正常工作的原因,然后您会意识到其中一个连接使用的是小写而不是大写的第一个字符。

于 2013-03-20T09:32:14.400 回答