【问题标题】:Implement testbench on verilog with clock divider and different output使用时钟分频器和不同的输出在 Verilog 中实现测试台
【发布时间】:2016-06-29 17:15:13
【问题描述】:

对于以下代码,这是一个 7 段 59 秒计数器,我正在尝试实现一个测试台。我有两个麻烦:一个是我使用术语 q[24] 作为实习时钟来使其计算近似秒数,但是在测试台中我应该能够在不实现数千个 posedge 时钟的情况下看到不同的输出。另一个麻烦是我想在测试台中看到寄存器 [3:0]unidad 和 [3:0]decena 作为输出,它们是 7 段面板上的每个数字,但在代码中没有使用与 in 或 output 一样,但作为一个内部变量。

如何实现这样的模拟,在合理的时间内显示 decena/unidad 输出?谢谢。

module cont(
   input clock,
   input reset,
   output reg [6:0]segm,
   output [3:0]an
   );

reg [3:0]unidad; 
reg [3:0]decena; 

reg [24:0] q;

always @(posedge clock or posedge reset)
    begin
        if(reset == 1)
         q <= 0;
        else
            q <= q + 1;
    end

always @ (posedge q[24] or posedge reset)
 begin
  if (reset) begin
   unidad <= 0;
   decena <= 0;
  end
  else if (unidad==4'd9) 
    begin  
    unidad <= 0;
     if (decena==4'd5) 
      decena <= 0;
        else
         decena <= decena + 1;
     end
   else
    unidad <= unidad + 1;
  end

reg [6:0]sseg;
reg [3:0]an_temp;
always @ (*)
 begin
  case(q[13])

   1'b0 : 
    begin
     sseg = unidad;
     an_temp = 4'b1110;
    end

   1'b1 :
    begin
     sseg = decena;
     an_temp = 4'b1101;
    end

  endcase
 end
assign an = an_temp;

always @ (*)
 begin
  case(sseg)
   4'd0 : segm = 7'b1000000; //0
   4'd1 : segm = 7'b1111001; //1
   4'd2 : segm = 7'b0100100; //2
   4'd3 : segm = 7'b0110000; //3
   4'd4 : segm = 7'b0011001; //4
   4'd5 : segm = 7'b0010010; //5
   4'd6 : segm = 7'b0000010; //6
   4'd7 : segm = 7'b1111000; //7
   4'd8 : segm = 7'b0000000; //8
   4'd9 : segm = 7'b0010000; //9
   default : segm = 7'b1111111; 
  endcase
 end

endmodule

【问题讨论】:

    标签: verilog counter simulation xilinx


    【解决方案1】:

    您可以强制计数器更接近测试台中感兴趣的值。 你可以通过两种风格来做到这一点。

    1) 将计数器强制设置为接近您感兴趣的值并生成一些时钟周期。

    2) 强制执行您感兴趣的位并等待一些时钟周期。

    在这种情况下 'h1000 和 'h1000000 的值是感兴趣的或位 24 和 13 。

    // function to set the register - replace <DUT>  
    task load_counter ( reg [24:0] val );
    #1 <DUT>.q = val ; //delay is to overwrite the main counter
    endtask
    

    // function to set the counter bit - replace <DUT>
    task count_up  ( int count,int loc , bit val);
    repeat(count) @(posedge clock ) ;
    #1 <DUT>.q[loc] =  val; //delay is to overwrite the main counter
    endtask
    
    // toggle bit 24 and in between toggle bit 13 based on counts.
    // 100 clock is just a value it can be changes.
    task count_24( int count_24,int count_13);
    repeat (count_24)
            begin
            repeat(count_13)
            begin
                    count_up ( 100,13,1);
                    count_up ( 100,13,0);
            end
            count_up ( 1,24,1);
            repeat(count_13)
            begin
                    count_up ( 100,13,1);
                    count_up ( 100,13,0);
            end
            count_up ( 1,24,0);
    end
    endtask
    

    第一种方法

    load_counter(25'hff0);// load and wait for bit 13 to be set 
    repeat(50)  @(posedge clock ) ;
    load_counter(25'h1ff0); // load and wait for bit 13 to be re-set. 
    repeat(50)  @(posedge clock ) ;
    load_counter(25'hf0ff0); //load and wait for bit 13 set ( while other bits > 13 are on )  
    repeat(50)  @(posedge clock ) ;
    load_counter(25'hfffff0); // bit 24 set 
    repeat(50)  @(posedge clock ) ;
    // if needed add set/reset for bit 13 code here 
    load_counter(25'h1fffff0); // load and wait till bit 24 rolls over 
    repeat(50)  @(posedge clock ) ; 
     // repeat the whole process above in a loop to get desired behavior
    

    您还可以随机化每个 24 位切换之间需要查看的 13 位切换的数量以及计数器更改之间需要运行的时钟数量。

    在方案2中

    13 和 24 的计数可以由测试作者确定,也可以随机。

    count_24(10,10)
    

    在选项 1 中,我们让计数器机制完成大部分任务,因此是首选。

    但最后最好还是运行完整的计数器来查看结果。也许您可以将其作为周末回归运行。

    您也可以直接观察TB中的信号。

    wire [3:0] observe_unidad = <DUT>.unidad;
    wire [3:0] observe_decena = <DUT>.decena;
    

    在此处为 tb 添加完整代码 ...

    // this code will not synthesize
    module tb_cont ;
    
    
    reg clock_gen ; // To generate a clock
    reg reset_gen ; // to generate reset
    
    // Main counter instance
    cont  cont_instance (
                    .clock(clock_gen),
                    .reset ( reset_gen)
                    ) ;
    
    // Clock generation block
    initial
    begin
    clock_gen = 0 ;
    
    forever
    begin
            #10 clock_gen = 0 ;
            #10 clock_gen = 1 ;
    end
    end
    
    // Task to write data in the cont- block
    task count_up  ( int count,int loc , bit val);
    repeat(count) @(posedge clock_gen ) ;
    #1  cont_instance.q[loc] =  val; //delay is to overwrite themain counter
    endtask
    
    / toggle bit 24 and in between toggle bit 13 based on counts.
    // 100 clock is just a value it can be changed.
    task count_24( int count_24,int count_13);
    repeat (count_24)
            begin
            repeat(count_13)
            begin
                    count_up ( 100,13,1);
                    count_up ( 100,13,0);
            end
            count_up ( 1,24,1);
            repeat(count_13)
            begin
                    count_up ( 100,13,1);
                    count_up ( 100,13,0);
            end
            count_up ( 1,24,0);
    end
    endtask
    
    // task to load the counter
    task load_counter ( reg [24:0] val );
    #1 cont_instance.q = val ; //delay is to overwrite themain counter
    endtask
    
    
    initial
    begin 
    // dump  waveform to observe signals
    $dumpvars;
    
    // generate a reset first
    reset_gen = 0 ;  
    #100 reset_gen = 0 ;
    #100 reset_gen = 1 ;
    #100 ;
    @(posedge clock_gen ) ;
    reset_gen = 0 ;
    end
    
    // value for the count
    int count13 = 100;
    int count24=100;
    
    // generate test vector
    initial
    begin
    
    repeat( 100 ) @ ( posedge clock_gen ) ; // wait for counter
    load_counter(25'hff0);
    repeat( 100 ) @ ( posedge clock_gen ) ; // wait for counter
    load_counter(25'hfffff0); 
    repeat( 100 ) @ ( posedge clock_gen ) ; // wait for counter
    load_counter(25'h1fffff0);
    repeat( 100 ) @ ( posedge clock_gen ) ; // wait for counter
    
    // scheme 2 
    count_24(10,10);
    
    $finish ;
    end
    
    // both the signal can eb observed 
    wire [3:0] observe_unidad = cont_instance.unidad;
    wire [3:0] observe_decena = cont_instance.decena;
    
    endmodule
    

    【讨论】:

    • 对不起,但我不知道如何实现这一点。我应该如何更换 ?这是我以前从未见过的一些符号。如果有帮助,我正在使用 Verilog 语言使用 Xilinx ISE webpack。此外,它不会读取上面定义了多个变量的任务 count_up,也不会将 .unidad 识别为代码中定义的变量 unidad 以显示它。
    • 对不起,因为只有 RTL 代码我做了一些假设。我假设您只希望测试台在模拟中并且不希望测试台也可综合。此外,测试台将作为 cont 块的包装器构建。我无法知道您的 DUT(被测设计)名称,所以我在那里放置了一个占位符。它可以 cont_instance.unidad (假设 cont_instance 是您的测试台中 cont 的实例)
    • 如果你能提供你的测试平台结构/代码,我可以改进上面的代码
    • 我只有以下几点:
    • 已添加完整的TB代码,您可以查看并根据您要测试的内容添加更多
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多