blob: c07ccfbf2a2ea4d36d1eb19c9d573809502c8bc7 [file] [log] [blame] [view]
lowRISC Contributors802543a2019-08-31 12:12:56 +01001{{% lowrisc-doc-hdr Comportable IP Testbench Architecture }}
2
3Going along the lines of what it takes to design an IP that adheres to the
4[Comportability Specifications](../../../../doc/rm/comportability_specification.md),
5we attempt to standardize the DV methodology for developing the IP level
6testbench environment as well by following the same approach. This document describes
7the Comportable IP (CIP) library, which is a complete UVM enviromnent framework that
8each IP level environment components can extend from to get started with DV. The goal
9here is to maximize code reuse across all test benches so that we can improve the
10efficiency and time to market. The features described here are not exhaustive,
11so it is highly recommended to the reader that they examine the code directly. In
12course of development, we also periodically identify pieces of verification logic that
13might be developed for one IP but is actually a good candidate to be added to
14these library classes instead. This doc is instead intended to provide the user
15a foray into what these are and how are the meant to be used.
16
17{{% toc 3 }}
18
19
20## CIP environment block diagram
21![CIP environment block diagram](env.svg)
22
23## CIP library classes
24The CIP library includes the base ral model, env cfg object, coverage
25object, virtual sequencer, scoreboard, env, base virtual sequence and finally
26the test class. To achieve run-time polymorphism, these classes are type
27parameterized to indicate what type of child objects are to be created. In the
28IP environments, the extended classes indicate the correct type parameters.
29
30### cip_base_env_cfg
31This class is intended to contain all of the settings, knobs, features, interface
32handles and downstream agent cfg handles. Features that are common to all IPs in
33accordance with the comportability spec are made a part of this base class, while the
34extended IP env cfg class will contain settings specific to that IP. An instance of
35the env cfg class is created in `cip_base_test::build_phase` and the handle is
36passed over uvm_config_db for the CIP env components to pick up. This allows
37the handle to the env cfg object to be available in the env's build_phase. Settings
38in the env cfg can then be used to configure the env based on the test needs.
39
40A handle to this class instance is passed on to the scoreboard, virtual
41sequencer and coverage objects so that all such common settings and features
42are instantly accessible everywhere.
43
44This class is type parameterized in the following way:
45```
46class cip_base_env_cfg #(type RAL_T = dv_base_reg_block) extends uvm_object;
47```
48The IP env cfg class will then extend from this class with the RAL_T parameter set
49to the actual IP RAL model class. This results in IP RAL model getting factory
50overridden automatically in the base env cfg itself during creation, so there is no
51need for manual factory override. We follow the same philosophy in all CIP library
52classes.
53
54The following is a list of common features and settings:
55* **clk_rst_if**: A handle to the clk_rst_if that controls the main clk and reset
56 to the DUT.
57* **intr_vif**: This is a handle to the `pins_if #(NUM_MAX_INTERRUPTS=64)` interface
58 instance created in the tb to hookup the DUT interrupts. The actual number of
59 interrupts might be much less than 64, but that is ok - we just connect as
60 many as the DUT provides. The reason for going with a fixed width pins_if is
61 to allow the intr_vif to be available in this base env cfg class (which does not
62 know how many interrupt each IP DUT provides).
63* **alerts_vif**: This is a handle to the `pins_if #(NUM_MAX_ALERTS=64)` interface
64 instance created in the tb to hookup the DUT alerts, similar to intr_vif.
65* **devmode_vif**: THis is a handle to the `pins_if #(1)` interface instance created
66 in the tb to hookup the DUT input `devmode`.
67* **tl_agent_cfg**: The downstream TileLink host agent created in the cip_base_env
68 class requires the agent cfg handle to tell it how to configure the agent.
69* **ral**: This is the instance to the auto-generated RAL model that is
70 extended from `dv_base_reg_block`. In the base class, this is created using
71 the RAL_T class parameter which the extended IP env cfg class sets correctly.
72
73Apart from these, there are several common settings such as `zero_delays`,
74`clk_freq_mhz`, which are randomized as well as knobs such as `en_scb` and
75`en_cov` to turn on/off scoreboard and coverage collection respectively.
76
77The base class provides a virtual method called `initialize()` which is called
78in `cip_base_test::build_phase` to create some of the objects listed above. If
79the extended IP env cfg class has more such objects added, then the `initialize()`
80method is required to be overridden to create those objects as well.
81
82We make all downstream interface agent cfg handles as a part of IP extension of
83cip_base_env_cfg so that all settings for the env and all downstream agents are
84avaiable within the env cfg handle. Since the env cfg handle is passed to all cip
85components, all those settings are also accesible.
86
87### cip_base_env_cov
88This is the base coverage object that contain all functional coverpoints and
89covergroups. The main goal is to have all functional coverage elements
90implemented in a single place. This class is extended from `uvm_component`
91so that it allows items to be set via `'uvm_config_db` using the component's
92hierarchy. This is created in cip_base_env and a handle to it is passed to the
93scoreboard and the virtual sequencer. This allows coverage to be sampled in
94scoreboard as well as the test sequences.
95
96This class is type parameterized with the env cfg class type `CFG_T` so that it
97can derive coverage on some of the env cfg settings.
98```
99class cip_base_env_cov #(type CFG_T = cip_base_env_cfg) extends uvm_component;
100```
101
102### cip_base_virtual_sequencer
103This is the base virtual sequencer class that contains a handle to the
104`tl_sequencer` to allow layered test sequences to be created. The extended IP
105virtual sequencer class will include handles to the IP specific agent
106sequencers.
107G
108This class is type-parameterized with the env cfg class type `CFG_T` and coverage
109class type `COV_T` so that all test sequences can access the env cfg settings and
110sample the coverage via the `p_sequencer` handle.
111```
112class cip_base_virtual_sequencer #(type CFG_T = cip_base_env_cfg,
113 type COV_T = cip_base_env_cov) extends uvm_sequencer;
114```
115
116### cip_base_scoreboard
117This is the base scoreboard component that already connects with the TileLink
118agent monitor to grab tl packets via analysis port at the address and the data
119phases. It provides a virtual task called `process_tl_access` that the extended
120IP scoreboard needs to implement. Please see code for additional details. The
121extended IP scoreboard class will connect with the IP-specific interface monitors
122if applicable to grab items from those analysis ports.
123
124This class is type-parameterized with the env cfg class type `CFG_T`, ral class
125type `RAL_T` and the coverage class type `COV_T`.
126```
127class cip_base_scoreboard #(type RAL_T = dv_base_reg_block,
128 type CFG_T = cip_base_env_cfg,
129 type COV_T = cip_base_env_cov) extends uvm_component;
130```
131There are several virtual tasks and functions that are to be overridden
132in extended IP scoreboard class. Please take a look at the code for more
133details.
134
135### cip_base_env
136This is the base UVM env that puts all of the above components together
137and creates and makes connections across them. In the build phase, it retrieves
138the env cfg class type handle from `uvm_config_db` as well as all the virtual
139interfaces (which are actually part of the env cfg class). It then uses the env
140cfg settings to modify the downstream agent cfg settings as required. All of
141the above components are created based on env cfg settings, along with the TileLink
142host agent. In the connect phase, the scoreboard connects with the monitor
143within the TileLink agent to be able to grab packets from the TL interface
144during address and the data phases. In the end of elaboration phase, the ral
145model within the env cfg handle is locked and the ral sequencer and adapters are
146set to be used with the TileLink interface.
147
148This class is type parameterized with env cfg class type CFG_T, coverage class type
149`COV_T`, virtual sequencer class type `VIRTUAL_SEQUENCER_T` and scoreboard class
150type `SCOREBOARD_T`.
151```
152class cip_base_env #(type CFG_T = cip_base_env_cfg,
153 type VIRTUAL_SEQUENCER_T = cip_base_virtual_sequencer,
154 type SCOREBOARD_T = cip_base_scoreboard,
155 type COV_T = cip_base_env_cov) extends uvm_env;
156```
157
158### cip_base_vseq
159This is the base virtual sequence class that will run on the cip virtual
160sequencer. This base class provides 'sequencing' set of tasks such as
161`dut_init()` and `dut_shutdown()` which are called within `pre_start` and
162`post_start` respectively. This sequence also provides an array of
163sub-sequences some of which are complete tests within themselves, but
164implemented as tasks. The reason for doing so is SystemVerilog does not
165support multi-inheritance so all sub-sequences that are identified as being
166common to all IP benches implemented as tasks in this base virtual sequence class.
167Some examples:
168* **task run_csr_vseq_wrapper**: This is a complete CSR test suite in itself -
169 Extended IP CSR vseq can simply call this in the body. This is paired with a
170 helper function `add_csr_exclusions`.
171* **function add_csr_exclusions**: This is extended in the IP CSR vseq to add
172 exclusions when running the CSR suite of tests.
173* **task tl_access**: This is a common generic task to create a read or a write
174 access over the TileLink host interface.
175* **task cfg_interrupts, check_interrupts**: All interrupt CSRs are standardized
176 according to the comportability spec, which allows us to create common tasks
177 to turn on / off interrupts as well as check them.
178
179This class is type parameterized with the env cfg class type `CFG_T`, ral class type
180`RAL_T` and the virtual sequencer class type `VIRTUAL_SEQUENCER_T` so that the
181env cfg settings, the ral CSRs are accessible and the `p_sequencer` type can be
182declared.
183
184```
185class cip_base_vseq #(type RAL_T = dv_base_reg_block,
186 type CFG_T = cip_base_env_cfg,
187 type COV_T = cip_base_env_cov,
188 type VIRTUAL_SEQUENCER_T = cip_base_virtual_sequencer) extends uvm_sequence;
189```
190All virtual sequences in the extended IP will eventually extend from this class and
191can hence, call these tasks and functions directly as needed.
192
193### cip_base_test
194This basically creates the IP UVM env and its env cfg class instance. Any env cfg
195setting that may be required to be controlled externally via plusargs are looked
196up here, before the env instance is created. This also sets a few variables that
197pertain to how / when should the test exit on timeout or failure. In the run
198phase, the test calls `run_seq` which basically uses factory to create the
199virtual sequence instance using the `UVM_TEST_SEQ` string that is passed via
200plusarg. As a style guide, it is preferred to encapsulate a complete test within
201a virtual sequence and use the same `UVM_TEST` plusarg for all of the tests (which
202points to the extended IP test class), and only change the `UVM_TEST_SEQ` plusarg.
203
204This class is type parameterized with the env cfg class type `CFG_T` and the env
205class type `ENV_T` so that when extended IP test class creates the env and env cfg
206specific to that IP.
207```
208class cip_base_test #(type CFG_T = cip_base_env_cfg,
209 type ENV_T = cip_base_env) extends uvm_test;
210```
211
212# Extending from CIP library classes
213Let's say we are verifying an actual comportable IP `uart` which has `uart_tx`
214and `uart_rx` interface. User then develops the `uart_agent` to be able to talk
215to that interface. User invokes the `ralgen` tool to generate the `uart_reg_block`,
216and then starts developing UVM environment by extending from the CIP library
217classes in the following way.
218
219## uart_env_cfg
220```
221class uart_env_cfg extends cip_base_env_cfg #(.RAL_T(uart_reg_block));
222```
223User adds the `uart_agent_cfg` object as a member so that it remains as a
224part of the env cfg and can be accessed everywhere. In the base class's
225`initialize()` function call, an instance of `uart_reg_block` is created, not
226the `dv_base_reg_block`, since we override the `RAL_T` type.
227
228## uart_env_cov
229```
230class uart_env_cov extends cip_base_env_cov #(.CFG_T(uart_env_cfg));
231```
232User adds `uart` IP specific coverage items and uses the `cov` handle in
233scoreboard and test sequences to sample the coverage.
234
235## uart_virtual_sequencer
236```
237class uart_virtual_sequencer extends cip_base_virtual_sequencer #(.CFG_T(uart_env_cfg),
238 .COV_T(uart_env_cov));
239```
240User adds the `uart_sequencer` handle to allow layered test sequences
241to send traffic to / from TileLink as well as `uart` interfaces.
242
243## uart_scoreboard
244```
245class uart_scoreboard extends cip_base_scoreboard #(.CFG_T(uart_env_cfg),
246 .RAL_T(uart_reg_block),
247 .COV_T(uart_env_cov));
248```
249User adds analysis ports to grab packets from the `uart_monitor` to
250perform end-to-end checking.
251
252## uart_env
253```
254class uart_env extends cip_base_env #(.CFG_T (uart_env_cfg),
255 .COV_T (uart_env_cov),
256 .VIRTUAL_SEQUENCER_T (uart_virtual_sequencer),
257 .SCOREBOARD_T (uart_scoreboard));
258```
259User creates `uart_agent` object in the env and use it to connect with the
260virtual sequencer and the scoreboard. User also uses the env cfg settings to
261manipulate the uart agent cfg settings if required.
262
263## uart_base_vseq
264```
265class uart_base_vseq extends cip_base_vseq #(.CFG_T (uart_env_cfg),
266 .RAL_T (uart_reg_block),
267 .COV_T (uart_env_cov),
268 .VIRTUAL_SEQUENCER_T (uart_virtual_sequencer));
269```
270User adds a base virtual sequence as a starting point and adds common tasks and
271functions to perform `uart` specific operations. User then extends from
272`uart_base_vseq` to add layered test sequences.
273
274## uart_base_test
275```
276class uart_base_test extends cip_base_test #(.ENV_T(uart_env), .CFG_T(uart_env_cfg));
277```
278User sets `UVM_TEST` plus arg to `uart_base_test` so that all tests create the UVM env
279that is automatically tailored to UART IP. Each test then sets the
280`UVM_TEST_SEQ` plusarg to run the specific test sequence, along with additional
281plusargs as required.
282
283# CIP Testbench
284![CIP testbench diagram](tb.svg)
285The block diagram above shows the CIP testbench architecture, that puts
286together the static side `tb` which instantiates the `dut`, and the dynamic
287side, which is the UVM environment extended from CIP library. The diagram
288lists some common items that need to be instantiated in `tb`
289and set into `uvm_config_db` for the testbench to work.