U1.4.1 The error test that never broke a checksum

EasyFixUVM · local serverReview the topic

A derived test swaps in an error-injecting driver, yet every length reaches the design with a good checksum. Make the override take effect.

Hardware context: Test family for a length checker sharing one environment. Make an error-injecting driver override take effect before the environment builds it.

A test family shares one environment for a length checker. base_test builds the environment, sends a list of lengths and checks the family member's goal. Each length carries a 4-bit check nibble that the driver computes.

error_test is the family's error member. It must replace the driver with the project's injector, chk_flip_driver, so that every length reaches the design with a bad nibble and comes back with err = 1.

The run reports TEST_GOAL for every length: the design received good nibbles and answered correctly, so nothing was tested. error_test does register the override. Fix error_test so the injector is the driver that runs.

Full specification
ClassWhat it does
base_testbuild_phase creates env; run_phase starts lc_seq on env.sqr; check_phase compares each observed err with goal_err()
lc_envbuild_phase creates sqr, drv (lc_driver through the factory), mon and sb
chk_flip_driverextends lc_driver and flips bit 0 of every check nibble

The bench runs your error_test as the selected test and records, for each length it sent, the nibble on the pins, the design's answer and the type of env.drv. Only error_test is your code.

Examples

Example 1

Length 0x10
Input
error_test sends len = 0x10 (item 1 of 5)
Output
len = 0x10, chk_on_pins = 0x0, correct_chk = 0x1, err = yes, y = 0x0, injector_built = yes

The correct nibble is 1 ^ 0 = 1. The injector drives 0, so the design answers err = 1 and y = 0, which is this test's goal.

Example 2

Length 0xff
Input
error_test sends len = 0xff (item 2 of 5)
Output
len = 0xff, chk_on_pins = 0x1, correct_chk = 0x0, err = yes, y = 0x0, injector_built = yes

The correct nibble is f ^ f = 0; the injector drives 1, and the design rejects it.

Example 3

Length 0x3c
Input
error_test sends len = 0x3c (item 3 of 5)
Output
len = 0x3c, chk_on_pins = 0xe, correct_chk = 0xf, err = yes, y = 0x0, injector_built = yes

The correct nibble is 3 ^ c = f; the injector drives e. With the plain driver this length would come back with err = 0 and y = 0x99.

Constraints and contract

  • Keep error_test's name, its base class and goal_err().
  • Do not change base_test, the environment or the driver classes; use the factory.
  • Every length must reach the pins with a bad nibble.

Hints

Hint 1

An override is a rule for future create calls. Find the create call for the driver: which phase, and which component, makes it?

Hint 2

By the time any run_phase starts, every component already exists.

Hint 3

Put the override where it runs before the environment builds its children. Whether it goes before or after super.build_phase() in your test matters less than you might think: check when lc_env.build_phase runs.

What this judge verifies: Your error_test is extended by the bench and run as the selected test against a real factory, environment and design. The checks read the check nibble on the pins, the design's answer and the type of the driver that was built.

5 checks on UVM · local server. Run the examples first, then check the full regression. The suite is local and inspectable. A passing result establishes the tested cases, not a proof for all possible inputs.

See all 1 problem on this path
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

Length 0x10

Input
error_test sends len = 0x10 (item 1 of 5)
Expected output
len = 0x10, chk_on_pins = 0x0, correct_chk = 0x1, err = yes, y = 0x0, injector_built = yes

The correct nibble is 1 ^ 0 = 1. The injector drives 0, so the design answers err = 1 and y = 0, which is this test's goal.

Run samples executes all 3 example checks. Check all tests runs 5 checks.

UVM · local server