Applying Modulo To a Negative Number In Verilog - verilog

In general math and software programming, -4 mod 5 = 1. But in Verilog, the answer turns out to be 2. The reason for this seems to be because of division happening in binary. How do I properly handle this calculation? Following is a Verilog code that reproduces this behaviour.
module test (a,b,c);
input [0:3]a,b;
output [0:3]c;
assign a = -4'd4;
assign b = 4'd5;
assign c = a%b;
endmodule

Your code does % operation on unsigned data. In this scheme -4 is just the same as 12 unsigned and the result of modulo is 2.
You need to use signed data as in here:
module test (
input signed [0:3]a,b, // <<<< signed
output signed [0:3]c // <<<< signed
):
assign a = -4'd4;
assign b = 4'd5;
assign c = a%b;
always #*
$display(a,b,c);
endmodule
And the result is -4, as expected from general programming rules.

You didn’t declare the variables as signed, so they are treated as unsigned. -4’d4 is being interpreted as it’s 2’s complement 4’b12 (~4’b0100 + 1’b1 == 4’b1100)
You need to add the signed keyword to the signal definition.
module test;
wire signed [3:0] a,b,c;
assign a = -4'd4;
assign b = 4'd5;
assign c = a%b;
endmodule

Related

Signed Number Multiplication using Karatsuba Algorithm in Verilog

