Most real signals are not a single bit. A vector is a signal that holds several bits at once, and you declare its width with a range, written as a high index down to a low index. A signal that holds eight bits, for example, spans index seven down to index zero. The width you choose is a promise about how many bits the signal can carry.
This is different from what you declared in Page 03, where each signal was a single bit. Vectors are how you represent buses, register values, addresses, and data paths — everything that carries more than one bit at a time. The rest of this page is about keeping the width promise you make when you declare one.
There are two ways to group bits. A packed array is a contiguous block of bits you can treat as a single number, which is what you want for buses and anything you do arithmetic on. An unpacked array is a collection of separate elements, which is what you want for things like a memory or a list, where each element stands on its own.
The distinction matters because a packed array behaves like a wide integer — you can slice it, assign a number to it, compare it directly. An unpacked array behaves like a list of separate signals. Use packed when the thing is one value. Use unpacked when it is many. In this lab and in most bus-level verification work, you will be working with packed vectors.
Once a signal holds several bits, you often want only some of them. Indexing picks a single bit by its position. Slicing picks a range of bits, written as a high index down to a low index, and gives you back a smaller vector. In an eight-bit signal declared [7:0], bit seven is the most significant bit and bit zero is the least significant.
Getting the indices right is the difference between reading the field you meant and reading the wrong bits entirely. An off-by-one on a slice range shifts every bit you read by one position. The result compiles cleanly, runs without error, and produces wrong data. The only defence is counting carefully.
Here is the trap, and it is one of the most common bugs in real designs. If you assign a wide value to a signal that is too narrow, the extra top bits are silently dropped. Nothing errors. The value is simply wrong from that point on.
The most common form is an off-by-one width: a signal declared one bit too narrow, or a slice range off by a single index. These mistakes hide precisely because they do not crash. The discipline that prevents them is simple: count the bits you need, declare exactly that many, and check your slice ranges. This lab makes a width mistake visible so you learn to catch it before it costs you.
A narrowly declared address bus in a register file quietly drops the top address bits. Every access lands on the wrong register. The simulation compiles, the waveform looks busy, and the bug ships. Width hygiene is not a detail. It is structural correctness.
Declare each signal below with the correct width, then complete the slice so it extracts the top four bits. Run and submit. The test drives a full-width value through your declarations and checks that no bits were lost.
Weekly intelligence on VLSI, AI for EDA, and chip careers. 20,000+ engineers already inside.