Added MUL

This commit is contained in:
David Harris 2021-02-15 22:27:35 -05:00
parent f00728448a
commit 8dec69c2ce
11 changed files with 163 additions and 66 deletions

View File

@ -27,7 +27,7 @@
// RV32 or RV64: XLEN = 32 or 64 // RV32 or RV64: XLEN = 32 or 64
`define XLEN 32 `define XLEN 32
`define MISA (32'h00000104) `define MISA (32'h00000104 | 1 << 12)
`define A_SUPPORTED ((`MISA >> 0) % 2 == 1) `define A_SUPPORTED ((`MISA >> 0) % 2 == 1)
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1) `define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1) `define D_SUPPORTED ((`MISA >> 3) % 2 == 1)

View File

@ -28,7 +28,7 @@
`define XLEN 64 `define XLEN 64
//`define MISA (32'h00000104) //`define MISA (32'h00000104)
`define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20) `define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12)
`define A_SUPPORTED ((`MISA >> 0) % 2 == 1) `define A_SUPPORTED ((`MISA >> 0) % 2 == 1)
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1) `define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1) `define D_SUPPORTED ((`MISA >> 3) % 2 == 1)

View File

@ -51,4 +51,12 @@ module mux4 #(parameter WIDTH = 8) (
assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0); assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0);
endmodule endmodule
module mux5 #(parameter WIDTH = 8) (
input logic [WIDTH-1:0] d0, d1, d2, d3, d4,
input logic [2:0] s,
output logic [WIDTH-1:0] y);
assign y = s[2] ? d4 : (s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0));
endmodule
/* verilator lint_on DECLFILENAME */ /* verilator lint_on DECLFILENAME */

View File

@ -31,7 +31,7 @@ module hazard(
// input logic MemReadE, // input logic MemReadE,
// input logic RegWriteM, RegWriteW, // input logic RegWriteM, RegWriteW,
input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM, input logic PCSrcE, CSRWritePendingDEM, RetM, TrapM,
input logic LoadStallD, input logic LoadStallD, MulDivStallD,
input logic InstrStall, DataStall, input logic InstrStall, DataStall,
// Stall outputs // Stall outputs
output logic StallF, StallD, FlushD, FlushE, FlushM, FlushW output logic StallF, StallD, FlushD, FlushE, FlushM, FlushW
@ -54,7 +54,7 @@ module hazard(
assign BranchFlushDE = PCSrcE | RetM | TrapM; assign BranchFlushDE = PCSrcE | RetM | TrapM;
assign StallDCause = LoadStallD; assign StallDCause = LoadStallD | MulDivStallD;
assign StallFCause = InstrStall | CSRWritePendingDEM; assign StallFCause = InstrStall | CSRWritePendingDEM;
assign StallWCause = DataStall; // *** not yet used assign StallWCause = DataStall; // *** not yet used

View File

@ -29,21 +29,23 @@
module controller( module controller(
input logic clk, reset, input logic clk, reset,
// Decode stage control signals // Decode stage control signals
input logic [6:0] OpD, input logic [6:0] OpD,
input logic [2:0] Funct3D, input logic [2:0] Funct3D,
input logic Funct7b5D, input logic [6:0] Funct7D,
output logic [2:0] ImmSrcD, output logic [2:0] ImmSrcD,
input logic StallD, FlushD, input logic StallD, FlushD,
input logic IllegalIEUInstrFaultD, input logic IllegalIEUInstrFaultD,
output logic IllegalBaseInstrFaultD, output logic IllegalBaseInstrFaultD,
// Execute stage control signals // Execute stage control signals
input logic FlushE, input logic FlushE,
input logic [2:0] FlagsE, input logic [2:0] FlagsE,
output logic PCSrcE, // for datapath and Hazard Unit output logic PCSrcE, // for datapath and Hazard Unit
output logic [4:0] ALUControlE, output logic [4:0] ALUControlE,
output logic ALUSrcAE, ALUSrcBE, output logic ALUSrcAE, ALUSrcBE,
output logic TargetSrcE, output logic TargetSrcE,
output logic MemReadE, // for Hazard Unit output logic MemReadE, // for Hazard Unit
output logic [2:0] Funct3E,
output logic MulDivE, W64E,
// Memory stage control signals // Memory stage control signals
input logic FlushM, input logic FlushM,
input logic DataMisalignedM, input logic DataMisalignedM,
@ -54,7 +56,7 @@ module controller(
// Writeback stage control signals // Writeback stage control signals
input logic FlushW, input logic FlushW,
output logic RegWriteW, // for datapath and Hazard Unit output logic RegWriteW, // for datapath and Hazard Unit
output logic [1:0] ResultSrcW, output logic [2:0] ResultSrcW,
output logic InstrValidW, output logic InstrValidW,
// Stall during CSRs // Stall during CSRs
output logic CSRWritePendingDEM output logic CSRWritePendingDEM
@ -62,19 +64,18 @@ module controller(
// pipelined control signals // pipelined control signals
logic RegWriteD, RegWriteE; logic RegWriteD, RegWriteE;
logic [1:0] ResultSrcD, ResultSrcE, ResultSrcM; logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM;
logic [1:0] MemRWD, MemRWE; logic [1:0] MemRWD, MemRWE;
logic JumpD, JumpE; logic JumpD, JumpE;
logic BranchD, BranchE; logic BranchD, BranchE;
logic [1:0] ALUOpD; logic [1:0] ALUOpD;
logic [4:0] ALUControlD; logic [4:0] ALUControlD;
logic ALUSrcAD, ALUSrcBD; logic ALUSrcAD, ALUSrcBD;
logic TargetSrcD, W64D; logic TargetSrcD, W64D, MulDivD;
logic CSRWriteD, CSRWriteE; logic CSRWriteD, CSRWriteE;
logic [2:0] Funct3E;
logic InstrValidE, InstrValidM; logic InstrValidE, InstrValidM;
logic PrivilegedD, PrivilegedE; logic PrivilegedD, PrivilegedE;
logic [18:0] ControlsD; logic [20:0] ControlsD;
logic aluc3D; logic aluc3D;
logic subD, sraD, sltD, sltuD; logic subD, sraD, sltD, sltuD;
logic BranchTakenE; logic BranchTakenE;
@ -84,42 +85,57 @@ module controller(
// Main Instruction Decoder // Main Instruction Decoder
// *** decoding of non-IEU instructions should also go here, and should be gated by MISA bits in a generate so // *** decoding of non-IEU instructions should also go here, and should be gated by MISA bits in a generate so
// they don't get generated if that mode is disabled // they don't get generated if that mode is disabled
always_comb generate
case(OpD) always_comb
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRWrite_Privileged_Illegal case(OpD)
7'b0000011: ControlsD = 19'b1_000_01_10_01_0_00_0_0_0_0_0_0; // lw // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRWrite_Privileged_MulDiv_Illegal
7'b0100011: ControlsD = 19'b0_001_01_01_00_0_00_0_0_0_0_0_0; // sw 7'b0000011: ControlsD = 21'b1_000_01_10_001_0_00_0_0_0_0_0_0_0; // lw
7'b0110011: ControlsD = 19'b1_000_00_00_00_0_10_0_0_0_0_0_0; // R-type 7'b0100011: ControlsD = 21'b0_001_01_01_000_0_00_0_0_0_0_0_0_0; // sw
7'b0111011: ControlsD = 19'b1_000_00_00_00_0_10_0_0_1_0_0_0; // R-type W instructions for RV64i 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000)
7'b1100011: ControlsD = 19'b0_010_00_00_00_1_01_0_0_0_0_0_0; // beq ControlsD = 21'b1_000_00_00_000_0_10_0_0_0_0_0_0_0; // R-type
7'b0010011: ControlsD = 19'b1_000_01_00_00_0_10_0_0_0_0_0_0; // I-type ALU else if (Funct7D == 7'b0000001 && `M_SUPPORTED)
7'b0011011: ControlsD = 19'b1_000_01_00_00_0_10_0_0_1_0_0_0; // IW-type ALU for RV64i ControlsD = 21'b1_000_00_00_100_0_00_0_0_0_0_0_1_0; // Multiply/Divide
7'b1101111: ControlsD = 19'b1_011_00_00_10_0_00_1_0_0_0_0_0; // jal else
7'b1100111: ControlsD = 19'b1_000_00_00_10_0_00_1_1_0_0_0_0; // jalr ControlsD = 21'b0_000_00_00_000_0_00_0_0_0_0_0_0_1; // non-implemented instruction
7'b0010111: ControlsD = 19'b1_100_11_00_00_0_00_0_0_0_0_0_0; // auipc 7'b0111011: if ((Funct7D == 7'b0000000 || Funct7D == 7'b0100000) && `XLEN == 64)
7'b0110111: ControlsD = 19'b1_100_01_00_00_0_11_0_0_0_0_0_0; // lui ControlsD = 21'b1_000_00_00_000_0_10_0_0_1_0_0_0_0; // R-type W instructions for RV64i
7'b0001111: ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_0_0; // fence = nop else if (Funct7D == 7'b0000001 && `M_SUPPORTED && `XLEN == 64)
7'b1110011: if (Funct3D == 3'b000) ControlsD = 21'b1_000_00_00_100_0_00_0_0_1_0_0_1_0; // Multiply/Divide
ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_1_0; // privileged; decoded further in priveleged modules else
else ControlsD = 21'b0_000_00_00_000_0_00_0_0_0_0_0_0_1; // non-implemented instruction
ControlsD = 19'b1_000_00_00_11_0_00_0_0_0_1_0_0; // csrs 7'b1100011: ControlsD = 21'b0_010_00_00_000_1_01_0_0_0_0_0_0_0; // beq
7'b0000000: ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_0_1; // illegal instruction 7'b0010011: ControlsD = 21'b1_000_01_00_000_0_10_0_0_0_0_0_0_0; // I-type ALU
default: ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_0_1; // non-implemented instruction 7'b0011011: if (`XLEN == 64)
endcase ControlsD = 21'b1_000_01_00_000_0_10_0_0_1_0_0_0_0; // IW-type ALU for RV64i
else
ControlsD = 21'b0_000_00_00_000_0_00_0_0_0_0_0_0_1; // non-implemented instruction
7'b1101111: ControlsD = 21'b1_011_00_00_010_0_00_1_0_0_0_0_0_0; // jal
7'b1100111: ControlsD = 21'b1_000_00_00_010_0_00_1_1_0_0_0_0_0; // jalr
7'b0010111: ControlsD = 21'b1_100_11_00_000_0_00_0_0_0_0_0_0_0; // auipc
7'b0110111: ControlsD = 21'b1_100_01_00_000_0_11_0_0_0_0_0_0_0; // lui
7'b0001111: ControlsD = 21'b0_000_00_00_000_0_00_0_0_0_0_0_0_0; // fence = nop
7'b1110011: if (Funct3D == 3'b000)
ControlsD = 21'b0_000_00_00_000_0_00_0_0_0_0_1_0_0; // privileged; decoded further in priveleged modules
else
ControlsD = 21'b1_000_00_00_011_0_00_0_0_0_1_0_0_0; // csrs
7'b0000000: ControlsD = 21'b0_000_00_00_000_0_00_0_0_0_0_0_0_1; // illegal instruction
default: ControlsD = 21'b0_000_00_00_000_0_00_0_0_0_0_0_0_1; // non-implemented instruction
endcase
endgenerate
// unswizzle control bits // unswizzle control bits
// squash control signals if coming from an illegal compressed instruction // squash control signals if coming from an illegal compressed instruction
assign IllegalBaseInstrFaultD = ControlsD[0]; assign IllegalBaseInstrFaultD = ControlsD[0];
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD, assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD, ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD,
PrivilegedD} = ControlsD[18:1] & ~IllegalIEUInstrFaultD; PrivilegedD, MulDivD} = ControlsD[20:1] & ~IllegalIEUInstrFaultD;
// *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions // *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions
// ALU Decoding // ALU Decoding *** should move to ALU for better modularity
assign sltD = (Funct3D == 3'b010); assign sltD = (Funct3D == 3'b010);
assign sltuD = (Funct3D == 3'b011); assign sltuD = (Funct3D == 3'b011);
assign subD = (Funct3D == 3'b000 & Funct7b5D & OpD[5]); assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]);
assign sraD = (Funct3D == 3'b101 & Funct7b5D); assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
assign aluc3D = subD | sraD | sltD | sltuD; // TRUE for R-type subtracts and sra, slt, sltu assign aluc3D = subD | sraD | sltD | sltuD; // TRUE for R-type subtracts and sra, slt, sltu
@ -132,9 +148,9 @@ module controller(
endcase endcase
// Execute stage pipeline control register and logic // Execute stage pipeline control register and logic
floprc #(21) controlregE(clk, reset, FlushE, floprc #(24) controlregE(clk, reset, FlushE,
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRWriteD, PrivilegedD, Funct3D, 1'b1}, {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, 1'b1},
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRWriteE, PrivilegedE, Funct3E, InstrValidE}); {RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, InstrValidE});
// Branch Logic // Branch Logic
assign {zeroE, ltE, ltuE} = FlagsE; assign {zeroE, ltE, ltuE} = FlagsE;
@ -155,12 +171,12 @@ module controller(
assign MemReadE = MemRWE[1]; assign MemReadE = MemRWE[1];
// Memory stage pipeline control register // Memory stage pipeline control register
floprc #(11) controlregM(clk, reset, FlushM, floprc #(12) controlregM(clk, reset, FlushM,
{RegWriteE, ResultSrcE, MemRWE, CSRWriteE, PrivilegedE, Funct3E, InstrValidE}, {RegWriteE, ResultSrcE, MemRWE, CSRWriteE, PrivilegedE, Funct3E, InstrValidE},
{RegWriteM, ResultSrcM, MemRWM, CSRWriteM, PrivilegedM, Funct3M, InstrValidM}); {RegWriteM, ResultSrcM, MemRWM, CSRWriteM, PrivilegedM, Funct3M, InstrValidM});
// Writeback stage pipeline control register // Writeback stage pipeline control register
floprc #(4) controlregW(clk, reset, FlushW, floprc #(5) controlregW(clk, reset, FlushW,
{RegWriteM, ResultSrcM, InstrValidM}, {RegWriteM, ResultSrcM, InstrValidM},
{RegWriteW, ResultSrcW, InstrValidW}); {RegWriteW, ResultSrcW, InstrValidW});

