How can I determine the register bit widths correctly? - verilog

This is the simple code I wrote.From 'outt' I get 122116. But if I change 'outt' width to be 33 bits ([32:0]) then code seems to work and give the correct answer -140028. What is the reason for this behaviour??
`timescale 1ns / 1ps
module valu_parser(clk,outt);
input clk;
reg signed [31:0] r_1;
reg signed [31:0] r_2;
output reg signed [31:0] outt;
initial begin
r_1 = -47938;
r_2 = -150096;
end
always # (posedge clk) begin
outt <= ((r_1 + r_2)* 11585 + 8192)>>>14;
end
endmodule

You are performing an operation that needs at least 33 bits (the temporary result before the right shift uses 33 bits) and theoretically it could need 32+"the size of the multiplicand constant" assuming that r_1 and r_2 are not constants.
If you think of the hardware your code will generate, these bits needs to be stored somewhere temporarily to allow the hardware to first perform multiplication, then addition followed by the right shift.
This will do the trick, but will also generate more registers than you wanted initially. If you are using this module to generate a constant, I would recommend hard-coding the constant.
module valu_parser(clk,outt);
input clk;
reg signed [31:0] r_1;
reg signed [31:0] r_2;
reg signed [32:0] temp;
output reg signed [31:0] outt;
initial begin
r_1 = -47938;
r_2 = -150096;
end
always # (posedge clk) begin
temp <= ((r_1 + r_2)* 11585 + 8192);
end
assign outt = temp>>>14;
endmodule
The concept can be seen here: https://www.edaplayground.com/x/3BXy.

In an expression Verilog needs to decide how many bits to use in the calculation.
The + and * operators result in what are called context-determined expressions. With the expression F = A + B; the number of bits used is the maximum of F, A, and B. This usually works fine, because normally you would ensure that F was wide enough to store the result of adding A and B. Likewise with the expression F = A * B; would usually work fine, because normally you would ensure that F was wide enough to store the result of multiplying A and B.
However, by adding the shift right operator you have been able to make the variable being assigned narrower than the number of bits actually needed to calculate the expression on the left of the shift operator. The number of bits Verilog uses in the calculation is the maximum of the width of outt, r_1, r_2, 11585 and 8192. All of these are 32 bits wide (including 11585 and 8192), so 32 bits are used in the calculation. As you have discovered, 32 bits is not enough, but, with the values you have chosen, 33 bits is. With other values, 33 bits wouldn't be enough either. For a completely flexible solution, you should be using 66 bits (32 + 32 + 1 + 1) - 32 bits + 32 bits for the multiplication plus 1 more bit for each addition.
The solution to your problem is to make r_1 and/or r_2 wider or to use an intermediate value (as suggested by Hida's answer here).

When you multiply -198034 (r1+r1) on 11585 you have in result highest bit is 0 (outt[31]), then if you have 32bit signed value its start be positive and in answer you have positive result. And when you change it for 33bit your highest bit is 1 (outt[32]) and result is negative value and you have correct answer.

Related

How to get the square and cube of a fractional number (say 0.78) in verilog?

I am new to Verilog/System Verilog and I wanted to implement the square and cube a fractional number. Consider the following example
module test(
input wire [31:0] input,
output reg [63:0] output
);
reg [63:0] temp;
always # (*) begin
temp = input*input;
output <= temp*input;
end
endmodule
So, when my input is 32'h0_C7AE147 (0.78 in the hexadecimal number system using the 32 bits representation and assuming _ is the equivalent of . in Verilog) I expect an output of 32'h0_797C3D6 (0.4745 in decimal number system)
But I am getting an output of 64'hD546_4A9C_ED94_2917
Also, how to handle the increasing bit sizes in a multiplication?
When we multiply two N-bit wide operands, we get an output of width 2N-bits. When we multiply this 2N-bit wide number with a k bit wide number, we get a number of widths 2N+k-bit wide and this process goes on.
You mean you want to represent fractional number in 32-bit fixed point notation with 4-bit integer part + 28-bit fractional part? And why do you need 64 bits for output?
Anyway I think you need to shift the product to the right by 28 bits for each multiplication.
Try:
temp = input * input >> 28;
output <= temp * input >> 28;
If you need proper rounding, do it before each shifting.

the difference between a[b+1] and a[b+1'b1]

when I try to write to a[b+1] where the bits of b are all '1' ,the value of the reg a[0] do not update,but when I try a[b+1'b1],it updated
awaddr_wa <= awaddr_wa + 2;
awaddr[awaddr_wa] <= AWADDR_M;
awlen [awaddr_wa] <= 4'd0;
awaddr[awaddr_wa+6'd1] <= AWADDR_M+16;
awlen [awaddr_wa+6'd1] <= 4'd0
so ,why?
Here is a reproducible example:
module M;
integer a[0:7] = {0,1,2,3,4,5,6,7};
reg [2:0] b = -1;
initial
begin
$display("a[b+1]=", a[b+1]);
$display("a[b+1'b1]=", b+1'b1);
end
endmodule
https://www.edaplayground.com/x/26Za
(Your question would be better had it included this)
You will see that the output is something like:
a[b+1]= x
a[b+1'b1]=0
1 is 32 bits wide. (All unbased literals in Verilog are 32 bits
wide.)
When you mix bit widths like this in Verilog, Verilog must
decide how many bits to use.
When you index an array out of range in Verilog this is not a catastrophe like it is in C. Instead the default value for the type of the array is returned. a is an array of integers, whose default value is 32'bx.
With a[b+1], Verilog will take the wider of 3 bits (b) and 32 bits (1), ie 32 bits. So, with b=3'b111, 1 is added to b using 32-bit arithmetic. In 32-bit arithmetic, 7+1 is 8, so a[b+1] is the same as a[8] which is out of range and hence 32'bx.
With a[b+1'b1], Verilog will take the wider of 3 bits (b) and 1 bit (1'b1), ie 3 bits. So, with b=3'b111, 1'b1 is added to b using 3-bit arithmetic. In 3-bit arithmetic, 7+1 is 0, so a[b+1'b1] is the same as a[0] which is not out of range and is 32'b0 in my example.
This is a classic trap in Verilog. It is an example of a Verilog self-determined expression. A self-determined expression is one where the number of bits used for the calculation depends only the widths of the operands. There are also context-determined expressions (eg F = A + B) where the number of bits also depends on the width of the variable (or net) being assigned to.

Is there automatic vector width coercion in Verilog?

Suppose I have a small vector:
wire [15:0] a;
and I assign it to a larger vector:
reg [31:0] b;
always #(posedge clk) begin
b <= a;
end
What would be the result? Will b be assigned with zeros in its higher word, or will the high part remain unmodified? Something else?
I've tried searching for the answer in other sources, but all examples I've found had matching widths in the left an right operands of an assignment.
The behaviour of Verilog in this case is well defined. With your example, because by default values are unsigned, you will get this behaviour:
if the left hand bit (bit 15) of a is 1'b0 or 1'b1 then a will be extended to 32 bits wide by zero-padding. ie bits 31 to 16 of b will be 1'b0.
if the left hand bit (bit 15) of a is 1'bx or 1'bz then a will be extended to 32 bits wide by copying that value. ie bits 31 to 16 of b will be 1'bx if bit 15 is 1'bz or 1'bz if bit 15 is 1'bx.
If a were signed, ie if a were declared like this:
wire signed [15:0] a;
then
the behaviour when the left hand bit is 1'bx or 1'bz would be the same as if it were unsigned - the value is just copied.
when the left hand bit is 1'b0 or 1'b1 that left hand bit is sign-extended, ie again the value of that left hand bit is just copied. This behaviour does not depend on whether b is signed or unsigned, only on whether a is signed or unsigned.
the result will assign zeros in the higher order bits. synthesis also possible.
module larger(input [7:0]a, output [15:0] b);
assign b = a;
endmodule
check for your self for this code.

Multiplying two 32 bit numbers using 32 bit carry look ahead adder

I have tried to write the code in Verilog to multiply two 32 bit binary numbers using a 32 bit carry look ahead adder but my program fails to compile. the generate if condition must be a constant expression error keeps on coming in Modelsim for the part 'if(store[0]==1)' and 'if(C[32]==1)'
This is the algorithm that I followed:
Begin Program
Multiplier = 32 bits
Multiplicand = 32 bits
Register = 64 bits
Put the multiplier in the least significant half and clear
the most significant half
For i = 1 to 32
Begin Loop
If the least significant bit of the 64-bit register
contains binary ‘1’
Begin If
Add the Multiplicand to the Most Significant
Half using the CLAA
Begin Adder
C[0 ] = ’0’
For j = 0 to 31
Begin Loop
Calculate Propagate P[j] = Multiplicand[j]^ Most Significant Half[j]
Calculate Generate G[j] =
Multiplicand[j]·Most Significant Half[j]
Calculate Carries C[i + 1] = G[i] + P[i] ·
C[i]
Calculate Sum S[i] = P[i] Å C[i]
End Loop
End Adder
Shift the 64-bit Register one bit to the right
throwing away the least significant bit
Else
Only Shift the 64-bit Register one bit to the
right throwing away the least significant bit
End If
End Loop
Register = Sum of Partial Products
End Program
Code:
module Multiplier_32(multiplier,multiplicand,store);
output store;
input [31:0]multiplier,multiplicand;
wire [63:0]store;
genvar i,j;
wire g=32;
wire [31:0]P,G,sum;
wire [32:0]C;
assign store[31:0]=multiplier;
generate for(i=0;i<32;i=i+1)
begin
if(store[0]==1)
begin
assign C[0]=0;
for(j=0;j<32;j=j+1)
begin
assign P[j]= multiplicand[j]^store[g];
assign G[j]=multiplicand[j]&store[g];
assign C[j+1]=G[i]|(P[i]&C[j]);
assign sum[j]=P[i]^C[j];
assign g=g-1;
end
assign store[63:32]=sum[31:0];
if(C[32]==1)
begin
assign store[62:0]=store[63:1];
assign store[63]=1;
end
else
begin
assign store[62:0]=store[63:1];
assign store[63]=0;
end
end
else
begin
assign store[62:0]=store[63:1];
assign store[63]=0;
end
end
endgenerate
endmodule
A generate block is evaluated at compile/elaboration time. They are used to construct hardware from patterns and not to evaluate logic. The value of store[0], C[32], and all other signals are unknown at this time. The only know values are parameters and genvars.
In this case, a combinational block (always #*) will fulfill your functionality requirements. Replace all your wire with reg, but all your assignments inside a always #*, and remove all the assign keywords (assign should not be used inside an always block).
module Multiplier_32(
input [31:0] multiplier, multiplicand,
output reg [63:0] store
);
integer i,j;
integer g;
reg [31:0] P,G,sum;
reg [32:0] C;
always #* begin
g = 32;
store[31:0]=multiplier;
for(i=0;i<32;i=i+1) begin
// your code here, do not use 'assign'
end
end
endmodule

Which is a better method of designing an upcounter in verilog from the ones mentioned below?

I have declared an 8 bit register variable count
reg [7:0]count=0;
count is supposed to increment from 8'h00 to 8'hFF & back to 8'h00 & increment again so on.
Below i am providing 2 ways of doing this
always #(posedge Clk)
begin
if(count==8'hFF)
count<=8'h0;
else
count<=count+1;
end
OR
always #(posedge Clk)
begin
count<=count+1;
end
In the 1st case, count will go from 00 to FF & 00 to FF again & again.
In the 2nd case also, count will go from 00 to FF then overflow to 00 with a carry & increment to FF again & again.
Will that carry affect anything & how? Also which method is better synthesis wise?
Either method will work. The best result is dependent on the how smart/dump your synthesizing tool is. Some tools issue warnings when it sees an overflow is possible. If you want to resolve the warning, you can use the below method:
reg [7:0] count = 0;
wire [8:0] next_count = count + 1'b1; // MSB is overflow bit
always #(posedge Clk)
count <= next_count[7:0]; // overflow bit not used in assignment
The overflow bit could be done in the synchronous block. Unless you plan on using the overflow bit, I would not recommend these as it will either waste a flop (dumb synthesizer) or issue a warning that a flop has been optimized out (smart synthesizer).
reg [7:0] count = 0;
reg overflow;
always #(posedge Clk)
{overflow,count} <= count + 1'b1; // optimization warning OR wasted flop
According to IEEE Std 1364™-2005
should an arithmetic add of two 16-bit values perform the evaluation using 16 bits, or should the evaluation use 17 bits in order to allow for a possible carry overflow? The answer depends on the type of device being modeled and whether that device handles carry overflow. The Verilog HDL uses the bit length of the operands to determine how manybits to use while evaluating an expression. The bit length rules are given in 5.4.1. In the case of the addition operator, the bit length of the largest operand, including the lefthand side of an assignment, shall be used
They have given an example which I think is applicable for this case:
reg[15:0] a, b; // 16-bit regs
reg[15:0] sumA; // 16-bit reg
reg[16:0] sumB; // 17-bit reg
sumA = a + b; // expression evaluates using 16 bits
sumB = a + b; // expression evaluates using 17 bits
So, hopefully it won't affect the synthesis and is better than previous one.

Resources