forked from lowRISC/opentitan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
csrng_agent_cov.sv
158 lines (136 loc) · 5.28 KB
/
csrng_agent_cov.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
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
`define CSRNG_GLEN_COVBIN \
csrng_glen: coverpoint item.glen { \
// TODO: EDN testbench currently sends a max of 64 endpoints, which is 64/4 genbits. \
bins glens[4] = {[1:16]}; \
}
`define CSRNG_STS_COVBIN \
csrng_sts: coverpoint sts { \
bins pass = {CMD_STS_SUCCESS}; \
bins fail = {CMD_STS_INVALID_ACMD, CMD_STS_INVALID_GEN_CMD, \
CMD_STS_INVALID_CMD_SEQ, CMD_STS_RESEED_CNT_EXCEEDED}; \
}
// covergroups
// Depends on whether the agent is device or host mode, the "csrng_cmd_cp" are slightly different:
// In device mode: acmd INV, GENB, GENU are in the illegal bin.
covergroup device_cmd_cg with function sample(csrng_item item, csrng_cmd_sts_e sts);
option.name = "csrng_device_cmd_cg";
option.per_instance = 1;
csrng_cmd_cp: coverpoint item.acmd {
bins ins = {INS};
bins res = {RES};
bins gen = {GEN};
bins uni = {UNI};
bins upd = {UPD};
illegal_bins il = default;
}
csrng_clen_cp: coverpoint item.clen {
bins zero = {0};
bins non_zero_bins[2] = {[1:15]};
}
// TODO: do not use enum to sample non-true/false data
csrng_flag_cp: coverpoint item.flags {
bins mubi_true = {MuBi4True};
bins mubi_false = {MuBi4False};
}
csrng_sts: coverpoint sts {
bins pass = {CMD_STS_SUCCESS};
bins fail = {CMD_STS_INVALID_ACMD, CMD_STS_INVALID_GEN_CMD,
CMD_STS_INVALID_CMD_SEQ, CMD_STS_RESEED_CNT_EXCEEDED};
}
csrng_cmd_cross: cross csrng_cmd_cp, csrng_clen_cp, csrng_sts, csrng_flag_cp {
// Only a value of zero should be used for clen when UNI command is used.
ignore_bins uni_clen = binsof(csrng_cmd_cp.uni) && binsof(csrng_clen_cp.non_zero_bins);
}
endgroup
covergroup host_cmd_cg with function sample(csrng_item item, csrng_cmd_sts_e sts);
option.name = "csrng_host_cmd_cg";
option.per_instance = 1;
csrng_cmd_cp: coverpoint item.acmd {
bins inv = {INV};
bins ins = {INS};
bins res = {RES};
bins gen = {GEN};
bins upd = {UPD};
bins uni = {UNI};
bins genb = {GENB};
bins genu = {GENU};
illegal_bins il = default;
}
csrng_clen_cp: coverpoint item.clen {
bins zero = {0};
bins other_bins[2] = {[1:15]};
}
// TODO: do not use enum to sample non-true/false data
csrng_flag_cp: coverpoint item.flags {
bins mubi_true = {MuBi4True};
bins mubi_false = {MuBi4False};
}
csrng_sts: coverpoint sts {
bins pass = {CMD_STS_SUCCESS};
bins fail = {CMD_STS_INVALID_ACMD, CMD_STS_INVALID_GEN_CMD,
CMD_STS_INVALID_CMD_SEQ, CMD_STS_RESEED_CNT_EXCEEDED};
}
csrng_cmd_clen_flag_cross: cross csrng_cmd_cp, csrng_clen_cp, csrng_flag_cp;
csrng_cmd_clen_flag_sts_cross: cross csrng_cmd_cp, csrng_clen_cp, csrng_flag_cp, csrng_sts {
// Illegal commands (INV, GENB, GENU) don't get a response, thus don't have a status.
ignore_bins illegal_cmds = binsof(csrng_cmd_cp) intersect {INV, GENB, GENU};
// Ignore status error responses for legal commands.
ignore_bins legal_cmds_with_error_sts = !binsof(csrng_cmd_cp) intersect {INV, GENB, GENU} &&
!binsof(csrng_sts) intersect {CMD_STS_SUCCESS};
}
endgroup
// Depends on whether the agent is device or host mode, the "csrng_genbits_cross" are slightly
// different:
// In device mode: csrng agent can drive `sts` to pass or fail randomly.
// In host mode: DUT will also return pass for genbits data.
covergroup device_genbits_cg with function sample(csrng_item item, csrng_cmd_sts_e sts);
option.name = "csrng_device_genbits_cg";
option.per_instance = 1;
`CSRNG_GLEN_COVBIN
`CSRNG_STS_COVBIN
csrng_genbits_cross: cross csrng_glen, csrng_sts;
endgroup
covergroup host_genbits_cg with function sample(csrng_item item, csrng_cmd_sts_e sts);
option.name = "csrng_host_genbits_cg";
option.per_instance = 1;
`CSRNG_GLEN_COVBIN
`CSRNG_STS_COVBIN
csrng_genbits_cross: cross csrng_glen, csrng_sts {
// Generate may not return fail as status.
ignore_bins sts_fail = binsof(csrng_sts.fail);
}
endgroup
class csrng_agent_cov extends dv_base_agent_cov#(csrng_agent_cfg);
host_cmd_cg m_host_cmd_cg;
device_cmd_cg m_device_cmd_cg;
host_genbits_cg m_host_genbits_cg;
device_genbits_cg m_device_genbits_cg;
`uvm_component_utils(csrng_agent_cov)
`uvm_component_new
function void build_phase(uvm_phase phase);
super.build_phase(phase);
if (cfg.if_mode == dv_utils_pkg::Device) begin
m_device_cmd_cg = new();
m_device_genbits_cg = new();
end else begin
m_host_cmd_cg = new();
m_host_genbits_cg = new();
end
endfunction
function void sample_csrng_cmds(csrng_item item, csrng_cmd_sts_e sts);
if (cfg.if_mode == dv_utils_pkg::Device) begin
m_device_cmd_cg.sample(item, cfg.vif.cmd_rsp.csrng_rsp_sts);
if (item.acmd == csrng_pkg::GEN) begin
m_device_genbits_cg.sample(item, cfg.vif.cmd_rsp.csrng_rsp_sts);
end
end else begin
m_host_cmd_cg.sample(item, cfg.vif.cmd_rsp.csrng_rsp_sts);
if (item.acmd == csrng_pkg::GEN) begin
m_host_genbits_cg.sample(item, cfg.vif.cmd_rsp.csrng_rsp_sts);
end
end
endfunction
endclass