View File

@ -41,19 +41,19 @@ module datapath (
input logic [`XLEN-1:0] PCE, input logic [`XLEN-1:0] PCE,
output logic [2:0] FlagsE, output logic [2:0] FlagsE,
output logic [`XLEN-1:0] PCTargetE, output logic [`XLEN-1:0] PCTargetE,
output logic [`XLEN-1:0] SrcAE, SrcBE,
// Memory stage signals // Memory stage signals
input logic FlushM, input logic FlushM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [`XLEN-1:0] CSRReadValW,
input logic [`XLEN-1:0] ReadDataW,
input logic RetM, TrapM, input logic RetM, TrapM,
output logic [`XLEN-1:0] SrcAM, output logic [`XLEN-1:0] SrcAM,
output logic [`XLEN-1:0] WriteDataM, MemAdrM, output logic [`XLEN-1:0] WriteDataM, MemAdrM,
// Writeback stage signals // Writeback stage signals
input logic FlushW, input logic FlushW,
input logic RegWriteW, input logic RegWriteW,
input logic [1:0] ResultSrcW, input logic [2:0] ResultSrcW,
input logic [`XLEN-1:0] PCLinkW, input logic [`XLEN-1:0] PCLinkW,
input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW,
// Hazard Unit signals // Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
output logic [4:0] RdE, RdM, RdW output logic [4:0] RdE, RdM, RdW
@ -67,7 +67,7 @@ module datapath (
// Execute stage signals // Execute stage signals
logic [`XLEN-1:0] RD1E, RD2E; logic [`XLEN-1:0] RD1E, RD2E;
logic [`XLEN-1:0] ExtImmE; logic [`XLEN-1:0] ExtImmE;
logic [`XLEN-1:0] PreSrcAE, SrcAE, SrcBE; logic [`XLEN-1:0] PreSrcAE;
logic [`XLEN-1:0] ALUResultE; logic [`XLEN-1:0] ALUResultE;
logic [`XLEN-1:0] WriteDataE; logic [`XLEN-1:0] WriteDataE;
logic [`XLEN-1:0] TargetBaseE; logic [`XLEN-1:0] TargetBaseE;
@ -111,5 +111,5 @@ module datapath (
floprc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ALUResultM, ALUResultW); floprc #(`XLEN) ALUResultWReg(clk, reset, FlushW, ALUResultM, ALUResultW);
floprc #(5) RdWEg(clk, reset, FlushW, RdM, RdW); floprc #(5) RdWEg(clk, reset, FlushW, RdM, RdW);
mux4 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, ResultSrcW, ResultW); mux5 #(`XLEN) resultmux(ALUResultW, ReadDataW, PCLinkW, CSRReadValW, MulDivResultW, ResultSrcW, ResultW);
endmodule endmodule

