[英]calculation of simulation time in verilog
我想计算一个计算一个素数的模拟时间,也就是计算一个素数的时钟周期数。 众所周知,计算大素数比计算小素数需要更多的时钟周期。
每当计算素数并将其捕获在time_s
寄存器中$time
,我都会在 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
不是integer
,在幕后它们是相同的。 但由于它只是一个整数,因此仅限于时间刻度 time_unit* 的准确性。 因此,我建议您实际使用realtime
,这是幕后的真实情况。
对于显示时间,可以使用%t
代替实数的%f
的%d
小数。 这个的格式可以通过$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 设置小数点,因此当使用time
或integer
记录时间戳时,精度的任何进一步准确性都会丢失。
`timescale <time_unit>/ <time_precision>
有关详细信息,请参阅IEEE 1800-1012 的第 22.7 节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.