Skip to content

Instantly share code, notes, and snippets.

@Shashi18
Last active July 17, 2019 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Shashi18/3f78d92b9c7c7bda6eca1fb50099a09d to your computer and use it in GitHub Desktop.
Save Shashi18/3f78d92b9c7c7bda6eca1fb50099a09d to your computer and use it in GitHub Desktop.
module ADDER(A,B,out,clk_ADDER);
input [7:0] A,B;
input clk_ADDER;
output reg [7:0] out;
reg [7:0] temp;
always @(negedge clk_ADDER)begin
temp = B<<1;
out = A + temp - 2;
end
endmodule
module ALU(clk_ALU,ain,bin,func,result,z,carry);
input clk_ALU;
input [7:0]ain;
input [7:0]bin;
output reg [7:0]result;
reg [8:0]temp;
output reg carry;
input [3:0]func;
output reg z;
initial begin
result = 0;
z = 0;
carry = 0;
temp = 0;
end
always @(negedge clk_ALU)begin
if(func==4'b0000)begin //ADD
temp = ain + bin;
result = temp[7:0];
carry = temp[8];
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b0001)begin // SUBTRACT
temp = ain - bin;
result = temp[7:0];
carry = temp[8];
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b0010)begin // INCREMENT BY 1
temp = ain + 1;
result = temp[7:0];
carry = temp[8];
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b0011)begin // DECREMENT BY 1
temp = ain - 1;
result = temp[7:0];
carry = temp[8];
if(result==0)
z = 1;
else
z = 0;
end
// LOGICAL OPERATIONS //
else if(func==4'b0100)begin // ADD Immediate
result = ain + bin;
carry = 0;
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b0101)begin // Subtract Immediate
result = ain - bin;
carry = 0;
if(result==0)
z = 1;
else
z = 0;
end //AND
else if(func==4'b0110)begin // EX OR
result = ain^bin;
carry = 0;
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b0111)begin // NAND
result[0] = ~(ain[0]&bin[0]);
result[1] = ~(ain[1]&bin[1]);
result[2] = ~(ain[2]&bin[2]);
result[3] = ~(ain[3]&bin[3]);
result[4] = ~(ain[4]&bin[4]);
result[5] = ~(ain[5]&bin[5]);
result[6] = ~(ain[6]&bin[6]);
result[7] = ~(ain[7]&bin[7]);
carry = 0;
if(result==0)
z = 1;
else
z = 0;
end //NAND
else if(func==4'b1000)begin // NOT
result[0] = ~ain[0];
result[1] = ~ain[1];
result[2] = ~ain[2];
result[3] = ~ain[3];
result[4] = ~ain[4];
result[5] = ~ain[5];
result[6] = ~ain[6];
result[7] = ~ain[7];
carry = 0;
if(result==0)
z = 1;
else
z = 0;
end //NOT
else if(func==4'b1001)begin // BEQ Function
temp = ain - bin;
result = temp[7:0];
carry = temp[8];
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b1010)begin // BNE Function
temp=ain-bin;
carry = temp[8];
result = temp[7:0];
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b1011)begin // BLT Function
temp=ain-bin;
carry = temp[8];
result = temp[7:0];
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b1100)begin // BGT Function
temp = ain - bin;
carry = temp[8];
result = temp[7:0];
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b1110)begin // LOAD
result = ain + bin;
carry = 0;
if(result==0)
z = 1;
else
z = 0;
end
else if(func==4'b1111)begin // STORE
result = ain + bin;
carry = 0;
if(result==0)
z = 1;
else
z = 0;
end
else begin
result = 4'bxxxx;
carry = 0;
end //Default
if(result==0)
z = 1;
else
z = 0;
end
endmodule
module Comparator(A_data, B_data, Comparator_Out);
input [7:0] A_data, B_data; //The two 8-bit Inputs A_data and B_data
output [3:0]Comparator_Out; //The Outputs of comparison
reg Gt, Lt, Eq, Ne;
always @(*) //Check the state of the input lines
begin
Gt = ( A_data > B_data )? 1'b1 : 1'b0;
Lt = ( A_data < B_data )? 1'b1 : 1'b0;
Eq = ( A_data == B_data)? 1'b1 : 1'b0;
Ne = ( A_data != B_data)? 1'b1 : 1'b0;
end
assign Comparator_Out = {Lt,Gt,Eq,Ne};
endmodule
module CONTROL(clk,opcode,Mux1,reg_wrt,BEQ, BNE, BLT, BGT, Mux8, re, wr, alu_op, Mux2, Mux3, pc_select, IM_clk, REG_clk, RAM_clk, ALU_clk, Add_clk);
input clk;
input [3:0] opcode;
output reg IM_clk, REG_clk, RAM_clk, ALU_clk, Add_clk;
output reg[3:0]alu_op;
output reg reg_wrt,re,wr,Mux1,Mux2,BEQ, BNE, BLT, BGT;
output reg [3:0] Mux8;
output reg Mux3, pc_select;
reg [3:0]pstate;
reg sign;
reg [3:0]count;
parameter s0 = 4'b0000,s1 = 4'b0001, s2=4'b0010, s3=4'b0011, s4=4'b0100, s5=4'b0101;
initial begin
pstate = s0;
sign = 0;
pc_select = 0;
count = 0;
IM_clk = 0;
REG_clk = 0;
ALU_clk = 0;
RAM_clk = 0;
Add_clk = 0;
end
always @(negedge clk)begin
alu_op <= opcode;
case(pstate)
//*********************************************************************************************************************
s0:begin // Initial State
reg_wrt<=1'b0;
re<=1'b1;
wr<=1'b1;
Mux1<=1'b1;
Mux2<=1'b1;
Mux3<=2'b1;
BEQ<=1'b1;
pstate <= s1;
pc_select <= 0;
IM_clk <= 1;
REG_clk <= 0;
ALU_clk <= 0;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
s1:begin // After Instruction Fetch Cycle
reg_wrt <= 1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux1 <= 1'b1;
Mux2 <= 1'b0;
Mux3 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s2;
pc_select <= 0;
IM_clk <= 0;
REG_clk <= 1;
ALU_clk <= 0;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
s2:begin // After REG Stage
case(opcode)
4'b0000:begin
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b0;
Mux2<=1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pc_select <= 0;
pstate<= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
4'b0001:begin /* DO NOT MODIFY R-FORMAT STARTS HERE */
//alu_op<=4'b0001; // Subtraction
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate<= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b0010:begin
//alu_op<=4'b0010; //Shift by 1 Right
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b0011:begin
//alu_op<=4'b0010; //Shift by 1 Right
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b0100:begin
//alu_op<=4'b0010; //ADD_I
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux1 <= 1'b0;
Mux2 <= 1'b1;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b0101:begin
//alu_op<=4'b0010; // SUB_I
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux1 <= 1'b0;
Mux2 <= 1'b1;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b0110:begin
//alu_op<=4'b0010; //Shift by 1 Right
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b0111:begin
//alu_op<=4'b0010; //Shift by 1 Right
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b1000:begin
//alu_op<=4'b0010; //Shift by 1 Right
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b1001:begin // BRANCH AIN == BIN BEQ
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b1;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
Mux8 <= 4'b1000;
count <= count + 1;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
pstate<=s3;
/*if (count < 3)
pstate <= s2;
else
pstate <= s5;
end*/
end
//*********************************************************************************************************************
4'b1010:begin // BRANCH AIN != BIN BNE
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b1;
BLT <= 1'b0;
BGT <= 1'b0;
Mux8 <= 4'b0100;
count <= count + 1;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
if (count < 1)
pstate <= s2;
else
pstate <= s5;
pstate<=s3;
end
//*********************************************************************************************************************
4'b1011:begin // BRANCH AIN < BIN
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b1;
BGT <= 1'b0;
Mux8 <= 4'b0010;
count <= count + 1;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
if (count < 1)
pstate <= s2;
else
pstate <= s5;
pstate<=s3;
end
//*********************************************************************************************************************
4'b1100:begin // BRANCH IF AIN > BIN
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b1;
Mux8 <= 4'b0001;
count <= count + 1;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
if (count < 1)
pstate <= s2;
else
pstate <= s5;
pstate<=s3;
end
//*********************************************************************************************************************
4'b1101:begin // BRANCH DIRECTLY
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b0;
Mux2 <= 1'b0;
BEQ <= 1'b1;
BNE <= 1'b1;
BLT <= 1'b1;
BGT <= 1'b1;
Mux8 <= 4'b1111;
count <= count + 1;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
if (count < 1)
pstate <= s2;
else
pstate <= s5;
pstate<=s3;
end
//*********************************************************************************************************************
4'b1110:begin // LOAD
reg_wrt<=1'b0;
re <= 1'b1;
wr <= 1'b0;
Mux1 <= 1'b0;
Mux2 <= 1'b1;
Mux3 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s3;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
4'b1111:begin // STORE
reg_wrt<=1'b0;
re <= 1'b0;
wr <= 1'b1;
Mux1 <= 1'b1;
Mux2 <= 1'b1;
Mux3 <= 1'b0;
BEQ <= 1'b0;
BNE <= 1'b0;
BLT <= 1'b0;
BGT <= 1'b0;
pstate <= s4;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 1;
RAM_clk <= 0;
Add_clk <= 0;
end
//*********************************************************************************************************************
endcase
end
s3:begin // After ALU Stage
reg_wrt<=1'b0;
//Mux2<=1'b0;
pstate <= s4;
IM_clk <= 0;
REG_clk <= 0;
ALU_clk <= 0;
RAM_clk <= 1;
Add_clk <= 0;
end
s4:begin // After Memory Stage
if(opcode <= 1000) begin
reg_wrt <= 1'b1;
Mux3 <= 1;
end
else
reg_wrt <= 1'b0;
re<=1'b0;
wr<=1'b0;
pc_select <= 0;
//Mux8 <= {BEQ,BNE,BLT,BGT};
pstate <= s5;
IM_clk <= 0;
REG_clk <= 1;
ALU_clk <= 0;
RAM_clk <= 0;
Add_clk <= 1;
end
s5:begin // After Write Back Cycle
reg_wrt<=1'b0;
re<=1'b0;
wr<=1'b0;
Mux3 <= 1'b0;
pstate <= s1;
pc_select <= 1;
count<=0;
IM_clk <= 1;
REG_clk <= 0;
ALU_clk <= 0;
RAM_clk <= 0;
Add_clk <= 0;
end
endcase
end
endmodule
module DATAPATH(clk, out, A_reg, B_reg, W_reg, read_data_A, read_data_B, opcode, alu_result, write_data, sel3,carry, z_flag);
input clk;
wire [15:0]instruction;
wire [7:0]sign_out;
wire [7:0]in;
wire [7:0]b_out, in_1, in_2, in_3, in_4;
output [7:0] out;
wire [3:0] Sign, Write_reg;
wire [3:0] aluop; wire [7:0] write_data; wire [7:0] read_data;
wire [7:0]read_data_A, read_data_B, mux2_out, data_out;
wire select4;
reg carry_bit;
wire sel4;
output carry, z_flag;
output [3:0] opcode;
wire [3:0] sel8;
output [7:0] alu_result;
output [3:0] A_reg, B_reg, W_reg;
output [7:0] read_data_A, read_data_B;
output [7:0] write_data;
output sel3;
always @(negedge clk)
carry_bit <= carry;
PC programcounter(in,pc_select,out);
//ADDER_PC add1(out,pc_select,increment,clk);
and clk_IMeme(clk_IM, clk, IM_clk);
and clk_Register(clk_REG, clk, REG_clk);
and clk_Random(clk_RAM, clk, RAM_clk);
and clk_Arithmetic(clk_ALU, clk, ALU_clk);
and clk_Adder(clk_ADD, clk, clk, Add_clk);
INSTRUCTION_MEMORY im(out,clk_IM,opcode,A_reg, B_reg, W_reg,Sign);
CONTROL control_unit(clk, opcode, sel1, reg_write, BEQ, BNE, BLT, BGT, sel8, read, write, aluop, sel2, sel3, pc_select, IM_clk, REG_clk, RAM_clk, ALU_clk, Add_clk);
MUX1 multiplexor1(B_reg, W_reg, sel1, Write_reg);
REGISTER_FILE register_file(clk_REG,A_reg,B_reg, Write_reg, write_data,reg_write,read_data_A,read_data_B);
MUX2 mux2(read_data_B,sign_out,sel2,mux2_out);
ALU alux(clk_ALU,read_data_A,mux2_out,aluop,alu_result,z_flag,carry);
RAM datamemory(clk_RAM,alu_result,read_data_B,data_out, read , write);
MUX3 mux3(data_out,alu_result,sel3,write_data);
SIGN xtend(Sign,sign_out);
ADDER branch(out, sign_out, b_out, clk_ADD);
//ADDER carry_branch(out, sign_out, c_out, clk);
and branch_if_zero(BEQ_1, z_flag, BEQ);
MUX4 mux4(out, b_out, BEQ_1, in_1); // BEQ
and branch_if_not_zero(BNE_1, ~z_flag, BNE);
MUX4 mux5(out, b_out, BNE_1, in_2); // BNE
and branch_if_less(BLT_1, carry, BLT);
MUX4 mux6(out, b_out, BLT_1, in_3); // BLT
and branch_if_greater(BGT_1, ~carry, BGT);
MUX4 mux7(out, b_out, BGT_1, in_4); // BGT
MUX8 mux8(out, in_1, in_2, in_3, in_4, b_out, sel8, in);
endmodule
module INSTRUCTION_MEMORY(address,clk_IM,opcode,A_reg,B_reg,W_reg,Sign);
input [7:0]address;
input clk_IM;
reg [3:0]dest;
output reg [3:0]opcode;
output reg [3:0]A_reg;
output reg [3:0]B_reg;
output reg [3:0]W_reg;
output reg [3:0]Sign;
reg [7:0] imem[0:17];
reg [15:0] instruction;
initial begin
imem[0]<=8'b1010_0011;
imem[1]<=8'b0010_0001;
imem[2]<=8'b1011_0001;
imem[3]<=8'b0010_0010;
imem[4]<=8'b0011_0100;
imem[5]<=8'b0011_0011;
imem[6]<=8'b1100_0100;
imem[7]<=8'b0011_0011;
imem[8]<=8'b0101_0111;
imem[9]<=8'b1000_0101;
imem[10]<=8'b0110_0010;
imem[11]<=8'b0001_0110;
imem[12]<=8'b0111_0001;
imem[13]<=8'b0001_0111;
imem[14]<=8'b1000_0110;
imem[15]<=8'b0001_1000;
imem[16]<=8'b1001_0001;
imem[17]<=8'b0011_0001;
end
always @(negedge clk_IM)begin
instruction = {imem[address],imem[address+1]};
opcode = instruction[15:12];
A_reg = instruction[11:8];
B_reg = instruction[7:4];
W_reg = instruction[3:0];
Sign = instruction[3:0];
end
endmodule
module MUX1(a,b,sel,c);
input [3:0] a,b;
input sel;
output reg [3:0]c;
always @(*)begin
if(sel==0)
c = a;
else
c = b;
end
endmodule
module MUX2(a,b,sel,c);
input [7:0] a,b;
input sel;
output reg [7:0]c;
always @(*)begin
if(sel==0)
c = a;
else
c = b;
end
endmodule
module MUX4(a,b,sel,c);
input [7:0] a;
input [7:0] b;
input sel;
output reg [7:0]c;
always @(*)begin
if(sel==1'b0)
c = a;
else
c = b;
end
endmodule
//Same Code for Mux3, Mux4, Mux5, Mux6.
//Create Seperate modules for each Mux and paste the above code in each.
// Mux 8 has a different code
module MUX8(a,b,c,d,f,g,sel,e);
input [7:0] a;
input [7:0] b;
input [7:0] c;
input [7:0] d;
input [7:0] f;
input [7:0] g;
input [3:0]sel;
output reg [7:0]e;
always @(*)begin
case(sel)
4'b1000:
e = b; //out
4'b0100:
e = c;
4'b0010:
e = d;
4'b0001:
e = f;
4'b1111:
e = g;
default:
e = a;
endcase
end
endmodule
module PC(in,pc_select,out);
input [7:0]in;
input pc_select;
output reg [7:0]out;
initial begin
out = 0;
end
reg [8:0]temp;
always @(posedge pc_select)begin
temp = in + 2;
out = temp[7:0];
end
endmodule
module RAM(clk_RAM,address,data_in,data_out,re,wr);
input [7:0]address;
input [7:0]data_in;
input clk_RAM,re,wr;
output reg [7:0]data_out;
reg[7:0] mem [0:30];
initial begin
mem[4]=15;
mem[7]=0;
end
always @(negedge clk_RAM)begin
if(wr)
mem[address] <= data_in;
if(re)
data_out <= mem[address];
end
/*always @(address or re)begin
if(re)begin
data = mem[address];
end
end*/
endmodule
module REGISTER_FILE(clk_REG,readA,readB,dest,data,reg_wrt,readA_out,readB_out);
input reg_wrt;
input [3:0]readA,readB,dest;
input [7:0]data;
input clk_REG;
reg [7:0] Register [0:15];
initial begin
Register[0]=0;//R0 alwayscontains zero
Register[1]=2; //Random values stored
Register[2]=4;
Register[3]=6;
Register[4]=8;
Register[5]=10; // You can change any value within this initial block
Register[6]=12;
Register[7]=14;
Register[8]=16;
end
output reg [7:0]readA_out,readB_out;
always @(negedge clk_REG)begin
readA_out <= Register[readA];
readB_out <= Register[readB];
if(reg_wrt==1)
Register[dest]<=data;
end
endmodule
module SIGN(a,b);
input [3:0]a;
output reg [7:0]b;
always @(a or b)begin
if(a[3]==1)
b = {4'b1111,a};
else
b = {4'b0000,a};
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment