0% found this document useful (0 votes)
625 views

Verilog Code For Simple Computer

This document describes the design and implementation of a datapath unit using Verilog modules. It includes modules for basic components like multiplexers, adders, registers, and decoders. It also includes more complex modules like an arithmetic logic unit (ALU), shifter, functional unit, register file, and overall datapath module. The datapath module instantiates and connects all the components to implement a basic processor datapath that can perform arithmetic, logical, and shift operations on inputs under control of a control word. A testbench is provided to simulate and test the datapath design.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
625 views

Verilog Code For Simple Computer

This document describes the design and implementation of a datapath unit using Verilog modules. It includes modules for basic components like multiplexers, adders, registers, and decoders. It also includes more complex modules like an arithmetic logic unit (ALU), shifter, functional unit, register file, and overall datapath module. The datapath module instantiates and connects all the components to implement a basic processor datapath that can perform arithmetic, logical, and shift operations on inputs under control of a control word. A testbench is provided to simulate and test the datapath design.
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 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