systemverilog arithmetic operation returns negative value - verilog

I have a part of code of my design as follows.
parameter n=256;
input [n-1:0] x;
output y;
initial begin
x = 0;
if(0 >= unsigned'(x-9))
y = 1;
end
My expectation is, the unsigned subtraction operation should return decimal 247 but in actual it returns -9. Is anyone having better way of coding to achieve this?
My actual requirement is, even if I subtract a smaller value from larger, the value should rollover w.r.t. parameter width (As if 0-1 should yield 255). My question may be wrong but this requirement is necessary from my project.

247 and -9 are the same bit pattern so the arithmetic is correct. Signed vs unsigned is an interpretation of the bit pattern.
NB: 0-1 is only 255 with 8 bit numbers you have defined them as 256 bit numbers.
The following example should help clarify, We use $signed and $unsigned keywords which alters how the decimal representation is displayed but the underlying binary form does not change.
module tb;
parameter n=8;
logic [n-1:0] x;
logic y;
initial begin
x = 0;
$display("%1d", x-9);
$display("%1b", x-9);
$display("");
$display("%1d", $unsigned(x-9) );
$display("%1b", $unsigned(x-9) );
$display("");
$display("%1d", $signed(x-9) );
$display("%1b", $signed(x-9) );
$display("");
$finish;
end
endmodule
Which Outputs:
4294967287
11111111111111111111111111110111
4294967287
11111111111111111111111111110111
-9
11111111111111111111111111110111
For your example you just need to use $unsigned:
module tb;
parameter n=8;
logic [n-1:0] x;
logic y;
initial begin
x = 0;
if(0 >= $unsigned(x-9)) begin
y = 1;
end
else begin
y = 0;
end
$display("y: %b", y);
$finish;
end
endmodule

Related

Unexpected behaviour using the ternary operator (Verilog)

In the following Verilog module, I'd like to understand why the blocking assignment using concatenation doesn't give the same result as the 2 commented out blocking assignments.
When I run the program on the FPGA, it gives the expected result with the 2 blocking assignments (the leds blink), but not with the blocking assignment using concatenation (the leds stay off).
Bonus points for answers pointing to the Verilog specification explaining what is at play here!
/* Every second, the set of leds that are lit will change */
module blinky(
input clk,
output [3:0] led
);
reg [3:0] count = 0;
reg [27:0] i = 0;
localparam [27:0] nTicksPerSecond = 100000000;
assign led = {count[3],count[2],count[1],count[0]};
always # (posedge(clk)) begin
// This works:
//count = i==nTicksPerSecond ? (count + 1) : count;
//i = i==nTicksPerSecond ? 0 : i+1;
// But this doesn't:
{count,i} = i==nTicksPerSecond ?
{count+1, 28'b0 } :
{count , i+1};
end
endmodule
PS: I use Vivado 2018.2
The reason is because the widths of count+1 and i+1 are both 32 bits. An unsized number is 32 bits wide (1800-2017 LRM section 5.7.1) and the width of the addition operator is the size of the largest operand (LRM section 11.6.1). To make your code work, add a proper size to your numeric literals
{count,i} = i==nTicksPerSecond ?
{count+4'd1, 28'b0 } :
{count , i+28'd1};
A simpler way to write this code is
always # (posedge clk)
if (i== nTicksPerSecond)
begin
count <= count + 1;
i <= 0;
end
else
begin
i <= i + 1;
end

Verilog : Variable index is not supported in signal

I get an error saying 'Index is not supported in signal'. From what I can see the error is on the left hand side of the non-blocking assignment. Why does the code below give an error and is there a way to work around it?
...
parameter width = 32;
parameter size = 3;
input clk, reset;
input [width*size-1:0] A;
input [width*size-1:0] B;
output [width*size-1:0] result;
reg signed [width*size-1:0] partials;
reg signed [width-1:0] temp;
reg signed [width-1:0] currenta;
reg signed [width-1:0] currentb;
wire signed [width-1:0] temp1wire;
...
integer k = 0;
always # (posedge clk)
begin
currenta[width-1:0] <= A[width*k +: width];
k = k+1
currentb[width-1:0] <= B[width*k +: width];
partials[width*k +: width] <= temp1wire;
end
Add Add1(clk, temp1wire, currenta, currentb);
...
This code is part of a sequential block that does vector addition and saves the result at partials[width*k +: width].
I found this on the Xilinx forum:
"XST works fine with the indexed part-select operator "+:" if it is on the right-hand side (RHS) of the assignment. It also works fine when it is on the left-hand side (LHS) AND the starting index is a constant. Your case uses a variable as the starting index on the LHS and that what XST doesn't like although it's legal."
k needs to be clamped or wrapped around after reaching size-1.
Wrapping around can be done with the mod operator (%); example:k = (k+1)%size. % may not synthesize optimally (check your synthesizer), so a if-statement is a functional alternative if(k==SIZE-1) k = 0; else k=k+1;
Suggestions:
It is generally recommenced to keep parameters as uppercase, this way you can easily identity parameters form signal names. Putting a blocking assignment inside a sequential block is legal, but most design rules recommend separating combinational logic from sequential assignments. I would prefer writing your code like the following:
// $clog is IEEE1364-2005 § 17.11, some synthesizers support it, others don't
reg [$clog2(SIZE):0] k=0, next_k;
always #* begin
if (k==SIZE-1) begin
next_k = 0; // wrap around
// next_k = k; // clamp
end
else begin
next_k = k+1;
end
end
always # (posedge clk)
begin
currenta[WIDTH-1:0] <= A[WIDTH*k +: WIDTH];
currentb[WIDTH-1:0] <= A[WIDTH*next_k +: WIDTH];
partials[WIDTH*next_k +: WIDTH] <= temp1wire;
k <= next_k;
end

How to constrain a counter reg size in verilog for ise synthesis?

I want to declare a counter reg in function of some parameters. I did it in this way :
parameter clk_freq = 95000; // clock frequency in kHz
parameter debounce_per_ms = 20;
localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
reg [$ln(MAX_COUNT)/$ln(2):0] count;
This work well in simulation with icarus but ISE 14.7 don't want to synthesize it. That give this error:
WARNING:HDLCompiler:1499 - "/src/button_deb.v" Line 4: Empty module <button_deb> remains a black box.
If I define the count like this :
reg [22:0] count;
ISE synthesize it well. If someone have a clue ?
This worked for me, although I'd swear I used functions like $log, $log10, $ceil and the like in the past with no problems.
module param_with_log2 (
input wire clk,
output wire d
);
function integer log2;
input integer value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction
parameter clk_freq = 95000; // clock frequency in kHz
parameter debounce_per_ms = 20;
localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
localparam integer UPPER = log2(MAX_COUNT);
reg [UPPER:0] count;
always #(posedge clk)
count <= count + 1;
assign d = count[UPPER];
endmodule
XST seems to have a problem with using constant functions: they only can be at the right side of a parameter declaration expression (as I suggested in my first comment). Credits and more information here:
http://www.beyond-circuits.com/wordpress/2008/11/constant-functions/
Notice too that UPPER is declared as localparam integer so we can use it inside a register definition upper bound expression. Credits go to the owner of this post: http://forums.xilinx.com/t5/Synthesis/XST-and-clog2/m-p/244440/highlight/true#M6609
(the module is just a phony module to have something that I can symthesize without the fear that the synthesizer will wipe all my code. It doesn't perform any kind of debouncing)

How to design a 64 x 64 bit array multiplier in Verilog?

I know how to design a 4x4 array multiplier , but if I follow the same logic , the coding becomes tedious.
4 x 4 - 16 partial products
64 x 64 - 4096 partial products.
Along with 8 full adders and 4 half adders, How many full adders and half adders do I need for 64 x 64 bit. How do I reduce the number of Partial products? Is there any simple way to solve this ?
Whenever tediously coding a repetitive pattern you should use a generate statement instead:
module array_multiplier(a, b, y);
parameter width = 8;
input [width-1:0] a, b;
output [width-1:0] y;
wire [width*width-1:0] partials;
genvar i;
assign partials[width-1 : 0] = a[0] ? b : 0;
generate for (i = 1; i < width; i = i+1) begin:gen
assign partials[width*(i+1)-1 : width*i] = (a[i] ? b << i : 0) +
partials[width*i-1 : width*(i-1)];
end endgenerate
assign y = partials[width*width-1 : width*(width-1)];
endmodule
I've verified this module using the following test-bench:
http://svn.clifford.at/handicraft/2013/array_multiplier/array_multiplier_tb.v
EDIT:
As #Debian has asked for a pipelined version - here it is. This time using a for loop in an always-region for the array part.
module array_multiplier_pipeline(clk, a, b, y);
parameter width = 8;
input clk;
input [width-1:0] a, b;
output [width-1:0] y;
reg [width-1:0] a_pipeline [0:width-2];
reg [width-1:0] b_pipeline [0:width-2];
reg [width-1:0] partials [0:width-1];
integer i;
always #(posedge clk) begin
a_pipeline[0] <= a;
b_pipeline[0] <= b;
for (i = 1; i < width-1; i = i+1) begin
a_pipeline[i] <= a_pipeline[i-1];
b_pipeline[i] <= b_pipeline[i-1];
end
partials[0] <= a[0] ? b : 0;
for (i = 1; i < width; i = i+1)
partials[i] <= (a_pipeline[i-1][i] ? b_pipeline[i-1] << i : 0) +
partials[i-1];
end
assign y = partials[width-1];
endmodule
Note that with many synthesis tools it's also possible to just add (width) register stages after the non-pipelined adder and let the tools register balancing pass do the pipelining.
[how to] reduce the number of partial products?
A method somewhat common used to be modified Booth encoding:
At the cost of more complicated addend selection, it at least almost halves their number.
In its simplest form, considering groups of three adjacent bits (overlapping by one) from one of the operands, say, b, and selecting 0, a, 2a, -2a or -a as an addend.
The code below generates only half of expected the output.
module arr_multi(a, b, y);
parameter w = 8;
input [w-1:0] a, b; // w-width
output [(2*w)-1:0] y; // p-partials
wire [(2*w*w)-1:0] p; //assign width as input bits multiplied by
output bits
genvar i;
assign p[(2*w)-1 : 0] = a[0] ? b : 0; //first output size bits
generate
for (i = 1; i < w; i = i+1)
begin
assign p[(w*(4+(2*(i-1))))-1 : (w*2)*i] = (a[i]?b<<i :0) + p[(w*(4+(2*
(i-2))))-1 :(w*2)*(i-1)];
end
endgenerate
assign y=p[(2*w*w)-1:(2*w)*(w-1)]; //taking last output size bits
endmodule

Verilog Signed Multiplication "loses" the Signed Bit

I am writing a code which uses a multiplier module which returns weird answers when one of the inputs is a negative number. I am guessing this has to do with how Verilog treats signed numbers and the module is not storing the result properly in the 'reg signed out' decleration. All my input/output/wire/reg declarations are signed, so I am not sure what I am missing and what else I need to do to tell Verilog to take care of this. Sorry for the beginner question!
For example,
When X[0] is 1610 and Theta1[1] is -123, the result I am getting from the multiplier module is:
6914897148530
Here are the relevant parts of my code:
module mult(in1, in2, out, mult_start); // multiplication module
input signed [32-1:0] in1, in2;
input mult_start;
output signed [64-1:0] out;
reg signed [64-1:0] out;
always #(in1 or in2 or mult_start)
begin
if (mult_start)
begin
out <= (in1 * in2) & {64{1'b1}};
end
else
out <= out;
end
endmodule
module child_one (clk, rst_b, sig_start, Input_X, Input_Theta1)
// Internal Variables Memory
reg signed [`REG_LENGTH-1:0] Theta1 [0:217-1];
reg signed [`REG_LENGTH-1:0] X [0:216-1];
wire signed [`OUT_LENGTH-1:0] prod_1 [0:217-1];
reg signed [`OUT_LENGTH-1:0] prod_sum;
wire signed [`OUT_LENGTH-1:0] sig_result;
mult mult_001 (X[0], Theta1[1], prod_1[1], mult_start);
mult mult_002 (X[1], Theta1[2], prod_1[2], mult_start);
mult mult_003 (X[2], Theta1[3], prod_1[3], mult_start);
mult mult_004 (X[3], Theta1[4], prod_1[4], mult_start);
always #(posedge clk or negedge rst_b)
begin
if (sig_start == 1)
begin
if (state == 4'b0000)
begin
state <= 4'b0001; // initialize state variable to zero
k <= 0;
result_done <= 0;
index <= 0;
end
else if (state == 4'b0001) // Start Multiplication Operation
begin
k <= result_done ? 0 : k + 1;
result_done <= result_done ? 1 : (k == 10);
state <= result_done ? 4'b0010 : 4'b0001;
mult_start <= result_done ? 1'b1 : 1'b0;
//mult_start <= 1'b1;
//state <= 4'b0010;
end
else if (state == 4'b0010) // Stop Multiplication Operation
begin
k <= 0;
result_done <= 0;
mult_start <= 0;
state <= 4'b0011;
end
end
end
endmodule
Thanks,
Faisal.
Thanks for all the help and suggestions. Writing a separate testbench for the mult module helped arrive at a solution.
My issue was in the mult module. Since my inputs are 32 bits long, the mult output would be 32*2+1 = 65 bits long. My output port 'out' was only assigned to be 64 bits long which resulted in a sign issue when the answer was a negative number. Assigning it to be 65 bits long took care of my problem.
The issue is the & {64{1'b1}} part in the mult module. {64{1'b1}} is an unsigned subexpression. This causes in1 and in2 and to be treated as unsigned regardless of their declaration, and causes unsigned multiplication to be performed. The resulting bits assigned to out are then interpreted as signed again because of its declaration, but by then it's too late.
As you alluded to, the general Verilog signedness rule is that if any operand in a simple expression is unsigned, all operands in the expression are interpreted as unsigned, and thus the operators perform unsigned math. (There are many other nuances to the rules (e.g. relational operators), but they aren't applicable here.)
Note that you can't make {64{1'b1}} signed by changing it to {64{1'sb1}} because the result of the replication operator is always unsigned regardless of its operand. But you could wrap it in the $signed() system function, making the rest of the expression (the * and & steps) fully signed. Thus this would work correctly:
out <= (in1 * in2) & $signed({64{1'b1}});
But you really don't need to mask the result with that &. Regardless of the width of the inputs and the result of the multiplication, Verilog rules state that the final value of the RHS of the assignment will simply be truncated (discarding some MSBs) to the width of the LHS, if the RHS were wider. Thus masking with 64 ones is completely redundant.
To address the currently-accepted answer... It is not true that 65 bits are needed for 32x32 signed->signed multiplication. Only 64 bits are needed to handle even the most-extreme cases:
minimum result: -(2^31) * ((2^31) - 1) = -4611686016279904256 > -(2^63)
maximum result: ((2^31) - 1) * ((2^31) - 1) = 4611686014132420609 < (2^63) - 1
In general, for fully-signed multiplication of N bits by M bits, you only need N+M bits for the product (and N+M-1 would suffice if not for the single most-negative times most-negative case). This is also true for fully-unsigned multiplication. But if you were mixing signed and unsigned multiplicands/product (and using $signed() as needed to get Verilog to behave as desired), you would need an extra result bit in some cases (e.g. unsigned*unsigned->signed).

Resources