-
Notifications
You must be signed in to change notification settings - Fork 50
/
tb_new_usb_nonperiodiccounter.sv
115 lines (105 loc) · 2.74 KB
/
tb_new_usb_nonperiodiccounter.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2024 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Fabian Hauser <[email protected]>
//
/// Testbench module for nonperiodiccounter
`timescale 1ps/1ps
module tb_new_usb_nonperiodiccounter #(
/// Parameters
) (
/// SoC clock and reset
// input logic soc_clk_i,
// input logic soc_rst_ni,
);
`include "common_cells/registers.svh"
localparam int unsigned period = 2000; // 500 MHz
localparam int unsigned halfperiod = period/2;
localparam int unsigned input_delay = 100;
localparam int unsigned reset_active = 2*period + 50; // reset active time
localparam int unsigned reset_wait = 1100; // wait for initial reset
localparam int unsigned td_1c = 6*period; // First Control TD served takes very long after a complete reset until this happens
localparam int unsigned td_2c = 3*period;
localparam int unsigned td_3c = 6*period;
localparam int unsigned td_4c = 8*period;
localparam int unsigned td_b = 4*period;
localparam int unsigned td_high = 4*period; // How long served is high
logic clk_i;
logic rst_ni;
logic served_control_td;
logic served_bulk_td;
logic [1:0] cbsr;
logic overflow;
logic threshold;
initial begin
clk_i = 1;
forever #halfperiod clk_i = ~clk_i;
end
initial begin
rst_ni = 1;
#reset_wait;
rst_ni = 0;
#reset_active;
rst_ni = 1;
end
initial begin
@(posedge clk_i);
#input_delay;
served_control_td = 0;
served_bulk_td = 0;
cbsr = 0;
@(posedge clk_i);
#input_delay;
#period;
cbsr = 3;
#td_1c;
served_control_td = 1;
@(posedge clk_i);
#input_delay;
#td_high;
served_control_td = 0;
@(posedge clk_i);
#input_delay;
#td_2c;
served_control_td = 1;
@(posedge clk_i);
#input_delay;
#td_high;
served_control_td = 0;
@(posedge clk_i);
#input_delay;
#td_3c;
served_control_td = 1;
@(posedge clk_i);
#input_delay;
cbsr = 1;
#td_high;
served_control_td = 0;
@(posedge clk_i);
#input_delay;
#td_4c;
served_control_td = 1;
@(posedge clk_i);
#input_delay;
#td_high;
served_control_td = 0;
@(posedge clk_i);
#input_delay;
#td_b;
served_bulk_td = 1;
@(posedge clk_i);
#input_delay;
#td_high;
served_bulk_td = 0;
end
new_usb_nonperiodiccounter i_nonperiodiccounter (
.clk_i,
.rst_ni,
.served_bulk_td_i(served_bulk_td), // successfully served bulk transfer descriptor
.served_control_td_i(served_control_td), // successfully served control transfer descriptor
.cbsr_i(cbsr),
.counter_overflown_o(overflow), // enough control EDs served
.counter_is_threshold_o(threshold) // signals last control ED to send for listservice
);
endmodule