-
Notifications
You must be signed in to change notification settings - Fork 11
/
rcc_driver.sv
executable file
·190 lines (134 loc) · 4.78 KB
/
rcc_driver.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
* Driver communicates with the DUT at pin level.
* It receives the stimulus from the sequencer in form of transactions
* Within Driver synchroization betwen sequencer and driver takes place via handshaking
*/
class rcc_driver extends uvm_driver#(rcc_transaction);
`uvm_component_utils(rcc_driver)
// virtual interface declaration
virtual rcc_if vif;
uvm_analysis_port #(rcc_transaction) din_cov;
uvm_analysis_port #(rcc_transaction) addrs_cov;
rcc_transaction cov_din_tx;
rcc_transaction cov_addr_tx;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
din_cov = new("din_cov", this);
addrs_cov = new("addrs_cov", this);
cov_din_tx = rcc_transaction::type_id::create("cov_din_tx", this);
cov_addr_tx = rcc_transaction::type_id::create("cov_addr_tx", this);
// get the virtual interface handle that was stored in the uvm_config_db
// and assign it to the local vif field
if(!uvm_config_db#(virtual rcc_if)::get(this, "", "vif", vif))
`uvm_fatal("No Vif", {"virtual interface must be set for: ", get_full_name(), ".vif"});
endfunction: build_phase
bit [3:0] g_address, digcnt, qcnt;
bit [15:0] g_din;
// using sequence_item_port connect with sequencer
// get the transaction and then drive the DUT
task run_phase(uvm_phase phase);
reset(); // reset task
forever
begin
rcc_transaction rcc_tx;
seq_item_port.get_next_item(rcc_tx); // get the transaction from sequencer
digcnt = rcc_tx.digcnt;
seq_item_port.item_done();
repeat(digcnt)
begin
repeat(4) // wait for 4 clock edges //
@(posedge vif.clk);
g_address = 0;
seq_item_port.get_next_item(rcc_tx);
g_din = rcc_tx.g_din;
seq_item_port.item_done();
cov_din_tx.g_din = g_din; // for din coverage
din_cov.write(cov_din_tx);
repeat(8) // for 8 registers write the data //
begin
write_it;
g_address = g_address +1;
//if(rcc_tx.randomize())
seq_item_port.get_next_item(rcc_tx);
// g_din = rcc_tx.g_din;
seq_item_port.item_done();
seq_item_port.get_next_item(rcc_tx);
g_din = rcc_tx.g_din;
seq_item_port.item_done();
//$display("input: %h", g_din);
cov_din_tx.g_din = g_din; // for din coverage
din_cov.write(cov_din_tx);
end
//cov_din_tx.g_din = g_din; // for din coverage
//din_cov.write(cov_din_tx);
write_it;
g_address = 0;
repeat(160)
@(posedge vif.clk);
end //digcnt
//if(rcc_tx.randomize())
seq_item_port.get_next_item(rcc_tx);
qcnt = rcc_tx.qcnt;
seq_item_port.item_done();
repeat(qcnt)
begin
repeat(4)
@(posedge vif.clk);
g_address = 0;
g_din = 0;
//seq_item_port.get_next_item(rcc_tx);
//rcc_tx.g_din = g_din;
// seq_item_port.item_done();
repeat(8)
begin
write_it;
g_address = g_address +1;
end
write_it;
g_address = 0;
repeat(160)
@(posedge vif.clk);
end //qcnt
//seq_item_port.item_done(); // transaction complete
end //forever loop
endtask // run_phase
task write_it();
@(posedge vif.clk);
vif.address <= g_address;
vif.din <= g_din;
cov_addr_tx.g_address = g_address; // for addrs coverage
addrs_cov.write(cov_addr_tx);
@(posedge vif.clk);
vif.rcc_clk <= 1;
@(posedge vif.clk);
vif.rcc_clk <= 0;
@(posedge vif.clk);
vif.din <= 'bz;
endtask
//bit [8:0] [15:0] temp;
// reset task, Resets the interface signals to default/initial values
task reset();
vif.test_mode = 0;
vif.scan_in0 = 0;
vif.scan_in1 = 0;
vif.scan_en = 0;
vif.din = 16'h0000;
vif.address = 4'h0;
vif.rcc_clk = 1'b0;
vif.reset = 1'b0;
// assertion checks
//vif.dout = 8'haa;
// vif.dout_flag = 1'b0;
@(negedge vif.clk);
@(negedge vif.clk);
vif.reset = 1;
$display("----------- RESET START------");
@(negedge vif.clk);
@(negedge vif.clk);
vif.reset = 0;
$display("------------ RESET ENDS-----------");
endtask
endclass: rcc_driver