A configurable memory or queue needs consistent widths for data, addresses and occupancy. Address width counts locations; occupancy width must also represent the full condition. Non-power-of-two depths require explicit wrap logic and invalid-address handling. Parameterization is a correctness problem, not just replacing a number with a name.
Worked example
For a depth of eight, three bits address a location, but four bits are needed to represent every occupancy from zero through eight. The example exposes these calculated widths in simulation so their boundary meanings are visible.
module example;
localparam DEPTH=8;
localparam ADDR_W=(DEPTH<=1)?1:$clog2(DEPTH);
localparam COUNT_W=$clog2(DEPTH+1);
initial begin
$display("address bits=%0d count bits=%0d",ADDR_W,COUNT_W); // 3, 4
$finish;
end
endmodule
What to watch for
A three-bit occupancy counter cannot represent eight. A pointer's width and a queue's item-count width need not be equal.
Try it yourself
Does a three-bit pointer automatically wrap correctly for DEPTH=6?
Answer: No. Its binary wrap is eight. A six-entry design must explicitly wrap after location five and prevent accesses to unused addresses.
How to study this topic
Save the example in a .v file and identify its top module before compiling. Separate stimulus and observation from synthesizable RTL. Change one input, width or boundary condition at a time, predict the result, and compare that prediction with simulation. A syntax check does not establish synthesis support or timing closure.
Continue learning
Previous: Generate loops and conditional generation
Next: Compiler directives and includes
Browse the complete Verilog index
Explore related programmes
These recorded programmes are upcoming. This article is general educational content, not a syllabus or course sample.
Verilog