RISC V Code

 module processor (clk1, clk2);


input clk1,clk2;// Two-phase clock




reg [31:0] PC, IF_ID_IR, IF_ID_NPC;


reg [31:0] ID_EX_IR, ID_EX_NPC, ID_EX_A, ID_EX_B, ID_EX_Imm;


reg [2:0] ID_EX_type, EX_MEM_type, MEM_WB_type;


reg [31:0] EX_MEM_IR, EX_MEM_ALUOut, EX_MEM_B; 


reg EX_MEM_cond;


reg [31:0] MEM_WB_IR, MEM_WB_ALUOut, MEM_WB_LMD;


reg [31:0] Reg [0:31];// Register bank (32 x 32)


reg [31:0] Mem [0:1023];// 1024 x 32 memory



parameter ADD=6'b000000,SUB=6'b000001, AND=6'b000010, OR=6'b000011, SLT=6'b000100, MUL=6'b000101, HLT=6'b111111, LW=6'b001000, SW=6'b001001, ADDI=6'b001010, SUBI=6'b001011, SLTI=6'b001100, BNEQZ=6'b001101, BEQZ=6'b001110;



parameter RR_ALU=3'b000, RM_ALU=3'b001, LOAD=3'b010, BRANCH=3'b100, HALT=3'b101,STORE=3'b011;


reg HALTED;// Set after HLT instruction is completed (in WB stage)


reg TAKEN_BRANCH;// Required to disable instructions after branch





always @ (posedge clk1) // IF Stage


if (HALTED == 0)


begin


if (((EX_MEM_IR [31:26] ===BEQZ) & & (EX_MEM_cond == 1)) || ((EX_MEM_IR [31:26] == BNEQZ) & & (EX_MEM_cond == 0) ) ) 


begin

IF_ID_IR <= #2 Mem [EX_MEM_ALUOut];

TAKEN_BRANCH <= #2 1'b1;

IF_ID_NPC<= #2 EX_MEM_ALUOut + 1;

PC<= #2 EX_MEM_ALUOut + 1;

end


else

begin

IF_ID_IR<= #2 Mem [PC];

IF_ID_NPC<= #2 PC + 1;

PC<= #2 PC + 1;

end

end






always @(posedge clk2) // ID Stage

if (HALTED ==0)

begin

