//**************************************ALU*************************************************************************** module ALU(ain,bin,func,result,z); input [7:0]ain; input [7:0]bin; output reg[7:0]result; reg carry,temp=0; input [3:0]func; output reg z; //wire [7:0]result; //assign n = result[7]; always @(ain or bin)begin if(func==4'b0000)begin {temp,result} = ain + bin; carry = temp; if(result==0) z=1; end else if(func==4'b0001)begin {temp,result} = ain - bin; carry = temp; if(result==0) z=1; end else if(func==4'b0010)begin {temp,result} = ain + 1; carry = temp; if(result==0) z=1; end else if(func==4'b0011)begin {temp,result} = ain - 1; carry = temp; if(result==0) z=1; end else if(func==4'b0100)begin result = ain | bin; carry = 0; if(result==0) z=1;end //OR else if(func==4'b0101)begin result = ain & bin; carry = 0; if(result==0) z=1;end //AND else if(func==4'b0110)begin result = ain^bin; carry = 0; if(result==0) z=1;end //XOR else if(func==4'b0111)begin 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;end //NAND else if(func==4'b1000)begin 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;end //NOT else if(func==4'b1001)begin result = ain<<1; carry = 0; if(result==0) z=1;end //Shift Left else if(func==4'b1010)begin result = ain>>1; carry = 0; if(result==0) z=1;end //Shift Right else begin result = 4'bxxxx; carry = 0; end //Default if(result==0) z = 1'b1; else z = 0; end endmodule //*******************************INSTRUCTION MEMORY******************************************************************** module instruction(address,clk,opcode,jump,jiz,addA,addB,write_add,iformat,im_select); input [15:0]address; input clk,im_select; output reg[3:0]opcode; output reg[11:0] jump; output reg[7:0] jiz; output reg[3:0] addA; output reg[3:0] addB; output reg[3:0] write_add; output reg[3:0] iformat; reg [3:0]dest; reg [15:0]instruction; reg [15:0] imem[0:15]; initial begin imem[2]<=16'b1111_0000_0000_0101; //ADD imem[1]<=16'b0001_0010_0011_0011; //SUB imem[3]<=16'b0010_0100_0010_0011; imem[0]<=16'b0010_0000_0000_0101; imem[4]<=16'b0010_0111_0010_0011; imem[5]<=16'b0011_0010_0011_0010; imem[6]<=16'b0110_0001_0001_0011; imem[7]<=16'b0001_0110_0001_0011; imem[8]<=16'b0110_0001_0011_0001; end always @(im_select)begin if(im_select==1)begin dest=write_add; instruction = imem[address]; opcode = instruction[15:12]; jump = instruction[11:0]; jiz = instruction[7:0]; addA = instruction[11:8]; addB = instruction[7:4]; write_add = instruction[3:0]; iformat = instruction[3:0]; end end endmodule //********************************REGISTER FILE************************************************************************* module Register(reg_wrt,readA,clk,readB,dest,data,readA_out,readB_out); input reg_wrt; input [3:0]readA,readB,dest; input [7:0]data; input clk; reg [7:0] Register [0:15]; initial begin Register[0]=0;//R0 alwayscontains zero Register[1]=2; Register[2]=4; Register[3]=6; Register[4]=8; Register[5]=10; Register[6]=12; Register[7]=14; end output reg [7:0]readA_out,readB_out; always @(posedge clk)begin readA_out <= Register[readA]; readB_out <= Register[readB]; if(reg_wrt==1) Register[dest]=data; end endmodule //********************************DATA MEMORY************************************************************************** module RAM(address,clk,data_in,data_out,re,wr); input [7:0]address; input [7:0]data_in; input clk,re,wr; output [7:0]data_out; reg[7:0] mem [0:30]; reg[7:0] data; assign data_out = data; initial mem[16]=25; always @(posedge clk)begin if(wr)begin mem[address] = data_in; end end always @(address or re)begin if(re)begin data = mem[address]; end end endmodule //*******************************PROGRAM COUNTER************************************************************************ module PC(in,clk,out,pc_sel,reset); input [15:0]in; input clk,reset,pc_sel; output reg[15:0]out; initial out = 0; always @(posedge clk)begin if(reset==1) out <= 16'bx; else if(pc_sel==1 && in<50) out <= in+1; else if(pc_sel==0) out <= in; end endmodule //*********************************MULTIPLEXERS************************************************************************* 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==2'b0) c = a; else if(sel==2'b01) c = b; else if(sel==2'b10) c = 8'b0; end endmodule module Mux3(a,b,sel,c); input [15:0] a,b; input sel; output reg [15:0]c; always @(*)begin if(sel==0) c = a; else c = b; end endmodule //***********************************SIGN EXTEND************************************************************************ 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 //***********************************LATCH***************************************************************************** module lat(in,out,clk); input [7:0] in; input clk; output reg[7:0] out; reg [7:0]memdataout; always @ (posedge clk) out=in; endmodule //**************************************DATAPATH*********************************************************************** module datapath(alu_op,opcode,clk,carry,sel1,sel2,sel3,sel5,sel6,j,re,wr,reg_wrt,reset,pc_sel,im_select,branch); input clk; output carry; input sel1,sel3,sel5,sel6,j,re,wr; input [1:0]sel2; input reg_wrt; input reset; output [3:0]opcode; input [3:0]alu_op; input im_select; input branch,pc_sel; wire [15:0] op3,out,pc_out,next_pc,next_alu_out,jump_add,new_jump,jizx; wire [11:0] jump; and (sel4,branch,zero); and (sel7,j,zero); Mux3 multi7(jump_add,jizx,sel7,new_jump); wire [3:0]iformat,addA,addB,write_add,out1; wire [7:0]shift,data_out,result,regData,aluMux,dataA,dataB,xtended,out2,latchout,jiz; Mux2 alu(dataA,8'bx,sel5,aluMux); PC programcounter(op3,clk,pc_out,pc_sel,reset); instruction im(pc_out,clk,opcode,jump,jiz,addA,addB,write_add,iformat,pc_sel); Mux1 multi1(addB,write_add,sel1,out1); Register regfile(reg_wrt,addA,clk,addB,out1,regData,dataA,dataB); sign xtend(iformat,xtended); lat latch(xtended,latchout,clk); Mux2 multi2(dataB,latchout,sel2,out2); ALU alux(aluMux,out2,alu_op,result,zero); RAM datamemory(result,clk,dataB,data_out,re,wr); Mux2 multi3(result,data_out,sel3,regData); //assign next_pc = pc_out+1'b1; assign next_alu_out = latchout + pc_out; assign jump_add = {pc_out[15:12],jump}; assign jizx = {pc_out[15:8],jiz}; Mux3 multi4(pc_out,next_alu_out,sel4,out); Mux3 multi5(new_jump,out,sel6,op3); endmodule //*********************************CONTROL UNIT************************************************************************* module control(alu_op,opcode,clk,carry,reset,reg_wrt,re,wr,Mux1,Mux2,Mux3,MuxAlu,Mux5,jiz,branch,pc_sel,im_select); input clk,carry,reset; input [3:0] opcode; output reg[3:0]alu_op; output reg reg_wrt,re,wr,jiz,Mux1,Mux3,MuxAlu,Mux5,branch,pc_sel,im_select; output reg[1:0]Mux2; reg [3:0]pstate,nstate; parameter s0 = 4'b0000,s1 = 4'b0001, s2=4'b0010, s3=4'b0011, s4=4'b0100, s5=4'b0101, s6=4'b0110, s7=4'b0111, s11=4'b1000; initial pstate = s0; always @(posedge clk)begin case(pstate) //********************************************************************************************************************* s0:begin //DO NOT MODIFY INSTRUCTION FETCH // reg_wrt<=1'b0; re<=1'b0; wr<=1'b0; Mux1<=1'b0; Mux2<=1'b1; Mux3<=1'b0; Mux3<=1'b1; Mux5<=1'b1; alu_op<=4'bxxxx; MuxAlu<=1'b1; branch<=1'b0; jiz=0; pc_sel<=1'b1; im_select<=1'b1; pstate<=s1; end //********************************************************************************************************************* s1:begin // DO NOT MODIFY DECODE STAGE // case(opcode) 4'b0000:begin alu_op<=4'b0; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=1'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b0001:begin /* DO NOT MODIFY R-FORMAT STARTS HERE */ alu_op<=4'b0001; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b0010:begin alu_op<=4'b0010; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b0011:begin alu_op<=4'b0011; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b0100:begin alu_op<=4'b0100; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b0101:begin alu_op<=4'b0101; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b0110:begin alu_op<=4'b0110; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b0111:begin alu_op<=4'b0111; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //********************************************************************************************************************* 4'b1000:begin alu_op<=4'b1000; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b0; pstate<=s0; end //********************************************************************************************************************* 4'b1001:begin alu_op<=4'b1001; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b0; pstate<=s0; end //********************************************************************************************************************* 4'b1010:begin alu_op<=4'b1010; reg_wrt<=1'b1; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b0; pstate<=s0; end /* DO NOT MODIFY R-FORMAT ENDS HERE */ //********************************************************************************************************************* 4'b1011:begin /*DO NOT MODIFY--I FORMAT STARTS HERE--LOAD*/ alu_op<=4'b0; reg_wrt<=1'b1; re<=1'b1; wr<=1'b0; Mux1<=1'b0; Mux2<=2'b01; Mux3<=1'b1; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end //******************************************************************************************************************** 4'b1100:begin /*DO NOT MODIFY--I FORMAT--STORE*/ alu_op<=4'b0; reg_wrt<=1'b0; re<=1'b0; wr<=1'b1; Mux1<=1'b1; Mux2<=2'b01; Mux3<=1'b1; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end /* DO NOT MODIFY--I FORMAT ENDS HERE */ //******************************************************************************************************************** 4'b1101:begin /* DO NOT MODIFY -- BEQ */ alu_op<=4'b0001; reg_wrt<=1'b0; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b0; Mux3<=1'b0; Mux5<=1'b1; MuxAlu<=1'b0; branch<=1'b1; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end /* DO NOT MODIFY -- BEQ */ //******************************************************************************************************************* 4'b1110:begin /* DO NOT MODIFY -- JMP */ alu_op<=4'b1110; reg_wrt<=1'b0; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b10; Mux3<=1'b0; Mux5<=1'b0; MuxAlu<=1'b0; branch<=1'b0; jiz=0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end 4'b1111:begin /* DO NOT MODIFY -- JIZ */ alu_op<=4'b0100; reg_wrt<=1'b0; re<=1'b0; wr<=1'b0; Mux1<=1'b1; Mux2<=2'b10; Mux3<=1'b0; Mux5<=1'b0; jiz = 1'b1; MuxAlu<=1'b0; branch<=1'b0; pc_sel<=1'b0; im_select<=1'b1; pstate<=s0; end endcase end endcase end endmodule //RISC TOP module risc(clk,reset); input clk,reset; wire [3:0]opcode; wire [3:0]alu_op; wire [2:0] alu_sel; wire [1:0] opb_sel,data_sel; wire [15:0] outA; wire [1:0]sel2; wire carry,reset,reg_wrt,re,wr,Mux1,Mux2,Mux3,branch,im_wrt,sel1,sel3; control control_path(alu_op,opcode,clk,carry,reset,reg_wrt,re,wr,sel1,sel2,sel3,sel5,sel6,jiz,branch,pc_sel,im_select); datapath data_path(alu_op,opcode,clk,carry,sel1,sel2,sel3,sel5,sel6,jiz,re,wr,reg_wrt,reset,pc_sel,im_select,branch); endmodule