You are on page 1of 7

module MUX2_1(Q,I0,I1,S);

//2X1 MUX
input I0,I1;
//input lines
input S;
//select line
output Q;
//output line
wire w1,w2;
//interconnecting wires
and(w1,S,I1);
and(w2,~S,I0);
or(Q,w1,w2);
endmodule
module qMUX2_1(Q,I0,I1,S); //Quad 2X1 MUX
input[3:0] I0,I1; //4bit input vectors
input S;
//select line
output[3:0] Q; //Output vector of the Quad MUX
MUX2_1
MUX2_1
MUX2_1
MUX2_1

mux1(Q[0],I0[0],I1[0],S);
mux2(Q[1],I0[1],I1[1],S);
mux3(Q[2],I0[2],I1[2],S);
mux4(Q[3],I0[3],I1[3],S);

endmodule
module MUX4_1(Q,D0,D1,D2,D3,S0,S1);
input D0,D1,D2,D3; //input lines
input S0,S1;
//select lines
output Q;
//output line

//4X1 MUX build using 2X1 MUXes

MUX2_1 mux1(w1,D0,D1,S0);
MUX2_1 mux2(w2,D2,D3,S0);
MUX2_1 mux3(Q,w1,w2,S1);
endmodule
module Shifter(H,B,Ir,Il,S); //Task 1a =
input [3:0] B; //input which has to be
output [3:0] H; //shifted output of the
input Ir,Il;
//Right and Left serial
input [1:0] S; //Operation selector
MUX4_1
MUX4_1
MUX4_1
MUX4_1

Basic Shifter using 4X1 MUXes


shifted
shifter
inputs

m3(H[3],B[3],Ir,B[2],,S[0],S[1]);
m2(H[2],B[2],B[3],B[1],,S[0],S[1]);
m1(H[1],B[1],B[2],B[0],,S[0],S[1]);
m0(H[0],B[0],B[1],Il,,S[0],S[1]);

endmodule
//The Arithmetic Unit from Lab Assignment #7
module HA(ca,s,a,b);
input a,b;
output ca,s;
xor(s,a,b);
and(ca,a,b);
endmodule

//Half Adder implementation

module FA(carry,sum,a,b,c); //Full Adder constructed from Half Adders


input a,b,c;
output carry,sum;
wire w1,w2,w3;
HA ha1(w2,w1,a,b);
HA ha2(w3,sum,w1,c);
or(carry,w3,w2);
endmodule
module FADD(V,CO,S3,S2,S1,S0,A3,A2,A1,A0,B3,B2,B1,B0,CI); //Four bit
adder
input A0,A1,A2,A3,B0,B1,B2,B3,CI;
output CO,S0,S1,S2,S3;
output V;
//overfow indication bit
wire c1,c2,c3;
FA fa0 (c1,S0,A0,B0,CI);
FA fa1 (c2,S1,A1,B1,c1);
FA fa2 (c3,S2,A2,B2,c2);
FA fa3 (CO,S3,A3,B3,c3);
xor(V,CO,c3);

//overflow detection

endmodule
module subcir(out,a,b,c,d);
//subcircuit to be used in the
implementation of Arithmetic Unit
input a,b,c,d; //inputs of the subcircuit
output out;
//output of the subcircuit
wire w1,w2;
//interconnecting wires
and(w1,a,b);
and(w2,c,d);
or(out,w1,w2);
endmodule
module AU(V,G,Cout,X,Y,S0,S1,S2); //Lab #7-Task 1: Arithmetic Unit
input[3:0] X,Y;
//input vectors
output[3:0] G;
//output vector
input S0,S1,S2;
//select lines
output Cout;
//carry out
wire w1,w2,w3,w4; //interconnecting wires
output V;
//overflow indication
subcir
subcir
subcir
subcir

sub1(w1,Y[3],S1,~Y[3],S2);
sub2(w2,Y[2],S1,~Y[2],S2);
sub3(w3,Y[1],S1,~Y[1],S2);
sub4(w4,Y[0],S1,~Y[0],S2);

FADD
fbadder(V,Cout,G[3],G[2],G[1],G[0],X[3],X[2],X[1],X[0],w1,w2,w3,w4,S0);
endmodule

