Verilog Code For Simple Computer
Verilog Code For Simple Computer
//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
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
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
//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]);
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;
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]);
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;
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;