The context is: I have 16-bit registers v1
and v2
. These contain signed (2's complement) 16-bit values, but I decided to stay away from the keyword signed
, and I'm explicitly handling sign-bits where needed.
At some point, I want to store the average of these two values, with a 3/4 factor applied, into the register output
(thus, I want to end up with ouptut
containing ((value1+value2)/2)*3/4
). Rounding errors are expected and acceptable, but overflow isn't.
I figured I'd declare a variable sum
to assign the result of 1.5*value1 + 1.5*value2
to simplify things; in part, the need for simplification is why that intermediate result requires 18-bits. Having assigned sum
, I then simply take its upper 16 bits and that's my result.
In my mind, inside the always @(posedge some_clk)
, inside an if
for the particular condition, I would assign sum
with a blocking assignment, and in the line after, I assign output
with a non-blocking (concurrent) assignment. Something like this:
reg[15:0] v1;
reg[15:0] v2;
reg[17:0] sum;
// ···
always @(posedge some_clk)
begin
// ···
if (counter == some_value)
begin
sum = {v1[15],v1[15],v1[15:0]} // this is v1, with sign extended to make it 18-bit wide
+ {v1[15],v1[15],v1[15],v1[15:1]} // this is v1/2, sign extended to make it 18-bit wide
+ { ··· (same thing, with v2) } ···
output <= sum[17:2]; // This is sum/4 (sign-bit works as is)
end
// ···
end
Two questions:
- Is the use of blocking vs. non-blocking assignments correct, and recommended for these types of situations where one wants to split some complex expression into steps with intermediate results?
- One detail I'm not sure I understand: why do I need to declare
sum
asreg
and notwire
? At first I had declared it aswire
, thinking that since the assignment intosum
is "fictitious" (in any case, it's not a "material" assignment), I figuredwire
would be just like a placeholder... but the compiler gave me an error that I cannot assign to awire
. It compiles now when I changed toreg
, and it seems to work, but I'm still a tad uncomfortable.