4bit multiplier in verilog without multiplication operator - verilog

I'm trying to write a Verilog module that multiplies two 4bit inputs, without using * operator, but I get some errors:
module multiplier(
output[7:0] prod,
input[3:0] a,
input[3:0] b);
reg [7:0] result=8'h00;
always #(*)
begin
for(i=0;i<4;i=i+1)
begin
if((b&(1<<<i))!=0)
begin
result = result+(a<<<i);
end
end
end
assign prod = result;
endmodule
Errors:
[Synth 8-2715] syntax error near =
[Synth 8-2715] syntax error near =
[Synth 8-993] result is an unknown type
[Common 17-69] Command failed: Vivado Synthesis failed
What am I doing wrong?
EDIT:
I modified the code, now i get:
[Synth 8-1031] i is not declared

reg [7:0] result=16'h00;
Should be
reg [7:0] result=8'h00;

module multiplier(
output[7:0] prod,
input[3:0] a,
input[3:0] b);
reg [7:0] result;
reg[2:0] i;
always #(*)
begin
result=0;
for(i=0;i<4;i=i+1)
begin
if(b[i]==1'b1)
begin
result = result+(a<<i);
end
end
end
assign prod = result;
endmodule
For your code, if I had a = 15 and b = 15, the result would have been 72. You must assign a value for result in always block result=0;

Related

How to generate random patterns using LFSR and i am using different partial seed value

As I said, seedValue wire is holding a 10 bit partial seed which I want to assign to a register when the rst signal is 1 it enters the block and the last statement of this block assigns the seedValue wire to the register temp so that when the if condition if((temp!=10'b0000000000) || (temp!=10'bxxxxxxxxxx)) is executed it enters the block and then the seedValue is concatenated with 12'b000000000000 and then I get my 32-bit seed value through which I am expecting to have random patterns from the LFSR after that the register temp is assigned zero values so that the else block must execute from which I am expection to get random patterns, but the following code is not working. I am new to Verilog and FPGA world, somebody please help me. The following code is written in Verilog.
module TestPatternGenerator(input wire clk, input wire rst, input wire enable,
input wire sel, input wire[9:0] seedValue, output reg[127:0] valueO);
integer i;
reg [31:0] patternGenerate[0:3],tempOne;
reg [9:0] temp;
always #(posedge clk)begin
if((sel == 1)&&(enable==1))begin
if(rst)begin
valueO = 128'b0;
patternGenerate[0]<=32'b0;
patternGenerate[1]<=32'b0;
patternGenerate[2]<=32'b0;
patternGenerate[3]<=32'b0;
tempOne <= 32'b11111111111111111111111111111111;
temp <= seedValue;
end
else if((temp!=10'b0000000000) || (temp!=10'bxxxxxxxxxx))begin
tempOne <= {12'b000000000000,seedValue};
$display("%h",tempOne);
temp <= 10'b0000000000;
end
else begin
for(i=0;i<4;i=i+1)begin
tempOne = {(tempOne[31] ^ tempOne[25] ^ tempOne[22] ^ tempOne[21] ^ tempOne[15] ^ tempOne[11] ^ tempOne[10] ^ tempOne[9] ^ tempOne[7] ^ tempOne[6] ^ tempOne[4] ^ tempOne[3] ^ tempOne[1] ^ tempOne[0]), tempOne[31:1]};
patternGenerate[i] = tempOne;
end
valueO = {patternGenerate[3],patternGenerate[2],patternGenerate[1],patternGenerate[0]};
end
end
i=i+1;
end
endmodule
code for testbench is given below
`timescale 10ns/1ns
module test_controller();
integer j;
reg [127:0] key_byte,valueI,oraI;
wire [127:0] state_byte;
wire [9:0] seedValue;
wire [47:0] result;
reg [7:0] iterate;
reg clk,rst,bistForDeternimistic,deterministicEnable,ecryptionEnable,enable,decryptionEnable,decryptionSecondEnable,bistMode,bistForEncryption,bistForDecryption,oraEnable;
wire [127:0] state_out_dec,state_out_enc,state_second_dec;
wire [31:0] state_out_ora;
reg [31:0] signatureToMatch;
wire load,ready;
TestPatternGenerator tpg (clk,rst,enable,bistMode,seedValue,state_byte);
always #3 clk = ~clk;
initial begin
bistMode <= 1;
key_byte <= 128'h5468617473206D79204B756E67204675;
bistForDecryption <= 0;
clk<=0;
rst<=1;
#5 rst<=0;
iterate<=0;
j<=0;
bistForDeternimistic<=1;
enable<=1;
end
always#(negedge clk)begin : deterministic_block
if(j==100)begin
disable deterministic_block;
end
if((bistMode==1) && (bistForDeternimistic==1))begin
#(state_byte)begin
$display("%h %d",state_byte,$time);
end
end
j=j+1;
end
endmodule
output i am getting only the first test pattern but it should generate 100 test patterns. So except the first test pattern, i am not getting the rest 99 patterns.
When I run your code, I don't see any patterns (the $display statements are not executed). This is because the enable signal is unknown when rst is 1.
If I delay the rst rising edge to occur after enable is set to 1, I see 100 patterns:
initial begin
bistMode <= 1;
key_byte <= 128'h5468617473206D79204B756E67204675;
bistForDecryption <= 0;
clk<=0;
rst<=1;
iterate<=0;
j<=0;
bistForDeternimistic<=1;
enable<=1;
#5 rst<=0;
end
This is a partial output:
00000000000000000000000000000000 3
afffffff5fffffffbfffffff7fffffff 9
2affffff55ffffffabffffff57ffffff 15
72afffffe55fffffcabfffff957fffff 21
272affff4e55ffff9cabffff3957ffff 27
4272afff84e55fff09cabfff13957fff 33
You mention the seedValue signal in your question, but it is undriven (the value z). You declared the signal as a wire, and wires default to z when they are not assigned.
To drive it with a know value for the full duration of the simulation, you could use, for example:
wire [9:0] seedValue = 1;
If you want to drive it like your other inputs, you should declare is as a reg.

ALU in Verilog: "Unable to bind wire/reg/memory"

I am trying to make a simple 32 bit ALU with an overflow flag, and then output the inputs and results of the ALU to the screen, but I encountered some problems with connecting the elements for the test bench. I got this error:
test_32bALU.v:15: error: Wrong number of ports. Expecting 4, got 5.
test_32bALU.v:33: error: Unable to bind wire/reg/memory
test_unit.overflow' inalu_test'
2 error(s) during elaboration.
I am just starting with Verilog and I have a basic idea of the syntax. I know I am not supposed to ask debugging questions, but this is my only hope. My professor or TA wouldn't respond to me requests for help. I would appreciate it if anyone here could help me point out my mistakes.
This is my 32bALU.v file:
module alu(
input signed[31:0] a,b,
input[3:0] opcode;
output signed[31:0] c;
output overflow;
);
reg signed[31:0] result;
assign c = result;
reg tmp;
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
always #(a,b,opcode)
begin
case(opcode)
add:
begin
c = a + b;
end
endcase
end
always #(c)
begin
if (c[32:31] == (2'b11 | 2'b10)) // Overflow
begin
tmp = 1'b1;
assign overflow = tmp;
end
else begin
tmp = 1'b0;
assign overflow = tmp;
end
end
assign result = c[31:0];
endmodule
test_32bALU.v
`timescale 1ns/1ps
module alu_test;
// Inputs
reg[31:0] a,b;
reg[2:0] opcode;
// Outputs
wire[31:0] c;
//wire [1:0] zero;
wire [1:0] overflow;
//wire [1:0] neg;
alu test_unit(
a,b, // Inputs
opcode,
c,
overflow
);
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
initial begin
$display("op: a : b : c : reg_A : reg_B : reg_C");
$monitor(" %h:%h:%h:%h:%h:%h:%h",
opcode, a, b, c, test_unit.a, test_unit.b, test_unit.c);
$monitor("%h", test_unit.overflow);
//// add
#10 a=32'b0000_0000_0000_0000_0000_0000_0000_0001;
#10 b=32'b0000_0000_0000_0000_0000_0000_0000_0001;
opcode= add;//3'b000
#10 $finish;
end
endmodule
I am confused as to why it says "wrong number of ports"? I assume it's the number of parameters in module alu and alu test_unit? They have the same number of parameters (a, b, c, opcode and overflow), so what exactly am I missing? How exactly do I get the value of overflow? It works fine before I added the overflow parameter, so I assume I'm doing it wrong?
For the second error, I read somewhere on here that it might be due to a missing declaration, but I have declared all of them... so I am not sure what's making it wrong.
I am not sure if this is the issue, but your module definition is not correct. It should be as follows:
module alu(
input signed[31:0] a,b,
input[3:0] opcode,
output signed[31:0] c,
output overflow
);
Perhaps this may help with your issue.
Commas separate inputs and outputs in the module declaration.
NEVER rely on the order of arguments to modules and ALWAYS try to use, for a module called A;
module A(output wire c,
input wire a,
input wire b);
...
endmodule // A
use an instance of it using;
A yourAname(.c(Bar),
.a(Foo1),
.b(Foo2));
so that if the definition and order of the I/O of the module changes, this instantiation will track those changes and/or give appropriate errors when simulated/synethesised.
You might find it useful to follow a few simple rules in your source code when naming;
inputs are denoted by i_yourinputname
outputs are denoted by o_youroutputname
inout are denoted by io_yourinputoutputname
wire are denoted by w_yourwirename
reg are denoted by r_yourregname
as this avoid confusion and is a good habit to get into as soon as possible when starting to learn verilog.

Absolute value module in Verilog returning only unknown values

I am trying to implement a simple 16-bit absolute value module; however, I am only getting unknown values as output.
Below is the code that I've written:
module refabs(b, a);
input wire [15:0] a;
output reg signed [15:0] b;
always #* begin
b = ((a < 0) ? -a : a);
end
endmodule
module testbench;
reg [15:0] a;
wire [15:0] b;
refabs abs(b, a);
initial begin
a = -30000;
begin
$display("refabs(%x) = %x", a, b);
end
end
endmodule
The output I get is:
refabs(8ad0) = xxxx
In your example, the initial block executes with 0 delay without giving the always #* a chance to execute.
Either change your $display to $strobe, or add a delay before the $display statement.

Error (10734): Verilog HDL error at SWSelector.v(13): selector is not a constant

Referring to my previous post:
Error (10482): VHDL error: object "select_vector" is used but not declared
I converted my code from VHDL to verilog, but I'm getting this error now:
(Error (10734): Verilog HDL error at SWSelector.v(13): selector is not
a constant),
Any suggestions how do I deal with it? There are 8 possibilities for selector switch which are coming from a decoder. So whenever the value of selector matches 3'b000, I want rq to be assigned to requests. Here is my code:
module SWSelector(
input [7:0] rq,
input [2:0] selector,
output [7:0] request
);
localparam NUM=3'b000;
generate
genvar i;
for(i=0;i<7;i=i+1)
begin: label
if(selector == NUM)
begin
assign request[i] = rq[i];
end
else
begin
assign request[i]=0;
end
end
endgenerate
endmodule
Since your if-statement is in a generate, you're asking the tool to pre-evaluate what selector is set to in order to figure out selecter == NUM evaluates to, but your tool doesn't know because it's a signal, not a parameter.
You want to use the generate to create an always block that you can check the value of selector in, like so:
module SWSelector(
input [7:0] rq,
input [2:0] selector,
output reg [7:0] request
);
localparam NUM=3'b000;
generate
genvar i;
for(i=0;i<7;i=i+1)
begin: label
always #* begin
if(selector == NUM)
request[i] = rq[i];
else
request[i]=0;
end
end
endgenerate
endmodule
Or, as toolic said, you can use a ternary and an assign.
Edit:
Without generate:
module SWSelector(
input [7:0] rq,
input [2:0] selector,
output reg [7:0] request
);
localparam NUM=3'b000;
integer i;
always #* begin
for(i=0;i<7;i=i+1)
if(selector == NUM)
request[i] = rq[i];
else
request[i]=0;
end
endmodule

Two's complement in verilog

I've been trying to build a module which returns the two's complement representation of the (3-bit) input (first bit being the sign). I think that the following code is correct conceptually, but I am probably missing something about it's structure: when I try to compile, I get the following errors:
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
Searching for that error showed it is usually seen when using a variable as input and output at the same time, but that's not my case. Could you point where the error is?
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
always #(a_i[2:0] or f_o[2:0])
begin
if (a_i[2] == 1)
begin
f_o[2] = a_i[2];
f_o[1:0] = (~a_i[1:0] + 'b1);
end
else
begin
f_o = a_i;
end
end
endmodule
In Verilog, undeclared identifiers are considered implicit wire declarations in most circumstances. Since f_o has not been declared the compiler considers it a wire, not a variable. This causes the compiler to complain about all the assignments.
// What was typed
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
// What the compiler implicitly declares
wire [2:0] a_i;
wire [2:0] f_o;
To fix it you can declare the variable or declare both the port and the variable.
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
reg [2:0] f_o;
module ca2 (a_i,f_o);
input [2:0] a_i;
output reg [2:0] f_o;
f_o needs to be declared as a reg. output reg [2:0] f_o.
Also I am not sure what you are calculating, that is not a standard twos complement.
module ca2 (
input [2:0] a_i,
output [2:0] twos_comp,
output [2:0] also_twos_comp
);
assign twos_comp = ~a_i + 1'b1;
assign also_twos_comp = -a_i ;
endmodule
You may be dealing with an encoded input, but twos_complement is to negate the number I would expect the sign bit (MSB) to change. Although we refer to it as a sign bit it also contains information about the value and therefore can not just be stripped off and leave the number unchanged.
The first solution -> In sequential circuits, the output must be in the form of a reg.
and Next we need to know that in two's complement we start from bit zero to get to the end so the condition is incorrect.
If the zero bit is one, then the zero bit is unchanged and the rest of the bits change to not.
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always #(a_i[2:0] or f_o[2:0]) begin
if (a_i[0] == 1'b1) begin
f_o[0] = a_i[0];
f_o[2:1] = (~a_i[2:1]);
end
else
if(a_i[1]==1'b1) begin
f_o[1:0] = a_i[1:0];
f_o[2] = (~a_i[2]);
end
else
if(a_i[2] == 1'b1) begin
f_o = a_i ;
end
end
endmodule
The second solution -> In binary numbers, if we subtract the number from zero, we get two's complement .
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always #(a_i[2:0] or f_o[2:0]) begin
f_o = 3'b000 - a_i ;
end
endmodule
The third solution -> all bits change to not and Finally, they are added to the number one (3'b000 = 3'b0)
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
reg [2:0] finish ;
always #(a_i[2:0] or f_o[2:0]) begin
finish = (~a_i);
f_o = finish + 3'b001 ;
end
endmodule

Resources