4 bit full subtraction with a 1 bit full subtractor - verilog

I'm trying to us a 1 bit full subtractor by a 4 bit module as so - I'm a little stuck on where to go next, I'm not sure what's happening under the hood - I thought maybe I could us fullsub in a loop of sub4 and iterate over each of the bits and update the in vs out, but I'm not sure how to do that.
module fullSub(x, y, b_in, diff, b_out);
input x, y, b_in;
output diff, b_out;
assign diff=(x^y)^b_in;
assign b_out = (~(x^y)&b_in) | ((~x)&y);
endmodule
module sub4(x, y, b_in, diff, b_out);
input [3:0] x, y;
input b_in;
output [3:0] diff;
output b_out;
fullSub init[3:0](x, y, b_in, diff, b_out);
assign b_in = b_out;
endmodule

I used the following and it worked well - thanks.
wire [3:0] borrow
genvar i;
generate
for(i=3; i>=0; i=i-1)
begin: description
if(i===0)
fullSub s(x[i], y[i], b_in, diff[i], borrow[i]);
else
fullSub s(x[i], y[i], borrow[i-1], diff[i], borrow[i]);
end
assign b_out = borrow[3];
endgenerate

Related

Bidirectional shifting using multiplexers

Edit:Only by the screenshots(http://prntscr.com/lv3uqw http://prntscr.com/lv3yhf) and my code below you can still understand my goal here just incase you dont want to read the text.
I am trying to write a verilog code for a universal shift register. My original register was working properly(the one without the LR_bar signal). But on this one i have no idea how i can make this conection(mux with ff) happen http://prntscr.com/lv3uqw and http://prntscr.com/lv3yhf.I had a suggestion that the for loop should start from -1 but i still cant find a solution. I would also like to avoid the h signal if possible(maybe we also use the w there). So basicly when LR_bar=1 i want the shift register to shift left and when =0 to shift right.
Tip for the screenshot: ser in l_sh stands for serial input for left shifting
(Also found that on a Mano Morris 3rd edition(6th is more detailed) book (Computer Design Fundamentals) which is, to a point , a little close to what i want. But i want 2to1 multiplexers . But the 2 first screenshots is what i want to achieve.
http://prntscr.com/lvb5bt http://prntscr.com/lvb65f )
I think i describe it well...can someone solve this?
MY NEW CODE(below) AND TEST AFTER SOME VALUES......http://prntscr.com/lvhk63
I TRIED TO MIMIC THAT(http://prntscr.com/lvgx31 http://prntscr.com/lvgxgw http://prntscr.com/lvgxkw) BUT ONLY FOR THE SERIAL INPUT PART(MSB,LSB). PLEASE TELL ME WHERE IM WRONG. THANKS
the output should be the state of the register
-----------------------------------------------------------
module lr_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
wire [n+1:0] w;
wire [n-1:0] mux_out;
genvar i;
assign w[0]=in;
assign w[n+1]=in;
generate
for(i=0;i<n;i=i+1)
begin
mux2to1 MUX(.in({w[i],w[i+2]}),.sel(LR_bar),.out(mux_out[i]));
dff ff1(.d(mux_out[i]), .q(w[i+1]), .clk(clk),
.rst(rst));
end
endgenerate
assign out=w[n:1];
endmodule
------------------------------------------------------------
JUST AN ATTEMPT NOTHING TO LOOK
module lr_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
wire [n+1:0] w;
wire mux_out;
genvar i;
assign w[0]=in;
assign w[n+1]=in;
generate
for(i=-1;i<n-1;i=i+1)
begin
mux2to1 MUX(.in({w[i+1],w[3+i]}),.sel(LR_bar),.out(mux_out));
dff ff1(.d(mux_out), .q(out[i+1]), .clk(clk),
.rst(rst));
end
endgenerate
------------------------------------------------------------
module dff (d, q, clk, rst);
input d, clk, rst;
output reg q;
always # (posedge clk) begin : dff_block
if (rst==1'b1)
q = 1'b0;
else
q = d;
end
endmodule
module mux2to1(in, sel, out) ;
input [1:0] in;
input sel;
output reg out;
always #(*)
case(sel)
1'b0: out=in[0];
1'b1: out=in[1];
endcase
endmodule
module shreg_n(in, out, clk, rst);
parameter n=4;
input in, rst, clk;
output [n-1:0] out;
wire [n:0] w;
genvar i;
assign w[0]=in;
generate
for(i=0;i<n;i=i+1)
dff ff1(.d(w[i]), .q(w[i+1]), .clk(clk),
.rst(rst));
endgenerate
assign out=w[n:1];
//assign out=w[n];
endmodule
Blocking assignments might work in your specific case. As a matter of clean coding style and preventing any issues in the future, always use <= for all output assignments in flops (and latches).
Now, let's see what you want to do:
w = out; // to keep the immediate values and avoid ordering issues
for left shift: w[3] -> x, w[2] -> out[3], w[1] -> out[2], w[0] -> out[1] , in -> out[0]
for right shift: w[0] -> x, w[1] -> out[0], w[2] -> out[1], w[3] -> out[2], in -> out[3]
so, with a mux, say for out[2]i == 2, you would need a mux which does this:
- w[1] -
-> out[2]
- w[3] -
mux2to1 (.in({out[i+1], out[i-1]}), .sel(LR_sel), .out(out[i]));
you also need to take care of special cases [0] with left shift and [n-1] with the right shift. For simplicity,
you can use if statement in the generate block to handle it.
if (i == 0)
mux2to1 MUX0(.in({in, w[1]}), .sel(LR_bar), .out(tmp[0]));
else if (i == n-1)
mux2to1 MUXN(.in({w[n-2], in}), .sel(LR_bar), .out(tmp[n-1]));
.out(out[i]));
else
mux2to1 (.in({out[i-1], out[i+1]}), .sel(LR_sel), .out(out[i]));
Basically it creates yet another mux for those special cases, so that you have more of them.
As for the flop, there are at least 2 ways to approach it. You can flop results before or after the mux.
for the flopping before the mux (which i assumed in the above explanation), you just do
always #(posedge clk)
if (rst)
w <= 4'b0;
else
w <= out;
to do it after the mux, you would need to switch out and w and then flop w into out. You can do a bit-by-bit flop as you did, but it makes the program more crowded in my opinion. Also it causes verilog to generate multiple one-bit flops which might affect simulation performance.
Another approach for shift registers with the flop is to something like the following:
always #(posegde clk) begi
if (rst)
out <= 4'b0;
else if (LR_bar) begin
out <= {out[2:0], in};
end
else begin
out <= {in, out[3:1]};
end
end
The above simplifies the code significantly. BTW, you would have an issue if you use blocking assignments there.
Edit 1
I modified your code to a workable condition down here based on my comments.
you need a register w to keep the shift register value. You need the tmp to connect the mux with the flop. w is the output of the flop.
module uni_shreg_n(in, out, clk, rst, LR_bar);
parameter n=4;
input in, rst, clk, LR_bar;
output [n-1:0] out;
reg [n-1:0] w; // keep the value of the register shift
wire [n-1:0] tmp;
genvar i;
mux2to1 MUX0(.in({in,w[1]}), .sel(LR_bar), .out(tmp[0]));
mux2to1 MUXN(.in({w[n-2], in}), .sel(LR_bar), .out(tmp[n-1]));
generate
for(i=0;i<n;i=i+1) begin
if (i > 0 && i < n-1) begin: loop
mux2to1 MUX(.in({w[i-1], w[i+1]}), .sel(LR_bar), .out(tmp[i]));
end
dff ff1(.d(tmp[i]), .q(w[i]), .clk(clk), .rst(rst));
end
endgenerate
assign out = w;
endmodule

error trying to implement 32-bit adder

I am trying to add two 32 bits numbers using verilog.But I am getting many dont-care in the resut.
The 32 bit adder uses 4 8-bit adders.One 8 -bit adder uses one bit Full-Adder.FAdder makes use of 3 to 8 decoder.
Here is my code-
module Decoder(D,x,y,z);
input x,y,z;
output [0:7] D;
wire xn,yn,zn;
not n1(xn,x);
not n2(yn,y);
not n3(zn,z);
and a1(D[0],xn,yn,zn);
and a2(D[1],xn,yn,z);
and a3(D[2],xn,y,zn);
and a4(D[3],xn,y,z);
and a5(D[4],x,yn,zn);
and a6(D[5],x,yn,z);
and a7(D[6],x,y,zn);
and a8(D[7],x,y,z);
endmodule
module FAdder(S,C,x,y,z);
input x,y,z;
output S,C;
wire [0:7] D;
Decoder dec(D,x,y,z);
assign S= D[1] | D[2] | D[4] | D[7];
assign C= D[3] | D[5] | D[6] | D[7];
endmodule
module eightbitAdder(S,Carry,in1,in2,z);
input [7:0] in1;
input [7:0] in2;
input z;
output [7:0] S;
output Carry;
wire C[7:0];
assign z=0;
FAdder F1(S[0],C[0],in1[0],in2[0],z);
FAdder F2(S[1],C[1],in1[1],in2[1],C[0]);
FAdder F3(S[2],C[2],in1[2],in2[2],C[1]);
FAdder F4(S[3],C[3],in1[3],in2[3],C[2]);
FAdder F5(S[4],C[4],in1[4],in2[4],C[3]);
FAdder F6(S[5],C[5],in1[5],in2[5],C[4]);
FAdder F7(S[6],C[6],in1[6],in2[6],C[5]);
FAdder F8(S[7],C[7],in1[7],in2[7],C[6]);
assign Carry=C[7];
endmodule
module t32bitadder(S,Carry1,in1,in2);
input [31:0] in1,in2;
output [31:0] S;
output Carry1;
wire [3:0] C1;
wire initCarry;
assign initCarry=0;
eightbitAdder e1(S[7:0],C1[0],in1[7:0],in2[7:0],initCarry);
eightbitAdder e2(S[15:8],C1[1],in1[15:8],in2[15:8],C1[0]);
eightbitAdder e3(S[23:16],C1[2],in1[23:16],in2[23:16],C1[1]);
eightbitAdder e4(S[31:24],C1[3],in1[31:24],in2[31:24],C1[2]);
assign Carry1=C1[3];
endmodule
module testbench32bitAdder;
reg [31:0] in1,in2;
reg z;
wire [31:0] S;
wire C;
t32bitadder Al(S,C,in1,in2);
initial
$monitor(,$time,"in1=%b,in2=%b,S=%b,C=%b",in1,in2,S,C);
initial
begin
#0 in1=32'b00000001000000010000000110000001;in2=32'b00000001000000010000000110000001;
#4 in1=32'b11000001100000011000000100000001;in2=32'b11000001100000010000000100000001;
#4 in1=32'b00000001000000010000000100000001;in2=32'b10000001000000010000000100000001;
end
This is the result I am getting-
# 0in1=00000001000000010000000110000001,in2=00000001000000010000000110000001,S=0000001000000010000000xx00000010,C=0
# 4in1=11000001100000011000000100000001,in2=11000001100000010000000100000001,S=100000xx000000101000001000000010,C=1
# 8in1=00000001000000010000000100000001,in2=10000001000000010000000100000001,S=10000010000000100000001000000010,C=0
Notice the dont-care in the second output. This is because of the C1[2] which becomes X . Can anyone point out my mistake?
vipin is correct, the assign z=0; line in the eightbitAdder module is leading to the dont cares. In your test, the carry out of the first 8-bit adder is 1, it attempts to set the z input to the next 8-bit adder to 1, but this conflicts with the continuous assignment of z to 0, thus resulting in z = 1'bx. This dont care is propagated through the first FA and impacts the second as well, which results in the 2 dont cares in the 8th and 9th places of the result (where the first bit is the 0th place). The same thing is happening between your third and your final 8-bit adders in the second test. Your third test doesnt propagate a carry between 8-bit adders so no dont cares are generated.

Verilog Simulation Error. Modelsim Altera 10.1b

This is my gate level code for A 4 bit full adder.
//Define stimulus
module stimulus;
//setup variables
reg[3:0] A,B;
reg C_IN;
wire [3:0] SUM;
wire C_OUT;
//Instantiate 4 bi full adder
fulladd4 FA1_4(SUM,C_OUT,A,B,C_IN);
//Setup for monitoring the values
initial
begin
$monitor($time," A= %b,B= %b,C_IN= %b, --- C_OUT= %b, SUM= %b \n",A,B,C_IN,C_OUT,SUM);
end
//Stimulate Inputs
initial
begin
A = 4'd0; B = 4'd0; C_IN = 1'b0;
#5 A = 4'd1; B = 4'd2;
#5 A = 4'd3; B = 4'd4;
end
endmodule
//Define full 1 bit adder
module fulladd(sum, c_out,a,b,c_in);
//I/O Ports Declaration
output sum,c_out;
input a,b,c_in;
//Internal nets
wire s1, c1, s2;
//Instantating the gates
xor (s1,a,b);
and (c1,a,b);
xor (sum,s1,c_in);
and (s2,s1,c_in);
xor (c_out,s2,c1);
endmodule
//Define a 4 bit full adder
module fulladd4(sum,c_out,a,b,c_in);
//I/O Ports declaration
output [3:0] sum;
output c_out;
input [3:0] a,b;
input c_in;
//internal nets
wire c1,c2,c3;
//Instantiate 4 full 1 bit adders
fulladd fa0(sum[0],c1,a[0],b[0],c_in);
fulladd fa1(sum[1],c2,a[1],b[1],c1);
fulladd fa2(sum[2],c3,,a[2],b[2],c2);
fulladd fa3(sum[3],c_out,a[3],b[3],c3);
endmodule
It show a fatal error while simulating.
** Fatal: (vsim-3365)
C:/altera/12.1/modelsim_ase/Full_Bit_Adder.v(67): Too many port
connections. Expected 5, found 6.
Time: 0 ps Iteration: 0 Instance: /fulladd4/fa2 File: C:/altera/12.1/modelsim_ase/Full_Bit_Adder.v
This is the error that it shows
Can someone please explain me my mistake
In the 67th line there are two commas after c3. If you remove one of them, it should be working.
fulladd fa2(sum[2],c3,,a[2],b[2],c2);
you have used 2 commas consecutively. This is resulting in error because simulation tool takes it as 6 ports but we require only 5.

32 bit adder subtractor ALU using generate

I need to implement a 32 bit adder subtractor ALU for a class assignment. I have a 1-bit adder subtractor that works fine and the operation is made with the help of a select statement (code for all is given below). Anyway, the problem I am facing is that I am unable to figure out how to use the carry/borrow out of one module to the subsequent module.
module add_sub(select, i0, i1, cin, out, cout
);
input i0, i1, select, cin;
output out, cout;
wire y0, y1, y2, y3, y4, y5, y6;
wire z0, z1, z2, z3, z4;
//diff = i0 xor i1 xor cin
//borrow = cin. ~(i1 xor i2) or ~x.y
xor (y0, i1, cin);
xor (y1, i0, y0); //y1=diff or sum as only carry and borrow vary between adder and subtractor circuits
xor (y2, i1, i0);
and (y3, cin, ~y2);
and (y4, ~i0, i1);
or (y6, y5, y4); //y6 = borrow
and (z0, i0, i1);
xor (z1, i0, i1);
and (z2, cin, z1);
or (z3, z0, z2); //z3= carry out for sum
//conditional operator for assigning sum or difference. if select = 0, we add, else subtract
assign out = y1;
assign cout = select ? y6 : z3;
endmodule
This module is instantiated in a loop in the alu module that is given below...
module alu(sel, num1, num2, alu_cin, alu_out, alu_c
);
parameter N = 32;
input sel; //select line for add or sub
input [N-1:0] num1; //two inputs
input [N-1:0] num2;
input alu_cin;
output [N-1:0] alu_out; //32 bit output
output alu_c; // becomes final carry or borrow accordingly
genvar i;
generate for (i=0; i<=N-1; i=i+1)
begin: alu_loop
if (i == 0)
add_sub as_i (sel, num1[i], num2[i], alu_cin, alu_out[i], alu_c);
else
add_sub as_i (sel, num1[i], num2[i], alu_loop[i-1].as_i.cout[i-1], alu_out[i], alu_c);
end
endgenerate
endmodule
In the test bench for the alu, I gave appropriate 32 bit values and the select value as I need. The problem comes with
add_sub as_i (sel, num1[i], num2[i], alu_loop[i-1].as_i.cout[i-1], alu_out[i], alu_c);
It says "Indexing cannot be applied to a scalar." as I am trying to simulate it. Syntax check is completed perfectly.
I need access to cout from the one-bit module to pass it on as cin to the next one. The alu_c can be overwritten as only the last one bit is needed.
Any help would be appreciated. Thanks in advance. :) All this is done on Xilinx ISE through Verilog modules.
It is syntactically correct but you are using a bit-select on a single bit value, which is a semantic error.
add_sub as_i (
sel,num1[i],num2[i],alu_loop[i-1].as_i.cout[i-1],alu_out[i],alu_c);
^^^^
Declared as scalar output in add_sub
output out, cout;
While Verilog allows referencing a port using the dot notation(hierarchical referencing), it's not a good practice outside of testbenches. You should declare a wire for that connectivity instead.
for (i=0; i<=N-1; i=i+1)
begin: alu_loop
wire cout; // Visible as alu_loop[N].cout
end

how to define m*n output in verilog

i am writting verilog code for shift left register which store its value after each shift in sub registers. can i define the output registers as array like this,the provided code is just a simple example to show the concept not my code,
module test(a,b,c);
input a,b;
output [7:0] c [3:0];
endmodule
instead of
module test(a,b,c1,c2,c3,c4);
input a,b;
output [7:0] c1,c2,c3,c4;
endmodule
and for the first way how i can call c[i]
... Yes you can very much use a 2D array at the output, like in your first example. Check out Section 5 of this paper by Stuart Sutherland himself, this should give you some confidence. The section is titled Module Ports.
http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CC4QFjAA&url=http%3A%2F%2Fwww.sutherland-hdl.com%2Fpapers%2F2006-SNUG-Europe_SystemVerilog_synthesis_paper.pdf&ei=7KmYUNKPN6GyigKDnoHwDA&usg=AFQjCNGmr3flHrARC-w40xveo8zitcdjfg&cad=rja
Also, elaborating on your first example, you can define your module this way for clarity:
module lshift(clk, reset, a, c);
input wire clk, reset;
input wire [7:0] a;
output reg [7:0] c [0:3]; // <-- defining the unpacked dimension as [0:3] for clarity
always#(posedge clk) begin
if(reset) begin
c[0] <= 8'd0;
...
c[3] <= 8'd0;
end
else begin
c[0] <= a;
c[1] <= c[0];
c[2] <= c[1];
c[3] <= c[2];
end
end
endmodule
... and now you can slice into your array. c[0], c[1] .. c[3] each represents a Byte and c[0][3:0] would mean the lower nibble of the first byte.
... Hope this helps!

Resources