【问题标题】:calculation of simulation time in verilog在verilog中计算模拟时间
【发布时间】:2014-12-17 09:39:24
【问题描述】:

我想计算一个素数计算的模拟时间,也就是计算一个素数的时钟周期数。众所周知,大素数的计算比小素数需要更多的时钟周期。

每当计算素数并将其捕获到time_s 寄存器中时,我都会在 Verilog 中使用$time。我计算了另一个素数之后的计算差异。这是我的代码,您可以在其中看到time_s1 捕获了计算素数的时间。 time_s2是计算差值的时间。

module prime_number_count(
  input clk
);

//for count 1
parameter N =100;          // size of array
parameter N_bits = 32;
reg     [N_bits-1:0] prime_number[0:N-1]; // memory array for prime_number 
reg     [N_bits-1:0] prime_aftr50 [0:49]; // memory array to get       
integer     k;               // counter variable   
integer     k1;               // counter variable   
integer     count;  
integer     test;
integer     time_s1;
integer     time_s2;
integer      check; //Counts 1 to k
localparam S_INC   = 2'b01;
localparam S_CHECK = 2'b10;
reg [1:0] state;

initial begin
 prime_number[0] = 'd1;
 prime_number[1] = 'd2;
  //prime_aftr50[0] = 'd0;
  state           = S_CHECK; //Check set count first
  count           = 'd3;
  k               = 'd2; //0,1 preloaded
  check           = 'd1;
  test            = 'd1;
   time_s1            = 'd0;
   time_s2            = 'd0;
     k1               = 'd0;
end

always @(posedge clk ) 
 begin

         $display ("time of clock   %d ", $time );
        if(state == S_INC)
        begin  // if state is 1
          //$display("State: Incrementing Number to check %d", count+1);
          count <= count+1 ;
          state <= S_CHECK ;           // chang the state to 2
          check <= 'd1; // Do not check against [0] value 1
          test  <= 'd1; // Safe default
        end     

        else if (state == S_CHECK) begin
             if (test == 0) begin
             // Failed Prime test (exact divisor found)
              $display("Reject        %3d", count);
              state           <= S_INC ;
             end
             else 
            if (time_s2>30000)begin
             prime_number[k]=prime_number[k-1];
             time_s1         <=$realtime ;
         state           <= S_INC ;     
             k               <=  k + 1;              
             $display("Found %1d th Prime_1 %1d", k, count);
             $display("display of simulation time" , time_s2);
             end // end of simulation time
             else 

                    if (check == k) begin
                      //Passed Prime check
                      time_s1         <=$time ;
                      prime_number[k] <=  count;
                      k               <=  k + 1;
                      state           <= S_INC ; 
                      $display("Found %1d th Prime_1 %1d", k, count);
                      $display("display of simulation time" , time_s2);
                      end

             else begin
             //$display("Check");
             test  <= count % prime_number[check] ;
             check <= check + 1;
             //$display("Checking %1d against %1d prime %1d : %1d", count, check, prime_number[check], count % prime_number[check]); 
             end
      end
end     
 ////////////////////////////////////////////////////////////////// 
always @(posedge clk )
begin 
     if(check==k-1)
     begin
     time_s2 <=$realtime-time_s1;
    // $display("display of simulation time" , time_s2) ;
     end
 end

always @ (posedge clk) begin
  if ( k==51+(50*k1)) begin
    prime_aftr50[k1] <= count;
    k1               <= k1+1;   
  end               
end

endmodule

【问题讨论】:

  • 与其用$time然后计算时差,不如自己计算时钟滴答数,打印时钟滴答差?

标签: verilog simulation


【解决方案1】:

时间背景

从语义上讲,我建议使用time 而不是integer,在幕后它们是相同的。但由于它只是一个整数,因此仅限于时间刻度 time_unit* 的准确性。因此,我建议您实际使用 realtime,这是真正的幕后操作。

对于显示时间,%t 可以用来代替 %d 的小数点 %f 用于实数。可以通过$timeformat控制其格式。

realtime capture = 0.0;
//To change the way (below) is displayed
initial begin
  #80.1ns;
  capture = $realtime;
  $display("%t", capture);
end

控制%t 的显示方式:

//$timeformat(unit#, prec#, "unit", minwidth);
$timeformat(-3, 2, " ms", 10);    // -3 and " ms" give useful display msg

unit      is the base that time is to be displayed in, from 0 to -15
precision is the number of decimal points to display.
"unit"    is a string appended to the time, such as " ns".
minwidth  is the minimum number of characters that will be displayed.

unit:  recommended "unit" text
  0 =   1 sec
 -1 = 100 ms
 -2 =  10 ms
 -3 =   1 ms 
 -4 = 100 us
 -5 =  10 us
 -6 =   1 us 
 -7 = 100 ns
 -8 =  10 ns
 -9 =   1 ns 
-10 = 100 ps
-11 =  10 ps
-12 =   1 ps 
-13 = 100 fs
-14 =  10 fs
-15 =   1 fs 

通过这些更改:realtime 类型、$realtime 捕获和显示与 %t 分析仿真时间变得更加容易。

解决方案

现在计算找到素数之间的时间:

将以下内容添加到intial begin

$timeformat(-9, 2, " ns", 10); 

然后在将素数添加到列表中的状态下,您只需添加以下内容:

          //Passed Prime check
          time_s2         = time_s1; //Last Prime
          time_s1         = $realtime ;
          $display("Found %1d th Prime_1 %1d", k, count);
          $display("Found at time : %t", time_s1);
          $display("Time Diff      : %t", time_s1 - time_s2);

EDA Playground 上的工作示例。

时间尺度

*:verilog 模拟的时间标度由设置,time_unit 设置小数点,因此在使用timeinteger 记录时间戳时,任何进一步的精度都会丢失。

`timescale <time_unit>/ <time_precision>

有关详细信息,请参阅IEEE 1800-1012 的第 22.7 节。

【讨论】:

  • 这是在模拟中显示值的格式.. Reject 5058 Found 677 th Prime_1 5059 Found at time : 24905100.00 ns Time Diff : 71500.00 ns Found 677 th Prime_1 5059
  • 我想获得时间的实际值,以便我可以将此值用于另一个问题....@Morgan .. 我认为时间的实际值以 ns 为单位。如果我不使用时间格式。
  • @fame313 时间单位将基于````timescale time_unit ```。如果您将其显示为十进制 时间格式,您至少可以检查单位是否正确。
  • 我不想显示时间值。我必须使用时差值来解决另一个问题。请你告诉我时间单位是什么,以便我可以在 if 循环中使用它
  • @fame313 我不是建议你显示时间,而是使用格式化选项来检查你的单位,时间差异仍然是要显示的时间值。您需要检查如何使用 `timescale / 或默认设置您的单位。如果您仍然遇到困难,请尝试发布一个最小示例作为新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
  • 2017-06-11
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
相关资源
最近更新 更多