Tried implementing Karatsuba multiplier for multiplying two binary numbers, the logic below works well for unsigned numbers, but getting incorrect answer when I change one of the inputs to a negative. In the example below a=1010011111000000(equals -88.25) and b= 0001010001000000(equals 20.25). The answer should be 11111001000001001111000000000000(equals:-1787.0625)but I end up getting the incorect answer. Have used fixed point logic, with inputs 16 bits and fraction point 8 bits, output being 32 bits with fraction bits 16.
module karatsuba( input signed [15:0] a,
input signed [15:0] b,
output signed [31:0] out
);
reg [15:0] ac,bd;
reg [31:0] t1;
reg [31:0]t2;
reg [24:0] psum;
initial begin
assign ac = a[15:8]*b[15:8];
assign bd = a[7:0]*b[7:0];
assign t2= bd;
assign t1={ac,16'b0000000000000000};
assign psum = {(a[15:8]+a[7:0])*(b[15:8]+b[7:0])-ac-bd,8'b00000000};
end
assign out= t1+psum+t2;
endmodule
module karatsuba_tb();
reg signed [15:0]a,b;
wire signed [31:0]out;
karatsuba uut(.a(a),.b(b),.out(out));
initial begin
a=16'b0101100001000000;
b=16'b0001010001000000;
end
endmodule
enter image description here
enter image description here
There are two issues pertaining to the signed multiply in the post:
Slices of vector variables (even slices of signed vectors) are treated as unsigned in Verilog. This is because when a slice is taken there is no way to identify the original sign bit, therefore it must be treated as unsigned
The solution is to cast the slices to signed so that Verilog treats them as signed. Like this:
assign ac = signed'(a[3:2]) * signed'(b[3:2]);
Make the line that defines the variable ac,bd to be treated as signed using the signed keyword (default is unsigned).
You will need to propagate these changes to other places in the posted code which have the same issues.
Here is a simplified version of the post using small numbers to illustrate the cast and keyword use:
module karatsuba(
input signed [3:0] a,
input signed [3:0] b
);
reg signed [3:0] ac;
assign ac = signed'(a[3:2]) * signed'(b[3:2]);
endmodule
module karatsuba_tb();
reg signed [3:0]a,b;
karatsuba uut(.a(a),.b(b));
initial begin
a = 4'b1110;
b = 4'b1111;
#1;
//
$display("---------------");
$display("uut.a[3:2] = %b",uut.a[3:2]);
$display("uut.b[3:2] = %b",uut.b[3:2]);
$display("uut.ac = %b",uut.ac);
$display("---------------");
//
$display("uut.a[3:2] = %d",signed'(uut.a[3:2]));
$display("uut.b[3:2] = %d",signed'(uut.b[3:2]));
$display("uut.ac = %d",uut.ac);
$display("---------------");
end
endmodule
The example displays this message at runtime:
---------------
uut.a[3:2] = 11
uut.b[3:2] = 11
uut.ac = 0001
---------------
uut.a[3:2] = -1
uut.b[3:2] = -1
uut.ac = 1
---------------

Can I reduce the number of bits after Arithmetic Right Shift?

If I reduce the number of bits after arithmetic right shift in verilog, do I still get the correct signed number? Is this valid?
number of bits reduced = shift value
A = 1110_1110
A>>>1
new A = 111_0111
Yes, but you should use three '>' not four and of course the new variable should be big enough:
wire signed [7:0] A,B;
wire signed [6:0] just_fits;
wire signed [5:0] oops;
assign B = A >>> 1; // Signed divide by two
assign just_fits = A >>> 1; // Signed divide by two
assign oops = A >>> 1; // Goes wrong

how to implement verilog divisible by 6?

I wanna create divisible by 6 module in verilog using divisible by 2 module and divisible by 3 module, I grasped the idea, but maybe my verilog grammar is wrong.
the module structure i want to implement is below,
module Divisible_6(input [3:0] a, output out);
using
module Divisible_2(
input [3:0] a,
output out
);
module Divisible_3(
input [3:0] a,
output out
);
and if input is 6(0110), then both divisible_2 and divisible_3 output 1,
and both 1 goes in to the AND gate, then came out with 1.
1 = true, 0 = false.
how can I implement the idea in verilog language?
and help is appreciated, thanks.
input: 1~15
Since I understand question a little bit different than #Morgan, I'd rather try this code:
module Divisible_6(
input [3:0] a,
output out
);
wire out_1, out_2;
assign out = out_1 & out_2;
Divisible_2(
.a (a),
.out(out_1)
);
Divisible_3(
.a (a),
.out(out_2)
);
endmodule
I assume that both Divisible_2 and Divisible_3 take 4-bit input and return boolean value (divisible (1) or not (0)).
You need divisible by 6 design, which can only be obtained, if your input is both divisible by 2 and divisible by 3.
Hence you can use both modules, like the following code.
// Defining the nets
logic out1, out2;
// Continuous Assignment
assign out = out1 & out2;
// Instantiation of 2 modules with instance name d1 & d2
divisible_2 d1 (a, out1);
divisible_3 d2 (a, out2);

How do I fix "Error-[IBLHS-NT] Illegal behavioral left hand side"?

I am trying to debug this code shown below. I can not get it to work at all. The attached Verilog file has two modues: 1) "equality" which defines the Device Under Test (DUT) and 2) "test" which generates the inputs to test the DUT. The module "equality" has a coding error. Let me know if you can give me a hint. Thanks!
The errors I am receiving are:
Error-[IBLHS-NT] Illegal behavioral left hand side
ECE413/src/Equality_bugs_Test_Bench.v, 7
Net type cannot be used on the left side of this assignment.
The offending expression is : Equal
Source info: Equal = 1;
Error-[IBLHS-NT] Illegal behavioral left hand side
ECE413/src/Equality_bugs_Test_Bench.v, 9
Net type cannot be used on the left side of this assignment.
The offending expression is : Equal
Source info: Equal = 0;
My SystemVerilog Code is:
module equality (Equal, a, b); // This module defines the DUT.
input[3:0] a, b;
output Equal;
always # (a or b)
begin
if (a == b)
Equal = 1;
else
Equal = 0;
end
endmodule
//
//
//
module test; // This is the test bench. It specifies input signals to drive the DUT.
reg [3:0] a, b;
wire Equal;
equality Eq1 (Equal, a, b); // This line instantiates the DUT.
initial
begin
a = 4'b0000; // Initialize "a" to 0.
b = 4'b0000; // Initialize "b" to 0.
#512 $finish; // Simulate for 32x16 = 512 time steps to exercise the entire truth table.
// (32 steps/cycle x 16 cycles)
end
// The next four lines clock the bits of input "b" so as to count up from 0 to 15.
always #2 b[0] = ~b[0]; // (Note: all procedural blocks run concurrently.)
always #4 b[1] = ~b[1];
always #8 b[2] = ~b[2];
always #16 b[3] = ~b[3]; // One complete cycle is 2x16 = 32 time steps.
always #32 a = a+1; // "a" is incremented by one after each complete count of "b".
endmodule
Procedural assignments (inside always blocks) must be made to signals declared as reg. Change:
output Equal;
to:
output reg Equal;
For a shorter, equivalent version:
module equality (
output Equal,
input [3:0] a, b
);
assign Equal = (a == b);
endmodule

How does Verilog behave with negative numbers?

For instance, say I have a reg [7:0] myReg
I assign it the value -8'D69
I know Verilog stores it as 2's complement so it should be stored as
10111011
The question I have now is if I were to perform an operation on it, say myReg/2
Would it evaluate to -34? Or would it take 10111011 and turn it into 187 then perform the division, returning 93?
You need to remember that -8d69 is just a bit pattern. reg is a type which holds bit patterns. It is the type of variable that instructs / to perform signed or unsigned arithmetic.
If this is for synthesis bare in mind that you want to try and avoid dividers, you really want to try and avoid signed dividers. It will likely synthesis smaller with >>> 1
reg [7:0] a;
reg signed [7:0] b;
reg [7:0] c;
reg signed [7:0] d;
initial begin
a = -8'd69 ;
b = -8'd69 ;
c = -8'd69 ;
d = -8'd69 ;
#10ns;
a = a/2 ;
b = b/2 ;
#10ns;
$display("a : %8b, %d", a, a);
$display("b : %8b, %d", b, b);
$display("c >>>1 : %8b, %d", c>>>1, c>>>1);
$display("d >>>1 : %8b, %d", d>>>1, d>>>1);
end
Gives:
a : 01011101, 93
b : 11011110, -34
c >>>1 : 01011101, 93
d >>>1 : 11011101, -35
>> x Shifts right by x places, >>> x Shifts right x places but sign extends for signed types.
NB: the /2 is also rounding up in my examples, >>> will round down/truncate.
For instance, say I have a reg [7:0] myReg I assign it the value
-8'D69
This actually isn't a signed number but instead an expression consisting of a unary negation applied to a positive constant. If the expression was -8'd130 the result would overflow. Signed constants are declared as 8'sd69 or just 69.
The question I have now is if I were to perform an operation on it,
say myReg/2
myReg is unsigned so the expression result will also be unsigned*. If you need the result to be signed than all operands must be signed. There are a couple ways to achieve this:
//Declare the reg as signed and divide by a signed value
reg signed [7:0] myReg;
assign result = myReg/2;
//Use system functions
assign result = $signed(myReg)/2;
*The complete rules regarding expression evaluation are much more complex but basically the result of any expression is unsigned, unless all operands are signed.
reg signed [7:0] a;
reg [7:0] b;
initial
begin
result = a; //Signed
result = a * a; //Signed
result = a * 10; //Signed
result = $unsigned(a); //Unsigned
result = a[0]; //Unsigned
result = a[7:0]; //Unsigned
result = {a,a}; //Unsigned
result = 10{a}; //Unsigned
result = a + b; //Unsigned
result = a * b; //Unsigned
end
I'll add that
1. Data types bit and reg are unsigned, by default.
2. Data types int, integer, longint, shortint, and byte are signed, by default.
3. All these data types can take a signed or unsigned qualifier to change the default.
So, assigning -8'D69 to myReg does an implicit conversion to 187. Then, myReg/2 = 187/2 = 93, unsigned. It's important to understand when and how SystemVerilog does implicit type conversions in expressions and assignments.
The best place to check is the Language Reference Manual. Predictably, given Verilog's "eh" attitude to proper typing, it's a bit of a mess.
Basically signed doesn't affect the actual data stored in the variable/net, but it does affect what the arithmetic operators do in some case. The obvious case is comparison, but also multiplication and division would behave differently. Addition and subtraction should be the same for both signed and unsigned.
Note especially that when one or more of the operands is unsigned it is treated as an unsigned comparison, which is different to what you would expect from C. So if we have
byte a = -10; // byte is signed
logic [7:0] b = 10; // this is unsigned
Then a > b is true.
Again if at least one operator is unsigned then it treats them both as unsigned so if we have:
byte a = -1;
logic [7:0] b = 255;
Then a == b is true.

Resources