├── design ├── adder.v ├── mux.v ├── mux3to1.v ├── First_register.v ├── Control_unit.v ├── registerfile.v ├── alu.v ├── alucontrol.v ├── Second_Register.v ├── datamem.v ├── immext.v ├── controlunit.v ├── Fifth_register.v ├── Fourth_register.v ├── Hazard_unit.v ├── Third_register.v ├── Risc_v_pipelined.v └── instmem.v ├── testbench └── Risc_v_pipelined_tb.v ├── LICENSE └── README.md /design/adder.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module adder(s,t,u); 3 | input [31:0] s,t; 4 | output [31:0] u; 5 | assign u = s+t; 6 | endmodule -------------------------------------------------------------------------------- /design/mux.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module mux(m,n,sel,out); 3 | input [31:0]m,n; 4 | input sel; 5 | output [31:0]out; 6 | assign out = sel ? n : m; 7 | endmodule -------------------------------------------------------------------------------- /design/mux3to1.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module mux3to1(m,n,o,sel,out); 3 | input [31:0]m,n,o; 4 | input [1:0] sel; 5 | output [31:0]out; 6 | assign out = (sel==2'b00) ? m : 7 | (sel==2'b01) ? n : 8 | (sel==2'b10) ? o : 32'bx; 9 | endmodule -------------------------------------------------------------------------------- /design/First_register.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module First_register (clk, reset, enable, PC, PCF); 3 | 4 | input clk, reset, enable; 5 | input [31:0] PC; 6 | output reg [31:0] PCF; 7 | 8 | always @ (posedge clk) 9 | begin 10 | if (reset) 11 | PCF <= 0; 12 | 13 | else if (enable) 14 | PCF <= PCF; 15 | 16 | else 17 | PCF <= PC; 18 | 19 | end 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /testbench/Risc_v_pipelined_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module Risc_v_pipelined_tb; 3 | reg clk, reset; 4 | Risc_v_pipelined dut ( 5 | .clk(clk), 6 | .reset(reset) 7 | ); 8 | initial begin 9 | clk = 0; 10 | forever #5 clk = ~clk; 11 | end 12 | initial begin 13 | reset = 1; 14 | #10 reset = 0; 15 | #100 $stop; 16 | end 17 | initial begin 18 | $monitor("Time: %0t | clk: %b | reset: %b", $time, clk, reset); 19 | end 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /design/Control_unit.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module Control_unit(opcode,funct3,funct7,alusrc,resultsrc,immsrc,regwrite,memwrite,alucontrol,branch, jump); 3 | input [6:0] opcode; 4 | input funct7; 5 | input [2:0] funct3; 6 | output [2:0] alucontrol; 7 | output [1:0] immsrc,resultsrc; 8 | output memwrite,alusrc,regwrite; 9 | output branch,jump; 10 | wire [1:0] aluop; 11 | 12 | controlunit u1(opcode,branch,jump,immsrc,resultsrc,aluop,memwrite,alusrc,regwrite); 13 | alucontrol u2(aluop,funct3,funct7,alucontrol); 14 | endmodule -------------------------------------------------------------------------------- /design/registerfile.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module registerfile(rs1,rs2,rd,writedata,regwrite,rd1,rd2,clk); 3 | input [4:0] rs1,rs2,rd; 4 | input [31:0] writedata; 5 | input regwrite,clk; 6 | output [31:0] rd1,rd2; 7 | reg [31:0] rf [31:0]; 8 | assign rd1 = rf[rs1]; 9 | assign rd2 = rf[rs2]; 10 | integer i; 11 | always @(negedge clk) 12 | if (regwrite) 13 | begin 14 | rf[rd] = writedata; 15 | end 16 | initial 17 | begin 18 | for(i=0; i<32; i=i+1) 19 | begin 20 | rf[i] = 0; 21 | end 22 | end 23 | endmodule 24 | -------------------------------------------------------------------------------- /design/alu.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module alu(a,b,aluoperation,zero,result); 3 | input [31:0] a,b; 4 | input [2:0]aluoperation; 5 | output reg zero; 6 | output reg [31:0] result; 7 | 8 | always @ (*) 9 | begin 10 | case(aluoperation) 11 | 3'b000: result=a+b; 12 | 3'b001: result=a-b; 13 | 3'b101: result=a 19 | 20 | A Hazard Unit has been implemented in this design to handle both data hazards and control hazards in the pipelined processor architecture. 21 | # Architecture 22 | We will add four registers in between the complete datapath. These registers store and track different parts of instructions as they pass through the pipeline. They make sure the instructions are properly moved through all five stages so they can execute correctly. This setup ensures the needed data is available to each stage at the right time for proper execution. 23 | ![image](https://github.com/user-attachments/assets/cbbb7163-a9d1-4dff-8df3-c15852db8c57) 24 | 25 | # RTL View: 26 | ![image](https://github.com/user-attachments/assets/95489537-a116-459d-b97e-ace88d61a31d) 27 | 28 | ## Instructions Used: 29 | * addi x1, x0, 0xA 30 | * addi x2, x0, 0x5 31 | * addi x3, x0, 0xF 32 | * add x4, x1, x2 33 | * xor x5, x4, x3 34 | * or x6, x4, x3 35 | * and x7, x5, x6 36 | * sll x8, x7, 2 37 | * srl x9, x8, 1 38 | * sw x4, 0x100(x0) 39 | * sw x5, 0x104(x0) 40 | * lw x10, 0x100(x0) 41 | * lw x11, 0x104(x0) 42 | * slt x12, x10, x11 43 | * bne x12, x0, Skip 44 | * addi x13, x0, 0xFF 45 | * sub x14, x11, x10 46 | * mul x15, x14, x3 47 | 48 | # Simulation Results 49 | ![sim1](https://github.com/user-attachments/assets/8200b374-569f-4efc-8076-6a795114cbde) 50 | ![sim2](https://github.com/user-attachments/assets/63aef183-cac5-4fe6-b8d0-a217deb7a509) 51 | ![sim3](https://github.com/user-attachments/assets/3a48fda7-7390-4266-9983-112e561da53a) 52 | ![sim5](https://github.com/user-attachments/assets/ede61faf-d743-4618-b134-3a94c966e46f) 53 | -------------------------------------------------------------------------------- /design/Risc_v_pipelined.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module Risc_v_pipelined (clk,reset); 3 | input clk, reset; 4 | wire [31:0] PCplus4F,PC, PCF,InstrF; 5 | wire [31:0] RD1D,RD2D, InstrD,PCD, PCplus4D,ImmExtD; 6 | wire [31:0] PCTargetE,RD1E, RD2E, PCE, ImmExtE,PCplus4E, SrcAE, SrcBE, Src2BE,ALUResultE; 7 | wire [31:0] PCplus4M,ALUResultM, WriteDataM,ReadDataM; 8 | wire [31:0] ResultW, PCplus4W,ALUResultW,ReadDataW; 9 | wire [4:0] rdW, rdE, rdM,rs1E,rs2E; 10 | wire [2:0] ALUControlE,ALUControlD; 11 | wire [1:0] ResultSrcE,ResultSrcD,ImmSrcD,ResultSrcM,ResultSrcW,ForwardAE,ForwardBE; 12 | wire PCSrcE,BranchE,JumpE,ALUSrcE,RegWriteE,MemWriteE,ZeroE; 13 | wire BranchD,JumpD,ALUSrcD,RegWriteD,MemWriteD; 14 | wire RegWriteM,MemWriteM; 15 | wire RegWriteW; 16 | wire StallD,StallF,FlushE,FlushD; 17 | //sub_blocks: 18 | mux PCSrc (PCplus4F,PCTargetE,PCSrcE,PC); 19 | First_register FR (clk, reset, StallF, PC, PCF); 20 | instmem IM (PCF,InstrF); 21 | adder PCplus4 (PCF,32'b100,PCplus4F); 22 | Second_Register SR (clk, reset, FlushD,StallD,InstrF,PCF,PCplus4F, InstrD, PCD, PCplus4D); 23 | Control_unit CU (InstrD[6:0],InstrD[14:12],InstrD[30],ALUSrcD,ResultSrcD,ImmSrcD,RegWriteD,MemWriteD,ALUControlD,BranchD,JumpD); 24 | registerfile RF (InstrD[19:15],InstrD[24:20],rdW,ResultW,RegWriteW,RD1D,RD2D,clk); 25 | immext Im_Ext (InstrD,ImmSrcD,ImmExtD); 26 | Third_register TR (clk, reset, FlushE,RegWriteD,MemWriteD, JumpD, BranchD, ALUSrcD, ALUControlD,ResultSrcD, ImmSrcD, InstrD[11:7], RD1D, RD2D, PCD, ImmExtD, PCplus4D, RegWriteE,MemWriteE, JumpE, BranchE, ALUSrcE, ALUControlE, ResultSrcE, rdE, RD1E, RD2E, PCE, ImmExtE, PCplus4E,InstrD[19:15],InstrD[24:20],rs1E,rs2E); 27 | mux ALUSrc (SrcBE,ImmExtE,ALUSrcE,Src2BE); 28 | adder PCplusImm (PCE,ImmExtE,PCTargetE); 29 | alu ALU (SrcAE,Src2BE,ALUControlE,ZeroE,ALUResultE); 30 | assign PCSrcE = JumpE | (BranchE & ZeroE); 31 | Fourth_register FRR (clk, reset, RegWriteM,MemWriteM, ResultSrcM, rdM, PCplus4M, RegWriteE, MemWriteE, ResultSrcE, rdE, PCplus4E, ALUResultE, SrcBE, ALUResultM, WriteDataM); 32 | datamem DM (ALUResultM,WriteDataM,clk,MemWriteM,ReadDataM); 33 | Fifth_register FIFR (clk, reset, RegWriteM, ResultSrcM, rdM, PCplus4M, RegWriteW, ResultSrcW, rdW, PCplus4W, ALUResultW, ReadDataW, ALUResultM, ReadDataM); 34 | mux3to1 resultSrc (ALUResultW,ReadDataW,PCplus4W,ResultSrcW,ResultW); 35 | Hazard_unit HU (InstrD[19:15],InstrD[24:20],rs1E,rs2E,rdM,rdW,RegWriteM,RegWriteW,rdE,ResultSrcE,PCSrcE,ForwardAE,ForwardBE,StallD,StallF,FlushE,FlushD); 36 | mux3to1 SrcA (RD1E,ResultW,ALUResultM,ForwardAE,SrcAE); 37 | mux3to1 SrcB (RD2E,ResultW,ALUResultM,ForwardBE,SrcBE); 38 | endmodule 39 | 40 | -------------------------------------------------------------------------------- /design/instmem.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | module instmem(instr_addr,instruction); 3 | input [31:0] instr_addr; 4 | output [31:0] instruction; 5 | reg[31:0] instruction; 6 | reg [7:0] ram [90:0]; 7 | initial 8 | begin 9 | ram[0] = 8'b00010011; 10 | ram[1] = 8'b00000000; 11 | ram[2] = 8'b10100000; 12 | ram[3] = 8'b00000000; 13 | 14 | ram[4] = 8'b10010011; 15 | ram[5] = 8'b00000101; 16 | ram[6] = 8'b01010000; 17 | ram[7] = 8'b00000000; 18 | 19 | ram[8] = 8'b00010011; 20 | ram[9] = 8'b00000000; 21 | ram[10] = 8'b11110000; 22 | ram[11] = 8'b00000000; 23 | 24 | ram[12] = 8'b10110011; 25 | ram[13] = 8'b10000001; 26 | ram[14] = 8'b00100000; 27 | ram[15] = 8'b00000000; 28 | 29 | ram[16] = 8'b00110011; 30 | ram[17] = 8'b10100010; 31 | ram[18] = 8'b00110001; 32 | ram[19] = 8'b00000000; 33 | 34 | ram[20] = 8'b00110011; 35 | ram[21] = 8'b10110010; 36 | ram[22] = 8'b00110001; 37 | ram[23] = 8'b00000000; 38 | 39 | ram[24] = 8'b00110011; 40 | ram[25] = 8'b10110011; 41 | ram[26] = 8'b01100010; 42 | ram[27] = 8'b00000000; 43 | 44 | ram[28] = 8'b10110011; 45 | ram[29] = 8'b10110011; 46 | ram[30] = 8'b00100011; 47 | ram[31] = 8'b00000000; 48 | 49 | ram[32] = 8'b10110011; 50 | ram[33] = 8'b11000011; 51 | ram[34] = 8'b00010011; 52 | ram[35] = 8'b00000000; 53 | 54 | ram[36] = 8'b00100011; 55 | ram[37] = 8'b00100000; 56 | ram[38] = 8'b01000001; 57 | ram[39] = 8'b00000000; 58 | 59 | ram[40] = 8'b10100011; 60 | ram[41] = 8'b00100000; 61 | ram[42] = 8'b01010001; 62 | ram[43] = 8'b00000000; 63 | 64 | ram[44] = 8'b10000011; 65 | ram[45] = 8'b00100010; 66 | ram[46] = 8'b00000001; 67 | ram[47] = 8'b00000000; 68 | 69 | ram[48] = 8'b00000011; 70 | ram[49] = 8'b00100011; 71 | ram[50] = 8'b01000001; 72 | ram[51] = 8'b00000000; 73 | 74 | ram[52] = 8'b00110011; 75 | ram[53] = 8'b01100011; 76 | ram[54] = 8'b10110010; 77 | ram[55] = 8'b00000000; 78 | 79 | ram[56] = 8'b11100011; 80 | ram[57] = 8'b00011100; 81 | ram[58] = 8'b00100010; 82 | ram[59] = 8'b11111110; 83 | 84 | ram[60] = 8'b10010011; 85 | ram[61] = 8'b00000110; 86 | ram[62] = 8'b11111111; 87 | ram[63] = 8'b00000000; 88 | 89 | ram[64] = 8'b00110011; 90 | ram[65] = 8'b01100011; 91 | ram[66] = 8'b10100011; 92 | ram[67] = 8'b01000000; 93 | 94 | ram[68] = 8'b10110011; 95 | ram[69] = 8'b11100011; 96 | ram[70] = 8'b00110011; 97 | ram[71] = 8'b00000000; 98 | 99 | end 100 | always @(instr_addr) 101 | instruction = {ram[instr_addr+3],ram[instr_addr+2],ram[instr_addr+1],ram[instr_addr]}; 102 | endmodule 103 | --------------------------------------------------------------------------------