-
Notifications
You must be signed in to change notification settings - Fork 35
/
axi_m_monitor.sv
108 lines (96 loc) · 3.63 KB
/
axi_m_monitor.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
class axi_m_monitor extends uvm_monitor;
`uvm_component_utils(axi_m_monitor)
// Components
uvm_analysis_port#(axi_transaction#(D_WIDTH, A_WIDTH)) ap;
virtual axi_intf#(.D_WIDTH(D_WIDTH), .A_WIDTH(A_WIDTH)).SMON vif;
// variables
axi_transaction#(D_WIDTH, A_WIDTH) w_trans, r_trans;
bit w_done, r_done;
int b_size;
// Methods
extern task run_mon(uvm_phase phase);
extern task write_monitor();
extern task read_monitor();
function new(string name, uvm_component parent);
super.new(name, parent);
w_done = 1;
r_done = 1;
endfunction //new()
// Function: build_phase
extern function void build_phase(uvm_phase phase);
// Function: run_phase
extern task run_phase(uvm_phase phase);
endclass //axi_m_monitor extends uvm_monitor
function void axi_m_monitor::build_phase(uvm_phase phase);
ap = new("ap", this);
endfunction: build_phase
task axi_m_monitor::run_phase(uvm_phase phase);
forever begin
run_mon(phase);
@(vif.mon_cb);
end
endtask: run_phase
task axi_m_monitor::run_mon(uvm_phase phase);
fork
if(w_done) begin
phase.raise_objection(this);
w_done = 0;
write_monitor();
w_done = 1;
phase.drop_objection(this);
end
if(r_done) begin
phase.raise_objection(this);
r_done = 0;
read_monitor();
r_done = 1;
phase.drop_objection(this);
end
join_none
endtask: run_mon
task axi_m_monitor::write_monitor();
if(vif.mon_cb.AWVALID && vif.mon_cb.AWREADY) begin
w_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("w_trans");
w_trans.addr = vif.mon_cb.AWADDR;
w_trans.id = vif.mon_cb.AWID;
w_trans.b_size = vif.mon_cb.AWSIZE;
w_trans.b_len = vif.mon_cb.AWLEN;
w_trans.b_type = B_TYPE'(vif.mon_cb.AWBURST);
w_trans.data = new [w_trans.b_len+1];
for (int i=0; i<w_trans.b_len+1; i++) begin
@(vif.mon_cb);
wait(vif.mon_cb.WVALID && vif.mon_cb.WREADY);
w_trans.data[i] = new [D_WIDTH/8];
for (int j=0; j<D_WIDTH/8; j++) begin
w_trans.data[i][j] = vif.mon_cb.WDATA[8*j+:8];
end
end
wait(vif.mon_cb.BVALID);
w_trans.b_resp = vif.mon_cb.BRESP;
ap.write(w_trans);
`uvm_info("MMON", $sformatf("WTRANS %s", w_trans.convert2string()), UVM_HIGH)
end
endtask: write_monitor
task axi_m_monitor::read_monitor();
if(vif.mon_cb.ARVALID && vif.mon_cb.ARREADY) begin
r_trans = axi_transaction#(D_WIDTH, A_WIDTH)::type_id::create("r_trans");
r_trans.addr = vif.mon_cb.ARADDR;
r_trans.id = vif.mon_cb.ARID;
r_trans.b_size = vif.mon_cb.ARSIZE;
r_trans.b_len = vif.mon_cb.ARLEN;
r_trans.b_type = B_TYPE'(vif.mon_cb.ARBURST);
r_trans.data = new [r_trans.b_len+1];
r_trans.r_resp = new [r_trans.b_len+1];
for (int i=0; i<r_trans.b_len+1; i++) begin
@(vif.mon_cb);
wait(vif.mon_cb.RVALID && vif.mon_cb.RREADY);
r_trans.data[i] = new [D_WIDTH/8];
for (int j=0; j<D_WIDTH/8; j++) begin
r_trans.data[i][j] = vif.mon_cb.RDATA[8*j+:8];
end
r_trans.r_resp[i] = vif.mon_cb.RRESP;
end
ap.write(r_trans);
`uvm_info("MMON", $sformatf("RTRANS %s", r_trans.convert2string()), UVM_HIGH)
end
endtask: read_monitor