Multiplication Issues in Verilog - verilog

I'm trying to take two 7-bit numbers and multiply them with Verilog. However, I seem to be running into trouble. The multiplication seems to work (producing an output of 1) when the results are between 0-9 decimal. However it appears that any result larger than 9 does not seem to produce an output of 1. Even though "Operand1" and "Operand2" are technically only 4-bits (0-9 decimal), I've tried switching them to 7-bit numbers to determine if that would solve the issues I'm encountering.
This particular module checks the answer provided by a user in binary through physical switches and returns a 0 if said answer is incorrect and a 1 if correct. All other operations (Addition, Subtraction and Division) work perfectly.
Here is my code:
module checkAnswer(OpSel, negFlag, Operand1, Operand2, usrAnswer, Correct);
input [1:0]OpSel;
input [6:0]Operand1, Operand2;
input negFlag;
input [6:0]usrAnswer;
output reg Correct;
always # (*)
case (OpSel)
2'b00:
if ((Operand1%10 + Operand2%10) == usrAnswer)
Correct = 1'b1;
else
Correct = 1'b0;
2'b01:
if ((negFlag && (Operand2 > Operand1) && ((Operand1%10 - Operand2%10) == -1*usrAnswer)) || ((Operand1 >= Operand2) && ((Operand1%10 - Operand2%10) == usrAnswer)))
Correct = 1'b1;
else
Correct = 1'b0;
2'b10:
if ((Operand1%10 * Operand2%10) == usrAnswer)
Correct = 1'b1;
else
Correct = 1'b0;
2'b11:
if ((Operand1%10 / Operand2%10) == (usrAnswer))
Correct = 1'b1;
else
Correct = 1'b0;
default: Correct = 1'b0;
endcase
endmodule

The problem is caused by operator precedence. Since % and * have the same precedence, your code executes as if parentheses were used like this:
((Operand1%10) * Operand2)%10
If you use 12 and 7, you get 4 instead of 14. To fix it, add more parentheses:
if (((Operand1%10) * (Operand2%10)) == usrAnswer)
Refer to IEEE 1800-2012, 11.3.2 Operator precedence

Related

Bits Not Shifting

