1.6.1 Register index

EasyImplementIcarus Verilog · browserReview the topic

Turn a byte address into a register index, and reject every address that is not exactly one of the four registers.

Hardware context: Memory-mapped control/status register bank. Convert an aligned bus address into the correct control-register index.

A timer test reported a DUT bug, but the DUT was right. The testbench model computed the register index by subtracting the base and shifting, so it rounded the misaligned address 0x40001001 down to register 0 and predicted a normal write.

This peripheral has four 32-bit registers at 0x40001000, 0x40001004, 0x40001008 and 0x4000100C. Write register_index(address), which returns 0, 1, 2 or 3 for those four addresses and -1 for every other address.

The whole 32-bit address counts. 0x40001003 is inside the block but is not the start of a register, so it returns -1. So does 0x50001004, which has the right low bits in the wrong page, and 0x40001010, the first byte past the block.

Signals in the timeline

SignalWidthRole
address32input of each check
Full specification
Signature (keep it)
function automatic int register_index(input logic [31:0] address);
addressreturns
0x400010000
0x400010041
0x400010082
0x4000100C3
anything else-1

Addresses are known 32-bit byte addresses. A register address is in the range [0x40001000, 0x40001010) and is a multiple of 4.

Examples

Example 1

The third register
Input
address = 0x40001008
Output
index = 2

0x40001008 is inside the block and a multiple of 4: (0x8) / 4 = 2.

Example 2

Inside the block, but not a register
Input
address = 0x40001003
Output
index = -1

The low two bits are 11, so this is not the start of a register. Rounding down to 0 would be wrong.

Example 3

The first byte past the block
Input
address = 0x40001010
Output
index = -1

The block ends just before 0x40001010, so there is no register 4.

Constraints and contract

  • address is a known 32-bit unsigned value.
  • Return -1 for every address that is not one of the four register addresses.
  • Keep the function name and signature.

Hints

Hint 1

Write the rule as two checks: is the address inside the block, and is it a multiple of 4? Only then compute an index.

Hint 2

Which bits of the address show that it is not a multiple of 4? What happens to them if you shift first?

Hint 3

Compare the full 32-bit address against both ends of the block, using a half-open range, before you subtract the base.

What this judge verifies: Your decoder is called on every byte address around the block, on the same offsets in other pages and on single-bit address flips. Passing shows only the four register addresses decode.

185 checks on Icarus Verilog · browser. 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 6 steps and the final capstone
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

The third register

Input
address = 0x40001008
Expected output
index = 2

0x40001008 is inside the block and a multiple of 4: (0x8) / 4 = 2.

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

Icarus Verilog · browser