View File

@ -28,11 +28,11 @@
module forward( module forward(
// Detect hazards // Detect hazards
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
input logic MemReadE, input logic MemReadE, MulDivE,
input logic RegWriteM, RegWriteW, input logic RegWriteM, RegWriteW,
// Forwaring controls // Forwaring controls
output logic [1:0] ForwardAE, ForwardBE, output logic [1:0] ForwardAE, ForwardBE,
output logic LoadStallD output logic LoadStallD, MulDivStallD
); );
always_comb begin always_comb begin
@ -48,5 +48,6 @@ module forward(
end end
assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE)); assign LoadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE));
assign MulDivStallD = MulDivE & & ((Rs1D == RdE) | (Rs2D == RdE)); // *** extend with stalls for divide
endmodule endmodule

View File

@ -34,6 +34,9 @@ module ieu (
// Execute Stage interface // Execute Stage interface
input logic [`XLEN-1:0] PCE, input logic [`XLEN-1:0] PCE,
output logic [`XLEN-1:0] PCTargetE, output logic [`XLEN-1:0] PCTargetE,
output logic MulDivE, W64E,
output logic [2:0] Funct3E,
output logic [`XLEN-1:0] SrcAE, SrcBE,
// Memory stage interface // Memory stage interface
input logic DataMisalignedM, input logic DataMisalignedM,
input logic DataAccessFaultM, input logic DataAccessFaultM,
@ -42,14 +45,13 @@ module ieu (
output logic [`XLEN-1:0] SrcAM, output logic [`XLEN-1:0] SrcAM,
output logic [2:0] Funct3M, output logic [2:0] Funct3M,
// Writeback stage // Writeback stage
input logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] CSRReadValW, ReadDataW, MulDivResultW,
input logic [`XLEN-1:0] CSRReadValW,
input logic [`XLEN-1:0] PCLinkW, input logic [`XLEN-1:0] PCLinkW,
output logic InstrValidW, output logic InstrValidW,
// hazards // hazards
input logic StallD, FlushD, FlushE, FlushM, FlushW, input logic StallD, FlushD, FlushE, FlushM, FlushW,
input logic RetM, TrapM, input logic RetM, TrapM,
output logic LoadStallD, output logic LoadStallD, MulDivStallD,
output logic PCSrcE, output logic PCSrcE,
output logic CSRWriteM, PrivilegedM, output logic CSRWriteM, PrivilegedM,
@ -60,7 +62,7 @@ module ieu (
logic [2:0] FlagsE; logic [2:0] FlagsE;
logic [4:0] ALUControlE; logic [4:0] ALUControlE;
logic ALUSrcAE, ALUSrcBE; logic ALUSrcAE, ALUSrcBE;
logic [1:0] ResultSrcW; logic [2:0] ResultSrcW;
logic TargetSrcE; logic TargetSrcE;
// forwarding signals // forwarding signals
@ -69,7 +71,7 @@ module ieu (
logic RegWriteM, RegWriteW; logic RegWriteM, RegWriteW;
logic MemReadE; logic MemReadE;
controller c(.OpD(InstrD[6:0]), .Funct3D(InstrD[14:12]), .Funct7b5D(InstrD[30]), .*); controller c(.OpD(InstrD[6:0]), .Funct3D(InstrD[14:12]), .Funct7D(InstrD[31:25]), .*);
datapath dp(.*); datapath dp(.*);
forward fw(.*); forward fw(.*);
endmodule endmodule

View File

@ -0,0 +1,51 @@
///////////////////////////////////////////
// muldiv.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
//
// Purpose: M extension multiply and divide
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
`include "wally-config.vh"
module muldiv (
input logic clk, reset,
// Decode Stage interface
input logic [31:0] InstrD,
// Execute Stage interface
input logic [`XLEN-1:0] SrcAE, SrcBE,
input logic MulDivE, W64E,
// Writeback stage
output logic [`XLEN-1:0] MulDivResultW,
// hazards
input logic FlushM, FlushW // ***fewer?
);
logic [`XLEN*2-1:0] ProdE;
logic [`XLEN-1:0] MulDivResultE, MulDivResultM;
assign ProdE = SrcAE * SrcBE;
assign MulDivResultE = ProdE[`XLEN-1:0];
floprc #(`XLEN) MulDivResultMReg(clk, reset, FlushM, MulDivResultE, MulDivResultM);
floprc #(`XLEN) MulDivResultWReg(clk, reset, FlushW, MulDivResultM, MulDivResultW);
endmodule

View File

@ -53,13 +53,16 @@ module wallypipelinedhart (
logic RetM, TrapM; logic RetM, TrapM;
// new signals that must connect through DP // new signals that must connect through DP
logic MulDivE, W64E;
logic CSRWriteM, PrivilegedM; logic CSRWriteM, PrivilegedM;
logic [`XLEN-1:0] SrcAE, SrcBE;
logic [`XLEN-1:0] SrcAM; logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
// logic [31:0] InstrF; // logic [31:0] InstrF;
logic [31:0] InstrD, InstrM; logic [31:0] InstrD, InstrM;
logic [`XLEN-1:0] PCE, PCM, PCLinkW; logic [`XLEN-1:0] PCE, PCM, PCLinkW;
logic [`XLEN-1:0] PCTargetE; logic [`XLEN-1:0] PCTargetE;
logic [`XLEN-1:0] CSRReadValW; logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
logic [`XLEN-1:0] PrivilegedNextPCM; logic [`XLEN-1:0] PrivilegedNextPCM;
logic [1:0] MemRWM; logic [1:0] MemRWM;
logic InstrValidW; logic InstrValidW;
@ -73,7 +76,7 @@ module wallypipelinedhart (
logic PCSrcE; logic PCSrcE;
logic CSRWritePendingDEM; logic CSRWritePendingDEM;
logic LoadStallD; logic LoadStallD, MulDivStallD;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
logic [2:0] FRM_REGW; logic [2:0] FRM_REGW;
logic FloatRegWriteW; logic FloatRegWriteW;
@ -100,9 +103,9 @@ module wallypipelinedhart (
.*); .*);
//assign InstrF = ReadDataM[31:0]; //assign InstrF = ReadDataM[31:0];
/*
mdu mdu(.*); // multiply and divide unit muldiv mdu(.*); // multiply and divide unit
fpu fpu(.*); // floating point unit /* fpu fpu(.*); // floating point unit
*/ */
hazard hzu(.*); // global stall and flush control hazard hzu(.*); // global stall and flush control

View File

@ -37,6 +37,9 @@ module testbench();
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
logic [31:0] InstrW; logic [31:0] InstrW;
logic [`XLEN-1:0] meminit; logic [`XLEN-1:0] meminit;
string tests64m[] = '{
"rv64m/I-MUL-01", "3000"
};
string tests64ic[] = '{ string tests64ic[] = '{
"rv64ic/I-C-ADD-01", "3000", "rv64ic/I-C-ADD-01", "3000",
@ -172,6 +175,9 @@ string tests64iNOc[] = {
"rv64i/WALLY-CSRRCI", "4000" "rv64i/WALLY-CSRRCI", "4000"
}; };
string tests32m[] = '{
"rv32m/I-MUL-01", "3000"
};
string tests32ic[] = '{ string tests32ic[] = '{
// "rv32ic/WALLY-C-ADHOC-01", "2000", // "rv32ic/WALLY-C-ADHOC-01", "2000",
"rv32ic/I-C-ADD-01", "2000", "rv32ic/I-C-ADD-01", "2000",
@ -299,10 +305,12 @@ string tests32i[] = {
tests = {tests64i}; tests = {tests64i};
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic}; if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic};
else tests = {tests, tests64iNOc}; else tests = {tests, tests64iNOc};
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests64m};
end else begin // RV32 end else begin // RV32
tests = {tests32i}; tests = {tests32i};
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
else tests = {tests, tests32iNOc}; else tests = {tests, tests32iNOc};
if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m};
end end
string signame, memfilename; string signame, memfilename;
@ -491,10 +499,18 @@ module instrNameDecTB(
else name = "ILLEGAL"; else name = "ILLEGAL";
10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW"; 10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW";
else if (funct7 == 7'b0100000) name = "SUBW"; else if (funct7 == 7'b0100000) name = "SUBW";
else if (funct7 == 7'b0000001) name = "MULW";
else name = "ILLEGAL";
10'b0111011_001: if (funct7 == 7'b0000000) name = "SLLW";
else if (funct7 == 7'b0000001) name = "DIVW";
else name = "ILLEGAL"; else name = "ILLEGAL";
10'b0111011_001: name = "SLLW";
10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW"; 10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW";
else if (funct7 == 7'b0100000) name = "SRAW"; else if (funct7 == 7'b0100000) name = "SRAW";
else if (funct7 == 7'b0000001) name = "DIVUW";
else name = "ILLEGAL";
10'b0111011_110: if (funct7 == 7'b0000001) name = "REMW";
else name = "ILLEGAL";
10'b0111011_111: if (funct7 == 7'b0000001) name = "REMUW";
else name = "ILLEGAL"; else name = "ILLEGAL";
10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD"; 10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD";
else if (funct7 == 7'b0000001) name = "MUL"; else if (funct7 == 7'b0000001) name = "MUL";