I want to be able to create a shift from right to left everytime I press a button, but my simulation says my bits is not shifting.
this is the code I wrote:
module Sipo(KEY0, qIN, qOUT, LEDsipo);
input KEY0;
output reg [5:0] qIN;
output reg [5:0] qOUT;
output [6:0] LEDsipo;
assign LEDsipo[0] = qIN[0];
assign LEDsipo[1] = qIN[1];
assign LEDsipo[2] = qIN[2];
assign LEDsipo[3] = qIN[3];
assign LEDsipo[4] = qIN[4];
assign LEDsipo[5] = qIN[5];
assign LEDsipo[6] = KEY0;
always #(KEY0) begin
if (KEY0 == 1)
qIN = 6'b000000;
qOUT[0] <= KEY0;
qOUT[1] <= qOUT[0];
qOUT[2] <= qOUT[1];
qOUT[3] <= qOUT[2];
qOUT[4] <= qOUT[3];
qOUT[5] <= qOUT[4];
if (qOUT == 7'b111111)
qOUT[0] = 0;
qOUT[1] = 0;
qOUT[2] = 0;
qOUT[3] = 0;
qOUT[4] = 0;
qOUT[5] = 0;
qIN = qOUT;
end
endmodule
The result I got in the simulation is that LEDsipo[0] was responding to KEY0, but the rest of the LEDsipo was not. I don't see why my bits are not shifting.
It is dificult to test your code without a testbench, which you have not provided, but I thik that you rissue is an extra exposure to python.
Verilog does not understand indentation as scope indicators and requires begin/end to indicats scopes. So, my guess is that you have at least several issues:
missing begin/end: if (KEY0 == 1) begin...end
incorrect mix of non-blocing/non-blocking assignments mix
Incorrect coding of your latch
bad use of veriog syntax
so, though it is corret, you can avoid using separate bits:
assign LEDsipo[6:0] = {KEY0, qIN[5:0]};
do not use sensititivity lists in the latch, it will not synthesize correctly in your case. Use always #* instead. Well, and begin/end.
I do not know why you need qIn, but it makes no sense to initialize it to 0 in the first place. Also, it is not a part of the latch and should be moved out of the always block.
always #* begin
if (KEY0 == 1) begin // need begin/end for multiple statements
// qIN <= 6'b000000; -- why do you need it?
qOut[5:0] <= {qOut[4:0], KEY0};
if (qOUT == 7'b111111) // can omit begin/end for a single statement
qOut <= 6'b0;
end
end
assign qIn = qOut;
Since you have not provide any testbench, I did not test the code.

Comparison Not Functioning Like It Should

I am trying to build a module that accepts two 16 bit inputs and depending a compare signal, evaluates a certain expression and sends a true (1) value to choice the output if the expression is evaluated as true.
This is my source code:
module comparator(input [15:0] r15_register, sourceone_register , input [1:0] comp_signal, output reg choice);
always #(*)begin
if (comp_signal == 2'b00) begin
//Check if soureceone is greater than r15.
choice = (sourceone_register > r15_register)? 1:0;
end
else if (comp_signal == 2'b01) begin
//Check is sourceone is less than r15.
choice = (sourceone_register <r15_register)? 1:0;
end
else if (comp_signal == 2'b10) begin
//Check if sourceone is equal to r15.
choice = (sourceone_register == r15_register)? 1:0;
end
else
choice <= 0;
end
endmodule
This is my testbench code:
module comparator_fixture();
reg [15:0] r15_register, sourceone_register;
reg [1:0] comp_signal;
wire choice;
comparator utt(.r15_register(r15_register), .sourceone_register(soureone_register), .comp_signal(comp_signal), .choice(choice));
initial begin
#20;
comp_signal = 2'b00;
//Sourceone is greater than r15.
r15_register = 4;
sourceone_register = 6;
//Sourceone is less than r15.
#10;
comp_signal = 2'b01;
r15_register = 6;
sourceone_register = 4;
//Sourceone is equal to r15.
#10;
comp_signal = 2'b10;
r15_register =7;
sourceone_register =7;
#30;
$stop;
end
endmodule
When a comp_signal is given, it drives the output choice to X (an unknown state), and I haven't been able to figure out why. Can someone please offer some advice?
I put your code into Vivado and get errors:
undeclared symbol soureone_register, assumed default net type wire ...
unexpected EOF
I found your waveform already 'weird' as choice was zero while nothing else had been given a value yet. So whatever you used to produce that waveform, it can't be the code you showed.
After I fixed the errors choice is no longer X.
Found my error, in my fixture there was an error in how I spelled "source" during the instantiation. I have included a waveform of the run after I fixed my spelling error.
Here is the waveform with the correct output of "choice".

Instantiate a module based on a condition in Verilog

I have a 1023 bit vector in Verilog. All I want to do is check if the ith bit is 1 and if it is 1 , I have to add 'i' to another variable .
In C , it would be something like :
int sum=0;
int i=0;
for(i=0;i<1023;i++) {
if(a[i]==1) {
sum=sum+i;
}
Of course , the addition that I am doing is over a Galois Field . So, I have a module called Galois_Field_Adder to do the computation .
So, my question now is how do I conditionally check if a specific bit is 1 and if so call my module to do that specific addition .
NOTE: The 1023 bit vector is declared as an input .
It's hard to answer your question without seeing your module, as we can't gage where you are in your Verilog. You always have to think of how your code translates in gates. If we want to translate your C code into synthesizable logic, we can take the same algorithm, go through each bit one after the other, and add to the sum depending on each bit. You would use something like this:
module gallois (
input wire clk,
input wire rst,
input wire [1022:0] a,
input wire a_valid,
output reg [18:0] sum,
output reg sum_valid
);
reg [9:0] cnt;
reg [1021:0] shift_a;
always #(posedge clk)
if (rst)
begin
sum[18:0] <= {19{1'bx}};
sum_valid <= 1'b0;
cnt[9:0] <= 10'd0;
shift_a[1021:0] <= {1022{1'bx}};
end
else
if (a_valid)
begin
sum[18:0] <= 19'd0;
sum_valid <= 1'b0;
cnt[9:0] <= 10'd1;
shift_a[1021:0] <= a[1022:1];
end
else if (cnt[9:0])
begin
if (cnt[9:0] == 10'd1022)
begin
sum_valid <= 1'b1;
cnt[9:0] <= 10'd0;
end
else
cnt[9:0] <= cnt[9:0] + 10'd1;
if (shift_a[0])
sum[18:0] <= sum[18:0] + cnt[9:0];
shift_a[1021:0] <= {1'bx, shift_a[1021:1]};
end
endmodule
You will get your result after 1023 clock cycles. This code needs to be modified depending on what goes around it, what interface you want etc...
Of importance here is that we use a shift register to test each bit, so that the logic adding your sum only takes shift_a[0], sum and cnt as an input.
Code based on the following would also work in simulation:
if (a[cnt[9:0])
sum[18:0] <= sum[18:0] + cnt[9:0];
but the logic adding to sum would in effect take all 1023 bits of a[] as an input. This would be quite hard to turn into actual lookup tables.
In simulation, you can also implement something very crude such as this:
reg [1022:0]a;
reg [9:0] sum;
integer i;
always #(a)
begin
sum[9:0] = 10'd0;
for (i=0; i < 1023; i=i+1)
if (a[i])
sum[9:0] = sum[9:0] + i;
end
If you were to try to synthesize this, sum would actually turn into a chunk of combinatorial logic, as the 'always' block doesn't rely on a clock. This code is in fact equivalent to this:
always #(a)
case(a):
1023'd0: sum[18:0] = 19'd0;
1023'd1: sum[18:0] = 19'd1;
1023'd2: sum[18:0] = 19'd3;
etc...
Needless to say that a lookup table with 1023 input bits is a VERY big memory...
Then if you want to improve your code, and use your FPGA as an FPGA and not like a CPU, you need to start thinking about parallelism, for instance working in parallel on different ranges of your input a. But this is another thread...

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).

Timing issue in Verilog

I am new to verilog and I am working on verilg code that defines two modules.
The first module calculates the mod of 2 numbers and the second uses the result to do some operation on it.
The result was wrong and has alot of don't care values because the same clk was used in both modules. Any suggestion please for synchronisation.
The mod module
module mod(m,a,b);
input [15:0] a,b;
output [15:0] m;
reg [31:0] mod;
reg [31:0] mul;
integer i;
always #* begin
mul = a*b;
mod = 32'h80008000;
for(i=0;i<16;i=i+1) begin
if(mul > mod) begin
mul = mul - mod;
mod = mod >> 1;
end
else begin
mod = mod >> 1;
end
end
assign m=mul[15:0];
endmodule
Part of the top module:
initial begin
keyp <= 2'b10;
shift <= 1'b0;
end
always #(posedge clk) begin
if(load)
case (keyp)
2'b10: begin
key[127:64] <= {k1,k0};
keyp <= 2'b01;
end
2'b01: begin
key[63:0] <= {k1,k0};
keyp <= 2'b00;
shift <= 1'b1;
end
//default: keyp <=2'b00;
endcase
else if (shift) begin
//shift key for first round
temp[24:0] <= key[127:103];
key[127:25] <= key[102:0];
key [24:0] <= temp [24:0];
shift <= 1'b0;
end
end
assign w1[2*SIZE-1:SIZE] = d1+key[2*SIZE-1:SIZE];
assign w1[3*SIZE-1:2*SIZE] = d2+key[3*SIZE-1:2*SIZE];
mod mod1( w1[SIZE-1:0], d0, key[SIZE-1:0] );
mod mod2( w1[4*SIZE-1:3*SIZE], d3, key[4*SIZE-1:3*SIZE]);
Assigning to the same value multiple times with blocking assignments is perfectly valid Verilog. Even having the same term appear on both sides is fine, provided it's been assigned at least once prior to that.
The code here is incomplete but the problem appears to be that the code is assigning to 'key' in multiple places. Both as the output of the mod instances and inside the clocked block. Anytime these two 'disagree' about the value of key it's going to been seen as an X. X in addition to representing unknown also reflects contention where two different assignments conflict.
Since I'm not sure what this code is meant to do (seems to be some sort of encryption) I can't offer a fix but you need to separate the assignments to key.
x's are referred to as do not cares in casex statements or Karnaugh maps, here they represent unknown values. Unknown values can come from a value not being initialised (reset) or multiple (conflicting) drivers.
The mod module contains this section of code:
always #* begin
mul = a*b;
mod = 32'h80008000;
for(i=0;i<16;i=i+1) begin
if(mul > mod) begin
mul = mul - mod;
mod = mod >> 1;
end
else begin
mod = mod >> 1;
end
end
always #* is a combinatorial block, you assign mul multiple times only the last assignment will have any effect.
The use of a for loop here makes it look like you are trying to reuse variables, as you would in c. Remember that we are describing hardware and that the value is intended to exist somewhere as flip flops or wires between modules and can only hold a single value in any given clock cycle.
In the combinatorial block you have mul = mul - mod; that is mul defining itself this will not work, you need to add a flip flop to break the loop.

Resources