What is the improve way to multiplying by 15? - verilog

I'm trying to implement as follows to multiplying by 15.
module mul15(
output [10:0] result,
input [3:0] a
);
assign result = a*15;
endmodule
But is there any improve way to multiplying to a by 15?
I think there are 2 ways like this
1.result = a<<4 -1;
2.result = {a,3'b1111_1111};
Ans I think the best way is 2.
but I'm not sure also with aspect to synthesis.
update:
What if I am multiplying 0 at {a,3'b1111_1111}? This is 255 not 0.
Does anyone know the best way?
Update
How about this way?
Case1
result = {a,8'b0}+ {a,7'b0}+ {a,6'b0}+ {a,5'b0}+ {a,4'b0}+ {a,7'b0}+ {a,3'b0}+ {a,2'b0}+ {a,1'b0}+ a;
But it looks 8 adder used.
Case2
result = a<<8 -1
I'm not sure what is the best way else.

There is always a*16 - a. Static multiplications of power of 2 are basically free in hardware; it is just hard-coded 0s to the LSB. So you just need one 11-bit full-subtracter, which is a full adder and some inverters.
other forms:
result = a<<4 - a;
result = {a,4'b0} - a; // unsigned full-subtractor
result = {a,4'b0} + ~a + 1'b1; // unsigned full-adder w/ carry in, 2's complement
result = {{3{a[3]}},a,4'b0} + ~{ {7{a[3]}}, a} + 1'b1; // signed full-adder w/ carry in, 2's complement

The cleanest RTL version is as you have stated in the question:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always #* begin
result = a * 4'd15;
end
endmodule
The Multiplicand 15 in binary is 4'b1111; That is 8 + 4 + 2 + 1.
Instead of a multiplier it could be broken down into the sum of these powers of 2. Powers of 2 are just barrel shifts. This is how a shift and add multiplier would work.
module mul15(
input [3:0] a
output reg [7:0] result,
);
always #* begin
// 8 4 2 1 =>15
result = (a<<3) + (a<<2) + (a<<1) + a;
end
endmodule
To minimise the number of adders required a CSD could be used. making 15 out of 16-1:
module mul15(
input [3:0] a
output reg [7:0] result,
);
always #* begin
// 16 - 1 =>15
result = (a<<4) - a;
end
endmodule
With a modern synthesis tool these should all result in same the thing. Therefore having more readable code which gives a clear instruction to the tool as to what you intended gives it the free rein to optimise as required.

Related

In Verilog, counting and outputting the number of 1's in an 8bit input?

What I am trying to do in my mind is take 8 1-bit inputs and count the 1's. Then represent those 1's.
01010111 should output 0101 (There are five 1's from input)
module 8to4 (in,out,hold,clk,reset);
input [7:0] in; //1 bit inputs
reg [7:0] hold; //possible use for case statement
output [3:0] out; //Shows the count of bits
always #(clk)
begin
out = in[0] + in[1] + in[2] + in[3] + in[4] + in[5] + in[6] + in[7]; //Adds the inputs from testbench and outputs it
end
endmodule
Questions:
Is that the proper way to have 8 1-bit inputs? Or do I need to declare each variable as one bit ex: input A,B,C,D,E,F,G,H;
If my above code is close to being correct, is that the proper way to get out to display the count of 1's? Would I need a case statement?
I'm really new to verilog, so I don't even want to think about a test bench yet.
The way you wrote it is probably the better way of writing it because it makes it easier to parameterize the number of bits. But technically, you have one 8-bit input.
module 8to4 #(parameter WIDTH=8) (input [WIDTH-1:0] in,
output reg [3:0] out,hold,
input clk,reset);
reg [WIDTH-1:0] temp;
integer ii;
always #(clk)
begin
temp = 0;
for(ii=0; ii<WIDTH; i = i + 1)
temp = temp + in[ii];
out <= temp;
end
endmodule
Logically the code is proper.
However you can improve it like the following.
Make out as a reg, because you are using it in a procedural assignment.
Usage of reset. Ideally any code should have reset state, which is missing in your code.
Declare the direction (input/output) for hold, clk & reset port, which is currently not specified.
As dave mentioned, you can use parameters for your code.

verilog multiplication results is zero?

i'm trying to multiply two 32 bit signed fractional number (1 sign bit, 8 integer bit, 23 fraction bit)
the first one is
32'b0_00000001_00000000000000000000000 // 1.00
the 2nd one is
32'b0_00000100_00000000000000000000000 // 4.00
when i do like this for example
output signed[31:0] a;
assign a = 32'b0_00000001_00000000000000000000000 * 32'b0_00000100_00000000000000000000000;
the results is zero? why it isn't 4?
kindly please help me in which part i am mistaken and what should i do. thank you very much
regards
Isaac
Because you are trying to assign a 64 bit value to a 32 bit wire, and Verilog will truncate the value, keeping only the lower 32 bits of the result, which is zero.
To have a proper result, you can do as this:
module mult;
reg [31:0] a = 32'b0_00000001_00000000000000000000000; // 1.0
reg [31:0] b = 32'b0_00000100_00000000000000000000000; // 4.0
reg [63:0] t;
reg [31:0] c;
initial begin
t = a * b;
c = t[54:23];
$display ("%b",c);
$finish;
end
endmodule

Signed multiplier Verilog

I am designing a processor in Verilog. I'm working on the ALU, specifically the multiplier for the ALU. I can get the correct results when performing multiplication with small, positive numbers, but if I try to multiply signed numbers I get issues. When a positive number multiplies a negative the result will not sign extend all the way to 64 bits, and if two negative numbers are multiplied the number is incorrect altogether (sign and value). Can anyone see where the issue lies? I assumed I was not performing an arithmetic shift but I adjusted that and am still getting the wrong results.
module multiplier(
input[31:0] operand1,
input[31:0] operand2,
output reg [63:0] product
);
reg [64:0] prod;
reg [31:0] mcand;
reg [31:0] sum;
integer i = 0;
always #* begin
prod = {32'b0,operand1};
mcand = operand2;
for(i=0;i<32;i=i+1) begin
//test 0 bit of product
case(prod[0])
1'b0:begin //if prod[0] == 0, arithmetic shift right
prod = prod>>>1;
end
1'b1:begin //if prod[0] == 1, add multiplicand to upper 32
//bits and arithmetic shift right
prod = {(prod[63:32]+mcand[31:0]),prod[31:0]};
prod = prod>>>1;
end
endcase
end
product = prod[63:0];
end
endmodule
For >>> to perform signed shift the variable must be declared as signed.
reg signed [64:0] prod;
Short example on eda playground.
Also note that prod = {32'b0,operand1}; is not a sign extension. You should probably be using:
prod = { {32{operand[31]}}, operand1 };

Verilog Design of a 32-bit ALU

Can you help me guys do a 32-bit ALU and explain me some things?
Wanna do:
0 bitwise AND: out = inA & inB.
1 bitwise OR: out = inA | inB.
2 addition: out = inA + inB.
6 subtraction: out = inA – inB //2's complement
7 Set On Less Than: out = ((inA < inB)?1:0)
12 NOR: out = ~( inA | inB)
Done this so far:
module ALU #(parameter N=32)(ALUOut, Zero, ALUinA, ALUinB, ALUop);
output [N-1:0] ALUOut;
reg [N-1:0] ALUOut;
output Zero;
reg Zero;
input [3:0] ALUop;
input [N-1:0] ALUinA, ALUinB;
always #(ALUinA or ALUinB or ALUop)
begin
case (ALUop)
4'b0000: ALUOut = ALUinA & ALUinB ; // 0:AND
Your code is good. Just some modifications required. ALUOut must be [N:0], since you'll require a carry bit in case of addition. Also, borrow bit must be required in case of subtraction.
Referring to SystemVerilog LRM 1800-2012 Section 11.6 Expression bit lengths,
SystemVerilog uses the bit length of the operands to determine how many bits to use while evaluating an
expression.
So, ALUOut[N-1:0] = ALUinA[N-1:0] + ALUinB[N-1:0]; will strictly evaluate an expression of N, while ALUOut = ALUinA + ALUinB; will
evaluate depending on size of ALUOut. Here, you can not see the difference, since all youe operands are N bits wide, but when ALUOut is increased to N+1 bits(including carry), then it can create a difference.
For example,
module top();
bit [3:0] a,b;
logic [3:0] sum;
bit carry;
assign sum[3:0] = a[3:0] + b[3:0];
// assign {carry,sum}= a + b;
initial
$monitor("a = %0d b = %0d carry = %0d sum = %0d",a,b,carry,sum);
initial
begin
a = 5; b = 1;
#5 ; a = 15; b = 1;
end
endmodule
shall execute to a = 15 b = 1 carry = 0 sum = 0 while, using the commented assign statement executes to a = 15 b = 1 carry = 1 sum = 0
Refer to LRM 1800-2012, Section 11.6 for further information.
Also, this and this links regarding ALU design can be useful.
In 2's complement -B is ~B+1 (~ is bit invert). Therefor A - B == A + (-B) == A + ~B + 1. But your doing RTL, so you don't need to write the 2's complement for subtraction as it is default. A - B and A + ~B + 1 will synthesize the same.
A[N-1:0] + B[N-1:0] is always an unsigned operation. A + B can be a signed operation if A and B are declared as input signed [N-1:0] A, B, otherwise it is an unsigned operation.
Other notes:
There is an issue with your header. Many simulators, synthesizers, and other Verilog tools will accept what you have, but it is not complaint with the IEEE standard. There are two header styles, ANSI and non-ANSI. I recommend ANSI unless required to follow the IEEE1364-1995 version of the standard.
ANSI style (IEEE Std 1364-2001 and above):
module ALU #(parameter N=32)(
output reg [N-1:0] ALUOut,
output reg Zero,
input [N-1:0] ALUinA, ALUinB,
input [3:0] ALUop );
Non-ANSI style (IEEE Std 1364-1995 and above):
module ALU (ALUOut, Zero, ALUinA, ALUinB, ALUop);
parameter N=32;
output [N-1:0] ALUOut;
output Zero;
input [3:0] ALUop;
input [N-1:0] ALUinA, ALUinB;
reg [N-1:0] ALUOut;
reg Zero;
always #(ALUinA or ALUinB or ALUop) is syntax legal. However since IEEE1364-2001 combinational logic is recommenced to be written as always #* or always #(*) (#* and #(*) are synonymous, user preference). With SystemVerilog (IEEE1800), the successor of Verilog (IEEE1364), always_comb is recommend over always #* for combinational logic, and always_latch for level-sensitive latching logic.

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

Resources