if (IF_ID_IR [25:21] ==5'b00000) ID_EX_A <= 0;

else ID_EX_A <= #2 Reg[IF_ID_IR [25:21]]; // "rs"


if (IF_ID_IR [20:16] <= 5'b00000) ID_EX_B <= 0;

else ID_EX_B<=#2 Reg [IF_ID_IR [20:16]]; // "rt"


ID_EX_NPC<=#2 IF_ID_NPC;

ID_EX_IR <=#2 IF_ID_IR;

ID_EX_Imm<=#2 {{16{IF_ID_IR [15]} }, {IF_ID_IR[15:0] } }; //sign extension, replicate sign bit 16 times and concatenate




case (IF_ID_IR [31:26])

ADD, SUB, AND, OR, SLT, MUL: ID_EX_type <= #2 RR_ALU;//reg - reg

ADDI, SUBI, SLTI:ID_EX_type <= #2 RM_ALU;//

 LW:ID_EX_type <= #2 LOAD;

 SW: ID_EX_type<= #2 STORE;

BNEQZ, BEQZ:ID_EX_type <= #2 BRANCH;

 HLT:ID_EX_type <= #2 HALT;

default:ID_EX_type <= #2 HALT;// Invalid opcode

endcase


end



always @ (posedge clk1)// EX Stage

if (HALTED == 0)

begin

EX_MEM_type <= #2 ID_EX_type;

EX_MEM_IR <= #2 ID_EX_IR;

TAKEN_BRANCH <= #2 0;

case (ID_EX_type)


  RR_ALU: begin

    case (ID_EX_IR [31:26]) // "opcode"

    ADD: EX_MEM_ALUOut <= #2 ID_EX_A + ID_EX_B;

    SUB:EX_MEM_ALUOut  <= #2 ID_EX_A - ID_EX_B;

    AND:EX_MEM_ALUOut  <= #2 ID_EX_A & ID_EX_B;

    OR:EX_MEM_ALUOut  <= #2 ID_EX_A | ID_EX_B;

    SLT:EX_MEM_ALUOut  <= #2 ID_EX_A <ID_EX_B;

    MUL:EX_MEM_ALUOut <= #2 ID_EX_A * ID_EX_B;

    default:EX_MEM_ALUOut <=#2 32'hxxxxxxxx;

    endcase

    end



  RM_ALU:

    begin

    case(ID_EX_IR [31:26]) //"opcode"

    ADDI:EX_MEM_ALUOut <= #2 ID_EX_A + ID_EX_Imm;

    SUBI:EX_MEM_ALUOut <= #2 ID_EX_A - ID_EX_Imm;

    SLTI:EX_MEM_ALUOut <= #2 ID_EX_A < ID_EX_Imm;

    default:EX_MEM_ALUOut <= #2 32'hxxxxxxxx;

    endcase

    end

    

    LOAD, STORE: begin    

    EX_MEM_ALUOut <= #2 ID_EX_A+ID_EX_Imm;    

    EX_MEM_B<= #2 ID_EX_B;   

    end

    

    BRANCH: begin    

    EX_MEM_ALUOut <= #2 ID_EX_NPC + ID_EX_Imm;    

    EX_MEM_cond<= #2 (ID_EX_A==0);    

    end   

    endcase    

    end





always @ (posedge clk2)// MEM stage

if(HALTED==0)

begin

MEM_WB_type <= #2 EX_MEM_type; 

MEM_WB_IR <= #2 EX_MEM_IR;

case (EX_MEM_type)

RR_ALU, RM_ALU:


MEM_WB_ALUOut<= #2 EX_MEM_ALUOut;


 LOAD:MEM_WB_LMD<= #2 Mem [EX_MEM_ALUOut];


 STORE:if (TAKEN_BRANCH ==0)// Disable write

  Mem [EX_MEM_ALUOut]<= #2 EX_MEM_B;


endcase


end



always @ (posedge clk1)// WB Stage

begin

if(TAKEN_BRANCH==0)// Disable write if branch taken

case (MEM_WB_type)

 RR_ALU: Reg [MEM_WB_IR [15:11]]<= #2 MEM_WB_ALUOut; // "rd"

 RM_ALU: Reg [MEM_WB_IR [20:16]]<= #2 MEM_WB_ALUOut; // "rt"

 LOAD: Reg [MEM_WB_IR [20:16]]<= #2 MEM_WB_LMD;// "rt"

 HALT: HALTED <= #2 1'b1;

endcase


end


endmodule




module proc_tb_application_1();


reg clk1,clk2;

integer k;


processor processor_i1 (clk1, clk2);

initial begin

clk1=0;clk2=0;

repeat(20)

begin

#5 clk1=1;#5 clk1=0;

#5 clk2=1;#5 clk2=0;

end

end


initial

begin

for (k=0; k<31; k=k+1)


processor_i1.Reg[k] <= k;

processor_i1.Mem[0] = 32'h2801000a;

processor_i1.Mem[1] = 32'h28020014;

processor_i1.Mem[2] = 32'h28030019;

processor_i1.Mem[3] = 32'h0ce77800;

processor_i1.Mem[4] = 32'h0ce77800;

processor_i1.Mem[5] = 32'h00222000;

processor_i1.Mem[6] = 32'h0ce77800;

processor_i1.Mem[7] = 32'h00832800;

processor_i1.Mem[8] = 32'hfc000000;

processor_i1.HALTED=0;

processor_i1.PC=0;

processor_i1.TAKEN_BRANCH=0;


end


endmodule




module proc_tb_application_2();


reg clk1,clk2;

integer k;


processor processor_i1 (clk1, clk2);

initial begin

clk1=0;clk2=0;

repeat(100)

begin

#5 clk1=1;#5 clk1=0;

#5 clk2=1;#5 clk2=0;

end

end

initial


begin


for (k=0; k<31; k=k+1)


processor_i1.Reg [k] =k;


processor_i1.Mem [0]=32'h280a00c8; 

processor_i1.Mem [1]=32'h28020001;

processor_i1.Mem [2]=32'h0e94a000;

processor_i1.Mem [3]=32'h21430000;

processor_i1.Mem [4]=32'h0e94a000;

processor_i1.Mem [5]=32'h14431000;

processor_i1.Mem [6]=32'h2c630001;

processor_i1.Mem [7]=32'h0e94a000;

processor_i1.Mem [8]=32'h3460fffc;

processor_i1.Mem [9]=32'h2542fffe;

processor_i1.Mem [10]=32'hfc000000;

processor_i1.Mem[200]=7; //to calculate factorial of 7

processor_i1.HALTED=0;

processor_i1.PC=0;

processor_i1.TAKEN_BRANCH=0;

end

initial begin

$monitor("R2 : %4d",processor_i1.Reg[2]);

end


endmodule






Comments

Popular posts from this blog

Sum of Even Numbers till N

Find the Runner-Up Score!

Print All Substrings