module LU(Qi,Xi,Yi,S0,S1);
//1 bit Logic unit
input Xi,Yi; //input lines
input S0,S1; //select lines
output Qi;
//output line
wire w1,w2,w3,w4; //interconnecting wires
not(w1,Xi);
//implementing the Logic-NOT operation
xor(w2,Xi,Yi); //implementing the Logic-XOR operation
or(w3,Xi,Yi);
//implementing the Logic-OR operation
and(w4,Xi,Yi); //implementing the Logic-AND operation
MUX4_1 mux421(Qi,w4,w3,w2,w1,S0,S1);
endmodule
module FLU(Q,X,Y,S0,S1);
// 4 bit Logic Unit
input[3:0] X,Y;
//Input vectors of the Logic unit
output[3:0] Q;
//output vector of the Logic Unit
input S0,S1;
//select lines of the Logic Unit
LU lu1(Q[3],X[3],Y[3],S0,S1);
LU lu2(Q[2],X[2],Y[2],S0,S1);
LU lu3(Q[1],X[1],Y[1],S0,S1);
LU lu4(Q[0],X[0],Y[0],S0,S1);
endmodule
module ALU(V,G,Cout,X,Y,S0,S1,S2,S3);
//Arithmetic Logic Unit
Complete
input[3:0] X,Y;
//input numbers(vectors)
input S0,S1,S2,S3;
//select lines
output[3:0] G;
//output vector
wire[3:0] w1,w2;
//interconnecting wires
output Cout;
output V;
//overflow indicator
AU alu1(V,w1,Cout,X,Y,S0,S1,S2); //Calling the Arithmetic Unit
FLU alu2(w2,X,Y,S0,S1);
//Calling the Logic Unit
qMUX2_1 alu3(G,w1,w2,S3);
//Calling the Quad MUX
endmodule
module FUnit(C,Z,N,V,F,A,B,FS);
//Task 1b = Functional Unit
input[3:0] A,B;
//inputs A and B on which the function will be
performed
output[3:0] F;
//output F of the Functional unit
input[3:0] FS;
//Function select lines of the functional unit
wire MF;
//To select between shifter and ALU
wire [3:0] G,H;
//outputs of the ALU and the Shifter
output C;
//status bit indicating carry out
output Z;
//status bit indicating zero output
output N;
//status bit indicating sign
output V;
// Status bit indicating overflow
and(MF,FS[3],FS[2]);

//MF will select between Shifter and ALU

ALU alu(V,G,C,A,B,FS[0],FS[1],FS[2],FS[3]); //calling the ALU


Shifter shifter(H,B,1'b0,1'b0,FS[1:0]);
//calling the shifter
qMUX2_1 MuxF(F,G,H,MF);
and(Z,~F[0],~F[1],~F[2],~F[3]);
//zero detection
buf(N,F[3]);
//MSB is taken as the sign bit
endmodule
module testFU();
//Task 1c = Test Bench for Functional Unit
reg [3:0] A,B,FS;
//inputs for the Functional unit
wire [3:0] F;
//Output of the functional Unit
FUnit functional_unit(C,Z,N,V,F,A,B,FS);
unit
initial
begin
A = 4'b0110;

//calling the functional

B = 4'b0111; FS=4'b0000;

repeat(14)
#5 FS = FS + 1'b1;
end
endmodule
//Register File from the previous lab
module decoder2X4(d0,d1,d2,d3,s0,s1);
input s0,s1;
//input lines of decoder
output d0,d1,d2,d3; //output lines of the decoder
and(d0,~s1,~s0);
and(d1,~s1,s0);
and(d2,s1,~s0);
and(d3,s1,s0);
endmodule
module QMUX4_1(Q,I0,I1,I2,I3,S0,S1);
//Quad 4X1 MUX
input[3:0] I0,I1,I2,I3;
//vector inputs
input S0,S1;
//select lines of the Quad MUX
output[3:0] Q;
//Output vector of the Quad MUX
wire w1,w2,w3,w4;
//wires for decoder output(minterms);
//implementing a 2X4 decoder
and(w1,~S1,~S0);
and(w2,~S1,S0);
and(w3,S1,~S0);
and(w4,S1,S0);
//now w1,w2,w3,w4 are the decoded outputs for S0,S1
wire[3:0] iw0,iw1,iw2,iw3;
and(iw0[0],I0[0],w1);
and(iw0[1],I0[1],w1);
and(iw0[2],I0[2],w1);
and(iw0[3],I0[3],w1);
and(iw1[0],I1[0],w2);

//interconnecting wires

and(iw1[1],I1[1],w2);
and(iw1[2],I1[2],w2);
and(iw1[3],I1[3],w2);
and(iw2[0],I2[0],w3);
and(iw2[1],I2[1],w3);
and(iw2[2],I2[2],w3);
and(iw2[3],I2[3],w3);
and(iw3[0],I3[0],w4);
and(iw3[1],I3[1],w4);
and(iw3[2],I3[2],w4);
and(iw3[3],I3[3],w4);
or(Q[0],iw0[0],iw1[0],iw2[0],iw3[0]);
or(Q[1],iw0[1],iw1[1],iw2[1],iw3[1]);
or(Q[2],iw0[2],iw1[2],iw2[2],iw3[2]);
or(Q[3],iw0[3],iw1[3],iw2[3],iw3[3]);
endmodule
module D_ff (out, in, rst, clk);
parameter n = 4;

//D-flipflop code provided

output [n-1:0] out;


