Skip to content

Commit 71303a0

Browse files
committed
Updated delayed_event testbench
1 parent 8043f65 commit 71303a0

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed

delayed_event_tb.sv

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
//------------------------------------------------------------------------------
2+
// delayed_event_tb.sv
3+
// published as part of https://github.com/pConst/basic_verilog
4+
// Konstantin Pavlov, pavlovconst@gmail.com
5+
//------------------------------------------------------------------------------
6+
7+
// INFO ------------------------------------------------------------------------
8+
// Testbench for delayed_event.sv
9+
10+
// use this define to make some things differently in simulation
11+
`define SIMULATION yes
12+
13+
`timescale 1ns / 1ps
14+
15+
module delayed_event_tb();
16+
17+
initial begin
18+
// Print out time markers in nanoseconds
19+
// Example: $display("[T=%0t] start=%d", $realtime, start);
20+
$timeformat(-9, 3, " ns");
21+
22+
// seed value setting is intentionally manual to achieve repeatability between sim runs
23+
$urandom( 1 ); // SEED value
24+
end
25+
26+
logic clk200;
27+
sim_clk_gen #(
28+
.FREQ( 200_000_000 ), // in Hz
29+
.PHASE( 0 ), // in degrees
30+
.DUTY( 50 ), // in percentage
31+
.DISTORT( 10 ) // in picoseconds
32+
) clk200_gen (
33+
.ena( 1'b1 ),
34+
.clk( clk200 ),
35+
.clkd( )
36+
);
37+
38+
logic nrst_once;
39+
40+
logic [31:0] clk200_div;
41+
clk_divider #(
42+
.WIDTH( 32 )
43+
) cd1 (
44+
.clk( clk200 ),
45+
.nrst( nrst_once ),
46+
.ena( 1'b1 ),
47+
.out( clk200_div[31:0] )
48+
);
49+
50+
logic [31:0] clk200_div_rise;
51+
edge_detect ed1[31:0] (
52+
.clk( {32{clk200}} ),
53+
.anrst( {32{nrst_once}} ),
54+
.in( clk200_div[31:0] ),
55+
.rising( clk200_div_rise[31:0] ),
56+
.falling( ),
57+
.both( )
58+
);
59+
60+
// external device "asynchronous" clock
61+
logic clk33;
62+
logic clk33d;
63+
sim_clk_gen #(
64+
.FREQ( 200_000_000 ), // in Hz
65+
.PHASE( 0 ), // in degrees
66+
.DUTY( 50 ), // in percentage
67+
.DISTORT( 1000 ) // in picoseconds
68+
) clk33_gen (
69+
.ena( 1'b1 ),
70+
.clk( clk33 ),
71+
.clkd( clk33d )
72+
);
73+
74+
75+
logic rst;
76+
initial begin
77+
rst = 1'b0; // initialization
78+
repeat( 1 ) @(posedge clk200);
79+
80+
forever begin
81+
repeat( 1 ) @(posedge clk200); // synchronous rise
82+
rst = 1'b1;
83+
//$urandom( 1 ); // uncomment to get the same random pattern EVERY nrst
84+
85+
repeat( 2 ) @(posedge clk200); // synchronous fall, controls rst pulse width
86+
rst = 1'b0;
87+
88+
repeat( 100 ) @(posedge clk200); // controls test body width
89+
end
90+
end
91+
logic nrst;
92+
assign nrst = ~rst;
93+
94+
95+
logic rst_once;
96+
initial begin
97+
rst_once = 1'b0; // initialization
98+
repeat( 1 ) @(posedge clk200);
99+
100+
repeat( 1 ) @(posedge clk200); // synchronous rise
101+
rst_once = 1'b1;
102+
103+
repeat( 2 ) @(posedge clk200); // synchronous fall, controls rst_once pulse width
104+
rst_once = 1'b0;
105+
end
106+
//logic nrst_once; // declared before
107+
assign nrst_once = ~rst_once;
108+
109+
110+
// random pattern generation
111+
logic [31:0] rnd_data;
112+
always_ff @(posedge clk200) begin
113+
rnd_data[31:0] <= $urandom;
114+
end
115+
116+
initial forever begin
117+
@(posedge nrst);
118+
$display("[T=%0t] rnd_data[]=%h", $realtime, rnd_data[31:0]);
119+
end
120+
121+
122+
// helper start strobe appears unpredictable up to 20 clocks after nrst
123+
logic start;
124+
initial forever begin
125+
start = 1'b0; // initialization
126+
127+
@(posedge nrst); // synchronous rise after EVERY nrst
128+
repeat( $urandom_range(0, 20) ) @(posedge clk200);
129+
start = 1'b1;
130+
131+
@(posedge clk200); // synchronous fall exactly 1 clock after rise
132+
start = 1'b0;
133+
end
134+
135+
136+
initial begin
137+
// #10000 $stop;
138+
// #10000 $finish;
139+
end
140+
141+
// sweeping pulses
142+
logic sp = 1'b1;
143+
logic [4:0] sp_duty_cycle = 8'd0;
144+
initial forever begin
145+
if( sp_duty_cycle[4:0] == 0 ) begin
146+
sp = 1'b1;
147+
repeat( 10 ) @(posedge clk200);
148+
end
149+
sp = 1'b0;
150+
repeat( 1 ) @(posedge clk200);
151+
sp = 1'b1;
152+
repeat( 1 ) @(posedge clk200);
153+
sp = 1'b0;
154+
repeat( sp_duty_cycle ) @(posedge clk200);
155+
sp_duty_cycle[4:0] = sp_duty_cycle[4:0] + 1'b1; // overflow is expected here
156+
end
157+
158+
159+
// Module under test ===========================================================
160+
161+
logic sp_d1;
162+
always_ff @(posedge clk200) begin
163+
if( sp ) begin
164+
sp_d1 <= 1'b0;
165+
end else begin
166+
sp_d1 <= 1'b1;
167+
end
168+
end
169+
170+
171+
for(genvar i=0; i<16; i++) begin
172+
173+
delayed_event #(
174+
.DELAY( i )
175+
) de (
176+
.clk( clk200 ),
177+
.nrst( ~sp ), //|rnd_data[2:0] ),
178+
.ena( 1'b1 ), //sp_d1 ),
179+
180+
.on_event( ),
181+
.before_event( ),
182+
.after_event( )
183+
);
184+
end
185+
186+
endmodule
187+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy