// 5-Stage RISC-V Pipeline Processor
// Complete implementation with hazard detection and forwarding
module riscv(input logic clk, reset,
output logic [31:0] PCF,
input logic [31:0] InstrF,
output logic MemWriteM,
output logic [31:0] ALUResultM, WriteDataM,
input logic [31:0] ReadDataM);
// Pipeline control signals
logic [6:0] opD;
logic [2:0] funct3D, funct3M, funct3E;
logic funct7b5D;
logic [2:0] ImmSrcD;
logic ZeroE, NegativeE, CarryE, OverflowE;
logic PCSrcE, PCSrcNextE;
logic [3:0] ALUControlE;
logic [1:0] ALUSrcE;
logic ResultSrcEb0;
logic RegWriteM;
logic [1:0] ResultSrcW;
logic RegWriteW;
// Hazard detection and forwarding signals
logic [1:0] ForwardAE, ForwardBE;
logic StallF, StallD, FlushD, FlushE;
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW;
logic [31:0] dpReadDataM, dpWriteDataM;
// Instantiate main processor components
controller c(clk, reset,
opD, funct3D, funct3E, funct7b5D, ImmSrcD,
FlushE, ZeroE, NegativeE, CarryE, OverflowE,
PCSrcE, PCSrcNextE, ALUControlE, ALUSrcE, ResultSrcEb0,
MemWriteM, RegWriteM, RegWriteW, ResultSrcW, funct3M);
datapath dp(clk, reset,
StallF, PCF, InstrF,
opD, funct3D, funct7b5D, StallD, FlushD, ImmSrcD,
FlushE, ForwardAE, ForwardBE, PCSrcE, PCSrcNextE,
ALUControlE, ALUSrcE, ZeroE, NegativeE, CarryE, OverflowE,
MemWriteM, dpWriteDataM, ALUResultM, ReadDataM,
RegWriteW, ResultSrcW,
Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW);
hazard hu(Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
PCSrcE, PCSrcNextE, ResultSrcEb0, RegWriteM, RegWriteW,
ForwardAE, ForwardBE, StallF, StallD, FlushD, FlushE);
// Store data formatting for different store types
always_comb
case(funct3M)
3'b000: begin // Store byte (sb)
case(ALUResultM[1:0])
2'b00: WriteDataM = {ReadDataM[31:8], dpWriteDataM[7:0]};
2'b01: WriteDataM = {ReadDataM[31:16], dpWriteDataM[7:0], ReadDataM[7:0]};
2'b10: WriteDataM = {ReadDataM[31:24], dpWriteDataM[7:0], ReadDataM[15:0]};
2'b11: WriteDataM = {dpWriteDataM[7:0], ReadDataM[23:0]};
endcase
end
3'b001: begin // Store halfword (sh)
case(ALUResultM[1])
1'b0: WriteDataM = {ReadDataM[31:16], dpWriteDataM[15:0]};
1'b1: WriteDataM = {dpWriteDataM[15:0], ReadDataM[15:0]};
endcase
end
default: WriteDataM = dpWriteDataM; // Store word (sw)
endcase
endmodule
// Hazard Unit: Implements forwarding, stalling, and flushing
module hazard(input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
input logic PCSrcE, PCSrcNextE, ResultSrcEb0,
input logic RegWriteM, RegWriteW,
output logic [1:0] ForwardAE, ForwardBE,
output logic StallF, StallD, FlushD, FlushE);
logic lwStallD;
// Data forwarding logic - bypass network
always_comb begin
ForwardAE = 2'b00; // No forwarding
ForwardBE = 2'b00;
// Forward from Memory stage (EX-to-EX forwarding)
if (Rs1E != 5'b0)
if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01;
if (Rs2E != 5'b0)
if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
end
// Stall and flush control logic
assign lwStallD = ResultSrcEb0 & ((Rs1D == RdE) | (Rs2D == RdE));
assign StallD = lwStallD;
assign StallF = lwStallD;
assign FlushD = PCSrcE | PCSrcNextE;
assign FlushE = lwStallD | PCSrcE | PCSrcNextE;
endmodule