input [n-1:0] in;
input rst;
input clk;
reg [n-1:0] out;
always @(posedge clk)
begin
if (rst)
out = 0;
else
out = in;
end
endmodule
module REG(Y,In,Load,reset,clk);
//4-bit register
input[3:0] In;
//Input for the register
input Load,clk;
//Load line and clock signal for the register
input reset;
//reset signal for the register
output[3:0] Y;
//Output of the register
wire[3:0] in;
//output of the muxes
MUX2_1 mux0(in[0],Y[0],In[0],Load);
MUX2_1 mux1(in[1],Y[1],In[1],Load);
MUX2_1 mux2(in[2],Y[2],In[2],Load);
MUX2_1 mux3(in[3],Y[3],In[3],Load);
D_ff dff(Y,in,reset,clk);
endmodule
module RegFILE(A,B,D,dest,a,b,Write,reset,clk);
//Register File
input[3:0] D;
//Data input of the register file

input[1:0] a;
input[1:0] b;
input[1:0] dest;
input Write;
input reset,clk;
output[3:0] A,B;

//A-select(A address)
//B-select(B address)
//Destination select(input of decoder/D address)
//Load Enable(Write)
//Reset and clock signal for the register
//A and B data outputs

wire[3:0] Y0,Y1,Y2,Y3;
wire l0,l1,l2,l3;

//Outputs of R0,R1,R2,R3
//Load lines for R0,R1,R2,R3

wire d0,d1,d2,d3;
//outputs of the decoder
decoder2X4 deco(d0,d1,d2,d3,dest[0],dest[1]);
//applying the load enable functionality
and(l0,d0,Write);
and(l1,d1,Write);
and(l2,d2,Write);
and(l3,d3,Write);
REG
REG
REG
REG

R0(Y0,D,l0,reset,clk);
R1(Y1,D,l1,reset,clk);
R2(Y2,D,l2,reset,clk);
R3(Y3,D,l3,reset,clk);

QMUX4_1 muxA(A,Y0,Y1,Y2,Y3,a[0],a[1]);
QMUX4_1 muxB(B,Y0,Y1,Y2,Y3,b[0],b[1]);
endmodule
module Datapath(C,Z,N,V,Data_out,Address_out,Data_in,Constant_in,CW,clk);
input [15:0] CW;
//The ultimate control word
output [3:0] Data_out,Address_out;
input [3:0] Data_in,Constant_in; //Data input and constant input
input clk;
//clock signal
output C,Z,N,V;
//indications
wire [3:0] B;
//wire connecting the data B from regfile to the
MUX B
wire [3:0] Bus_A,Bus_B,Bus_D; //data buses connecting various
components
wire [3:0] F;
//wire carrying output of func. unit to the MUX_D
RegFILE
rfile(Bus_A,B,Bus_D,CW[14:13],CW[11:10],CW[8:7],CW[0],1'b0,clk);
qMUX2_1 MUX_B(Bus_B,B,Constant_in,CW[6]);
FUnit function_unit(C,Z,N,V,F,Bus_A,Bus_B,CW[5:2]);
qMUX2_1 MUX_D(Bus_D,F,Data_in,CW[1]);
buf(Address_out[0],Bus_A[0]); //connecting the Address_out terminal
buf(Address_out[1],Bus_A[1]);
buf(Address_out[2],Bus_A[2]);
buf(Address_out[3],Bus_A[3]);
buf(Data_out[0],Bus_B[0]);
buf(Data_out[1],Bus_B[1]);

//Connecting the Data_out terminal

buf(Data_out[2],Bus_B[2]);
buf(Data_out[3],Bus_B[3]);
endmodule
module test();
//Test bench for the data path
reg clk;
//clock signal
reg [15:0] CW;
//Control Word
wire [3:0] Data_out, Address_out; //data outputs
reg [3:0] Data_in,Constant_in,FS;
wire C,Z,N,V;
//indications
Datapath
datapath(C,Z,N,V,Data_out,Address_out,Data_in,Constant_in,CW,clk);
//calling the Datapath
always #5 clk = ~clk;
initial
begin
clk=0;

Data_in = 0; Constant_in = 0; CW=0;

// writing initial data to the registers


#5 Data_in = 7; CW = 16'b0000000000000011;
#10 Data_in = 1; CW = 16'b0010000000000011;
#10 Data_in = 2; CW = 16'b0100000000000011;
#10 Data_in = 3; CW = 16'b0110000000000011;
#5 CW=0;
//data written - about to perform the micro-operations
#5
#10
#10
#10
#10
#10
#10
#10
end
endmodule

CW
CW
CW
CW
CW
CW
CW
CW

=
=
=
=
=
=
=
=

16'b0010100110010101;
//R1 < R2 - R3
16'b0010000110111001;
//R1 < sl R3
16'b0000000000000101;
//R0 < R0 + 1
16'b0010000100010101;
//R1 < R0 - R2
16'b0000000110000000;
// Data_out < R3
16'b0010000000000011; Data_in = 4'b1111; // R1 < Data_in
16'b0100000000101001; //R2 < 0
16'b0000000000000000;

You might also like