This commit is contained in:
Kip Macsai-Goren 2021-05-31 11:01:15 -04:00
commit 42af5f9818
15 changed files with 2360 additions and 642 deletions

View File

@ -40,7 +40,7 @@ vsim workopt
view wave
-- display input and output signals as hexidecimal values
do ./wave-dos/default-waves.do
do ./wave-dos/peripheral-waves.do
-- Run the Simulation
#run 5000

View File

@ -48,6 +48,11 @@ add wave /testbench/dut/hart/ieu/dp/RegWriteW
add wave -hex /testbench/dut/hart/ieu/dp/ResultW
add wave -hex /testbench/dut/hart/ieu/dp/RdW
add wave -divider
add wave -hex /testbench/dut/hart/priv/csr/ProposedEPCM
add wave -hex /testbench/dut/hart/priv/csr/TrapM
add wave -hex /testbench/dut/hart/priv/csr/UnalignedNextEPCM
add wave -hex /testbench/dut/hart/priv/csr/genblk1/csrm/WriteMEPCM
add wave -hex /testbench/dut/hart/priv/csr/genblk1/csrm/MEPC_REGW
add wave -divider
# peripherals

View File

@ -0,0 +1,195 @@
///////////////////////////////////////////
// lzd.sv
//
// Written: James.Stine@okstate.edu 1 February 2021
// Modified:
//
// Purpose: Integer Divide instructions
//
// 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"
/* verilator lint_off DECLFILENAME */
// Original idea came from V. G. Oklobdzija, "An algorithmic and novel
// design of a leading zero detector circuit: comparison with logic
// synthesis," in IEEE Transactions on Very Large Scale Integration
// (VLSI) Systems, vol. 2, no. 1, pp. 124-128, March 1994, doi:
// 10.1109/92.273153.
// Modified to be more hierarchical
module lzd2 (P, V, B);
input logic [1:0] B;
output logic P;
output logic V;
assign V = B[0] | B[1];
assign P = B[0] & ~B[1];
endmodule // lz2
module lzd_hier #(parameter WIDTH=8)
(input logic [WIDTH-1:0] B,
output logic [$clog2(WIDTH)-1:0] ZP,
output logic ZV);
if (WIDTH == 128)
lzd128 lz127 (ZP, ZV, B);
else if (WIDTH == 64)
lzd64 lz64 (ZP, ZV, B);
else if (WIDTH == 32)
lzd32 lz32 (ZP, ZV, B);
else if (WIDTH == 16)
lzd16 lz16 (ZP, ZV, B);
else if (WIDTH == 8)
lzd8 lz8 (ZP, ZV, B);
else if (WIDTH == 4)
lzd4 lz4 (ZP, ZV, B);
endmodule // lzd_hier
module lzd4 (ZP, ZV, B);
input logic [3:0] B;
logic ZPa;
logic ZPb;
logic ZVa;
logic ZVb;
output logic [1:0] ZP;
output logic ZV;
lz2 l1(ZPa, ZVa, B[1:0]);
lz2 l2(ZPb, ZVb, B[3:2]);
assign ZP[0:0] = ZVb ? ZPb : ZPa;
assign ZP[1] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd4
module lzd8 (ZP, ZV, B);
input logic [7:0] B;
logic [1:0] ZPa;
logic [1:0] ZPb;
logic ZVa;
logic ZVb;
output logic [2:0] ZP;
output logic ZV;
lz4 l1(ZPa, ZVa, B[3:0]);
lz4 l2(ZPb, ZVb, B[7:4]);
assign ZP[1:0] = ZVb ? ZPb : ZPa;
assign ZP[2] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd8
module lzd16 (ZP, ZV, B);
input logic [15:0] B;
logic [2:0] ZPa;
logic [2:0] ZPb;
logic ZVa;
logic ZVb;
output logic [3:0] ZP;
output logic ZV;
lz8 l1(ZPa, ZVa, B[7:0]);
lz8 l2(ZPb, ZVb, B[15:8]);
assign ZP[2:0] = ZVb ? ZPb : ZPa;
assign ZP[3] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd16
module lzd32 (ZP, ZV, B);
input logic [31:0] B;
logic [3:0] ZPa;
logic [3:0] ZPb;
logic ZVa;
logic ZVb;
output logic [4:0] ZP;
output logic ZV;
lz16 l1(ZPa, ZVa, B[15:0]);
lz16 l2(ZPb, ZVb, B[31:16]);
assign ZP[3:0] = ZVb ? ZPb : ZPa;
assign ZP[4] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd32
module lzd64 (ZP, ZV, B);
input logic [63:0] B;
logic [4:0] ZPa;
logic [4:0] ZPb;
logic ZVa;
logic ZVb;
output logic [5:0] ZP;
output logic ZV;
lz32 l1(ZPa, ZVa, B[31:0]);
lz32 l2(ZPb, ZVb, B[63:32]);
assign ZP[4:0] = ZVb ? ZPb : ZPa;
assign ZP[5] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd64
module lzd128 (ZP, ZV, B);
input logic [127:0] B;
logic [5:0] ZPa;
logic [5:0] ZPb;
logic ZVa;
logic ZVb;
output logic [6:0] ZP;
output logic ZV;
lz64 l1(ZPa, ZVa, B[64:0]);
lz64 l2(ZPb, ZVb, B[127:63]);
assign ZP[5:0] = ZVb ? ZPb : ZPa;
assign ZP[6] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lzd128
/* verilator lint_on DECLFILENAME */

View File

@ -0,0 +1,195 @@
///////////////////////////////////////////
// lzd.sv
//
// Written: James.Stine@okstate.edu 1 February 2021
// Modified:
//
// Purpose: Integer Divide instructions
//
// 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"
/* verilator lint_off DECLFILENAME */
// Original idea came from V. G. Oklobdzija, "An algorithmic and novel
// design of a leading zero detector circuit: comparison with logic
// synthesis," in IEEE Transactions on Very Large Scale Integration
// (VLSI) Systems, vol. 2, no. 1, pp. 124-128, March 1994, doi:
// 10.1109/92.273153.
// Modified to be more hierarchical
module lz2 (P, V, B);
input logic [1:0] B;
output logic P;
output logic V;
assign V = B[0] | B[1];
assign P = B[0] & ~B[1];
endmodule // lz2
module lzd_hier #(parameter WIDTH=8)
(input logic [WIDTH-1:0] B,
output logic [$clog2(WIDTH)-1:0] ZP,
output logic ZV);
if (WIDTH == 128)
lz128 lzd127 (ZP, ZV, B);
else if (WIDTH == 64)
lz64 lzd64 (ZP, ZV, B);
else if (WIDTH == 32)
lz32 lzd32 (ZP, ZV, B);
else if (WIDTH == 16)
lz16 lzd16 (ZP, ZV, B);
else if (WIDTH == 8)
lz8 lzd8 (ZP, ZV, B);
else if (WIDTH == 4)
lz4 lzd4 (ZP, ZV, B);
endmodule // lzd_hier
module lz4 (ZP, ZV, B);
input logic [3:0] B;
logic ZPa;
logic ZPb;
logic ZVa;
logic ZVb;
output logic [1:0] ZP;
output logic ZV;
lz2 l1(ZPa, ZVa, B[1:0]);
lz2 l2(ZPb, ZVb, B[3:2]);
assign ZP[0:0] = ZVb ? ZPb : ZPa;
assign ZP[1] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule
module lz8 (ZP, ZV, B);
input logic [7:0] B;
logic [1:0] ZPa;
logic [1:0] ZPb;
logic ZVa;
logic ZVb;
output logic [2:0] ZP;
output logic ZV;
lz4 l1(ZPa, ZVa, B[3:0]);
lz4 l2(ZPb, ZVb, B[7:4]);
assign ZP[1:0] = ZVb ? ZPb : ZPa;
assign ZP[2] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule
module lz16 (ZP, ZV, B);
input logic [15:0] B;
logic [2:0] ZPa;
logic [2:0] ZPb;
logic ZVa;
logic ZVb;
output logic [3:0] ZP;
output logic ZV;
lz8 l1(ZPa, ZVa, B[7:0]);
lz8 l2(ZPb, ZVb, B[15:8]);
assign ZP[2:0] = ZVb ? ZPb : ZPa;
assign ZP[3] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lz16
module lz32 (ZP, ZV, B);
input logic [31:0] B;
logic [3:0] ZPa;
logic [3:0] ZPb;
logic ZVa;
logic ZVb;
output logic [4:0] ZP;
output logic ZV;
lz16 l1(ZPa, ZVa, B[15:0]);
lz16 l2(ZPb, ZVb, B[31:16]);
assign ZP[3:0] = ZVb ? ZPb : ZPa;
assign ZP[4] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lz32
module lz64 (ZP, ZV, B);
input logic [63:0] B;
logic [4:0] ZPa;
logic [4:0] ZPb;
logic ZVa;
logic ZVb;
output logic [5:0] ZP;
output logic ZV;
lz32 l1(ZPa, ZVa, B[31:0]);
lz32 l2(ZPb, ZVb, B[63:32]);
assign ZP[4:0] = ZVb ? ZPb : ZPa;
assign ZP[5] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lz64
module lz128 (ZP, ZV, B);
input logic [127:0] B;
logic [5:0] ZPa;
logic [5:0] ZPb;
logic ZVa;
logic ZVb;
output logic [6:0] ZP;
output logic ZV;
lz64 l1(ZPa, ZVa, B[64:0]);
lz64 l2(ZPb, ZVb, B[127:63]);
assign ZP[5:0] = ZVb ? ZPb : ZPa;
assign ZP[6] = ~ZVb;
assign ZV = ZVa | ZVb;
endmodule // lz128
/* verilator lint_on DECLFILENAME */

View File

@ -0,0 +1,76 @@
///////////////////////////////////////////
// shifters.sv
//
// Written: James.Stine@okstate.edu 1 February 2021
// Modified:
//
// Purpose: Integer Divide instructions
//
// 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"
/* verilator lint_off DECLFILENAME */
/* verilator lint_off UNOPTFLAT */
module shift_right #(parameter WIDTH=8)
(input logic [WIDTH-1:0] A,
input logic [$clog2(WIDTH)-1:0] Shift,
output logic [WIDTH-1:0] Z);
logic [WIDTH-1:0] stage [$clog2(WIDTH):0];
logic sign;
genvar i;
assign stage[0] = A;
generate
for (i=0;i<$clog2(WIDTH);i=i+1)
begin : genbit
mux2 #(WIDTH) mux_inst (stage[i],
{{(WIDTH/(2**(i+1))){1'b0}}, stage[i][WIDTH-1:WIDTH/(2**(i+1))]},
Shift[$clog2(WIDTH)-i-1],
stage[i+1]);
end
endgenerate
assign Z = stage[$clog2(WIDTH)];
endmodule // shift_right
module shift_left #(parameter WIDTH=8)
(input logic [WIDTH-1:0] A,
input logic [$clog2(WIDTH)-1:0] Shift,
output logic [WIDTH-1:0] Z);
logic [WIDTH-1:0] stage [$clog2(WIDTH):0];
genvar i;
assign stage[0] = A;
generate
for (i=0;i<$clog2(WIDTH);i=i+1)
begin : genbit
mux2 #(WIDTH) mux_inst (stage[i],
{stage[i][WIDTH-1-WIDTH/(2**(i+1)):0], {(WIDTH/(2**(i+1))){1'b0}}},
Shift[$clog2(WIDTH)-i-1],
stage[i+1]);
end
endgenerate
assign Z = stage[$clog2(WIDTH)];
endmodule // shift_left
/* verilator lint_on DECLFILENAME */
/* verilator lint_on UNOPTFLAT */

View File

@ -30,16 +30,15 @@ module hazard(
input logic reset,
// Detect hazards
input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
input logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD,
input logic LoadStallD, MulDivStallD, CSRRdStallD,
input logic DataStall, ICacheStallF,
input logic FStallD,
input logic FPUStallD,
input logic DivBusyE,
// Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushF, FlushD, FlushE, FlushM, FlushW
);
logic BranchFlushDE;
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW;
@ -56,34 +55,29 @@ module hazard(
// A stage must stall if the next stage is stalled
// If any stages are stalled, the first stage that isn't stalled must flush.
assign BranchFlushDE = BPPredWrongE | RetM | TrapM;
assign StallFCause = CSRWritePendingDEM & ~(BranchFlushDE);
assign StallDCause = (FPUStallD | LoadStallD | MulDivStallD | CSRRdStallD | FStallD) & ~(BranchFlushDE); // stall in decode if instruction is a load/mul/csr dependent on previous
// assign StallDCause = LoadStallD | MulDivStallD | CSRRdStallD; // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallFCause = CSRWritePendingDEM && ~(TrapM || RetM || BPPredWrongE);
assign StallDCause = (LoadStallD || MulDivStallD || CSRRdStallD || FPUStallD) && ~(TrapM || RetM || BPPredWrongE); // stall in decode if instruction is a load/mul/csr dependent on previous
assign StallECause = DivBusyE;
assign StallMCause = 0;
assign StallWCause = DataStall | ICacheStallF;
assign StallWCause = DataStall || ICacheStallF;
// Each stage stalls if the next stage is stalled or there is a cause to stall this stage.
assign StallF = StallD | StallFCause;
assign StallD = StallE | StallDCause;
assign StallE = StallM | StallECause;
assign StallM = StallW | StallMCause;
assign StallF = StallFCause || StallD;
assign StallD = StallDCause || StallE;
assign StallE = StallECause || StallM;
assign StallM = StallMCause || StallW;
assign StallW = StallWCause;
//assign FirstUnstalledD = (~StallD & StallF & ~MulDivStallD);
assign FirstUnstalledD = (~StallD & StallF);
//assign FirstUnstalledE = (~StallE & StallD & ~MulDivStallD);
assign FirstUnstalledE = (~StallE & StallD);
assign FirstUnstalledM = (~StallM & StallE);
assign FirstUnstalledW = (~StallW & StallM);;
assign FirstUnstalledD = (~StallD && StallF);
assign FirstUnstalledE = (~StallE && StallD);
assign FirstUnstalledM = (~StallM && StallE);
assign FirstUnstalledW = (~StallW && StallM);
// Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush
assign FlushF = BPPredWrongE;
assign FlushD = FirstUnstalledD || BranchFlushDE; // PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM;
assign FlushE = FirstUnstalledE || BranchFlushDE; // LoadStallD | PCSrcE | RetM | TrapM;
assign FlushM = FirstUnstalledM || RetM || TrapM;
assign FlushW = FirstUnstalledW | TrapM;
assign FlushD = FirstUnstalledD || TrapM || RetM || BPPredWrongE;
assign FlushE = FirstUnstalledE || TrapM || RetM || BPPredWrongE;
assign FlushM = FirstUnstalledM || TrapM || RetM;
assign FlushW = FirstUnstalledW || TrapM;
endmodule

View File

@ -37,7 +37,8 @@ module ifu (
output logic [`XLEN-1:0] InstrPAdrF,
output logic InstrReadF,
output logic ICacheStallF,
// Decode
// Decode
output logic [`XLEN-1:0] PCD,
// Execute
output logic [`XLEN-1:0] PCLinkE,
input logic PCSrcE,
@ -47,7 +48,7 @@ module ifu (
// Mem
input logic RetM, TrapM,
input logic [`XLEN-1:0] PrivilegedNextPCM,
output logic [31:0] InstrD, InstrM,
output logic [31:0] InstrD, InstrE, InstrM, InstrW,
output logic [`XLEN-1:0] PCM,
output logic [4:0] InstrClassM,
output logic BPPredDirWrongM,
@ -76,9 +77,9 @@ module ifu (
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
logic PrivilegedChangePCM;
logic IllegalCompInstrD;
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCD, PCW, PCLinkD, PCLinkM, PCNextPF, PCPF;
logic [`XLEN-1:0] PCPlusUpperF, PCPlus2or4F, PCW, PCLinkD, PCLinkM, PCNextPF, PCPF;
logic CompressedF;
logic [31:0] InstrRawD, InstrE, InstrW;
logic [31:0] InstrRawD;
localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic reset_q; // *** look at this later.

1560
wally-pipelined/src/muldiv/div.bak Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,6 @@ module muldiv (
logic [`XLEN-1:0] MulDivResultE, MulDivResultM;
logic [`XLEN-1:0] PrelimResultE;
logic [`XLEN-1:0] QuotE, RemE;
//logic [`XLEN-1:0] Q, R;
logic [`XLEN*2-1:0] ProdE;
logic enable_q;
@ -78,7 +77,7 @@ module muldiv (
.en(startDivideE), .clear(DivDoneE),
.reset(reset), .clk(~gclk));
assign signedDivide = (Funct3E[2]&~Funct3E[1]&~Funct3E[0]) | (Funct3E[2]&Funct3E[1]&~Funct3E[0]);
div div (QuotE, RemE, DivDoneE, DivBusyE, div0error, N, D, gclk, reset, startDivideE, signedDivide);
intdiv #(`XLEN) div (QuotE, RemE, DivDoneE, DivBusyE, div0error, N, D, gclk, reset, startDivideE, signedDivide);
// Added for debugging of start signal for divide
assign startDivideE = MulDivE&DivStartE&~DivBusyE;
@ -93,7 +92,6 @@ module muldiv (
// Select result
always_comb
// case (DivDoneE ? Funct3E_Q : Funct3E)
case (Funct3E)
3'b000: PrelimResultE = ProdE[`XLEN-1:0];
3'b001: PrelimResultE = ProdE[`XLEN*2-1:`XLEN];

View File

@ -34,8 +34,8 @@ module csr #(parameter
) (
input logic clk, reset,
input logic FlushW, StallD, StallE, StallM, StallW,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM,
input logic [31:0] InstrD,InstrE,InstrM,
input logic [`XLEN-1:0] PCF, PCD, PCE, PCM, SrcAM,
input logic InterruptM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
input logic TimerIntM, ExtIntM, SwIntM,
@ -47,6 +47,9 @@ module csr #(parameter
input logic [4:0] InstrClassM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic [`XLEN-1:0] CauseM, NextFaultMtvalM,
input logic BreakpointFaultM, EcallFaultM,
input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
input logic LoadMisalignedFaultM, StoreMisalignedFaultM, LoadAccessFaultM, StoreAccessFaultM,
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
@ -65,6 +68,7 @@ module csr #(parameter
output logic IllegalCSRAccessM
);
localparam NOP = 32'h13;
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRNReadValM, CSRCReadValM, CSRReadValM;
logic [`XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM;
@ -73,22 +77,32 @@ module csr #(parameter
logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, preservedPCM, readPCM, NextCauseM, NextMtvalM;
always_ff @(posedge clk) begin
preservedPCM <= PCM;
end
mux2 #(`XLEN) pcmux(PCM, preservedPCM, InterruptM, readPCM);
//flop #(`XLEN) CSRReadPCMreg(clk, reset, PCM, readPCM);
logic MStageFailed;
logic [`XLEN-1:0] ProposedEPCM, UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
logic [11:0] CSRAdrM;
logic [11:0] SIP_REGW, SIE_REGW;
//logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, IllegalCSRNAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM;
assign MStageFailed = BreakpointFaultM || EcallFaultM || InstrMisalignedFaultM || InstrAccessFaultM || IllegalInstrFaultM || LoadMisalignedFaultM || StoreMisalignedFaultM || LoadAccessFaultM || StoreAccessFaultM;
always_comb begin
if (MStageFailed)
casez({InstrD==NOP,InstrE==NOP,InstrM==NOP})
3'b??0: ProposedEPCM = PCM;
3'b?01: ProposedEPCM = PCE;
3'b011: ProposedEPCM = PCD;
3'b111: ProposedEPCM = PCF;
endcase
else
casez({InstrD==NOP,InstrE==NOP})
2'b?0: ProposedEPCM = PCE;
2'b01: ProposedEPCM = PCD;
2'b11: ProposedEPCM = PCF;
endcase
end
generate
if (`ZCSR_SUPPORTED) begin
// modify CSRs
@ -109,7 +123,7 @@ module csr #(parameter
// write CSRs
assign CSRAdrM = InstrM[31:20];
assign UnalignedNextEPCM = TrapM ? readPCM : CSRWriteValM;
assign UnalignedNextEPCM = TrapM ? ProposedEPCM : CSRWriteValM;
assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment
assign NextCauseM = TrapM ? CauseM : CSRWriteValM;
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;

View File

@ -109,74 +109,74 @@ module csrsr (
// complex register with reset, write enable, and the ability to update other bits in certain cases
always_ff @(posedge clk, posedge reset)
if (reset) begin
STATUS_SUM_INT <= 0;
STATUS_MPRV_INT <= 0; // Per Priv 3.3
STATUS_FS_INT <= 0; //2'b01; // busybear: change all these reset values to 0
STATUS_MPP <= 0; //`M_MODE;
STATUS_SPP <= 0; //1'b1;
STATUS_MPIE <= 0; //1;
STATUS_SPIE <= 0; //`S_SUPPORTED;
STATUS_UPIE <= 0; // `U_SUPPORTED;
STATUS_MIE <= 0; // Per Priv 3.3
STATUS_SIE <= 0; //`S_SUPPORTED;
STATUS_UIE <= 0; //`U_SUPPORTED;
STATUS_SUM_INT <= #1 0;
STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
STATUS_FS_INT <= #1 0; //2'b01; // busybear: change all these reset values to 0
STATUS_MPP <= #1 0; //`M_MODE;
STATUS_SPP <= #1 0; //1'b1;
STATUS_MPIE <= #1 0; //1;
STATUS_SPIE <= #1 0; //`S_SUPPORTED;
STATUS_UPIE <= #1 0; // `U_SUPPORTED;
STATUS_MIE <= #1 0; // Per Priv 3.3
STATUS_SIE <= #1 0; //`S_SUPPORTED;
STATUS_UIE <= #1 0; //`U_SUPPORTED;
end else if (~StallW) begin
if (WriteMSTATUSM) begin
STATUS_SUM_INT <= CSRWriteValM[18];
STATUS_MPRV_INT <= CSRWriteValM[17];
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_MPP <= STATUS_MPP_NEXT;
STATUS_SPP <= `S_SUPPORTED & CSRWriteValM[8];
STATUS_MPIE <= CSRWriteValM[7];
STATUS_SPIE <= `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4];
STATUS_MIE <= CSRWriteValM[3];
STATUS_SIE <= `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0];
STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_MPRV_INT <= #1 CSRWriteValM[17];
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_MPP <= #1 STATUS_MPP_NEXT;
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_MPIE <= #1 CSRWriteValM[7];
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_MIE <= #1 CSRWriteValM[3];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_SUM_INT <= CSRWriteValM[18];
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_SPP <= `S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4];
STATUS_SIE <= `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0];
STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteUSTATUSM) begin // write a subset of the STATUS bits
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0];
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else begin
if (FloatRegWriteW) STATUS_FS_INT <=2'b11; // mark Float State dirty
if (FloatRegWriteW) STATUS_FS_INT <= #12'b11; // mark Float State dirty
if (TrapM) begin
// Update interrupt enables per Privileged Spec p. 21
// y = PrivilegeModeW
// x = NextPrivilegeModeM
// Modes: 11 = Machine, 01 = Supervisor, 00 = User
if (NextPrivilegeModeM == `M_MODE) begin
STATUS_MPIE <= STATUS_MIE;
STATUS_MIE <= 0;
STATUS_MPP <= PrivilegeModeW;
STATUS_MPIE <= #1 STATUS_MIE;
STATUS_MIE <= #1 0;
STATUS_MPP <= #1 PrivilegeModeW;
end else if (NextPrivilegeModeM == `S_MODE) begin
STATUS_SPIE <= STATUS_SIE;
STATUS_SIE <= 0;
STATUS_SPP <= PrivilegeModeW[0]; // *** seems to disagree with P. 56
STATUS_SPIE <= #1 STATUS_SIE;
STATUS_SIE <= #1 0;
STATUS_SPP <= #1 PrivilegeModeW[0]; // *** seems to disagree with P. 56
end else begin // user mode
STATUS_UPIE <= STATUS_UIE;
STATUS_UIE <= 0;
STATUS_UPIE <= #1 STATUS_UIE;
STATUS_UIE <= #1 0;
end
end else if (mretM) begin // Privileged 3.1.6.1
STATUS_MIE <= STATUS_MPIE;
STATUS_MPIE <= 1;
STATUS_MPP <= `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why
STATUS_MPRV_INT <= 0; // per 20210108 draft spec
STATUS_MIE <= #1 STATUS_MPIE;
STATUS_MPIE <= #1 1;
STATUS_MPP <= #1 `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (sretM) begin
STATUS_SIE <= STATUS_SPIE;
STATUS_SPIE <= `S_SUPPORTED;
STATUS_SPP <= 0; // Privileged 4.1.1
STATUS_MPRV_INT <= 0; // per 20210108 draft spec
STATUS_SIE <= #1 STATUS_SPIE;
STATUS_SPIE <= #1 `S_SUPPORTED;
STATUS_SPP <= #1 0; // Privileged 4.1.1
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (uretM) begin
STATUS_UIE <= STATUS_UPIE;
STATUS_UPIE <= `U_SUPPORTED;
STATUS_UIE <= #1 STATUS_UPIE;
STATUS_UPIE <= #1 `U_SUPPORTED;
end
// *** add code to track STATUS_FS_INT for dirty floating point registers
end

View File

@ -31,8 +31,8 @@ module privileged (
input logic FlushW,
input logic CSRReadM, CSRWriteM,
input logic [`XLEN-1:0] SrcAM,
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM,
input logic [`XLEN-1:0] PCF,PCD,PCE,PCM,
input logic [31:0] InstrD, InstrE, InstrM, InstrW,
output logic [`XLEN-1:0] CSRReadValW,
output logic [`XLEN-1:0] PrivilegedNextPCM,
output logic RetM, TrapM,

View File

@ -68,8 +68,8 @@ module wallypipelinedhart (
logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
// logic [31:0] InstrF;
logic [31:0] InstrD, InstrM;
logic [`XLEN-1:0] PCE, PCM, PCLinkE, PCLinkW;
logic [31:0] InstrD, InstrE, InstrM, InstrW;
logic [`XLEN-1:0] PCD, PCE, PCM, PCLinkE, PCLinkW;
logic [`XLEN-1:0] PCTargetE;
logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
logic [`XLEN-1:0] PrivilegedNextPCM;

View File

@ -29,6 +29,7 @@
module testbench();
parameter DEBUG = 0;
parameter TESTSPERIPH = 0; // set to 0 for regression
parameter TESTSPRIV = 0; // set to 0 for regression
logic clk;
logic reset;
@ -516,9 +517,11 @@ string tests32f[] = '{
tests = testsBP64;
// testsbp should not run the other tests. It starts at address 0 rather than
// 0x8000_0000, the next if must remain an else if.
end else if (TESTSPERIPH) begin
end else if (TESTSPERIPH)
tests = tests64periph;
end else begin
else if (TESTSPRIV)
tests = tests64p;
else begin
tests = {tests64p,tests64i,tests64periph};
if (`C_SUPPORTED) tests = {tests, tests64ic};
else tests = {tests, tests64iNOc};
@ -531,9 +534,11 @@ string tests32f[] = '{
//tests = {tests64a, tests};
end else begin // RV32
// *** add the 32 bit bp tests
if (TESTSPERIPH) begin
if (TESTSPERIPH)
tests = tests32periph;
end else begin
else if (TESTSPRIV)
tests = tests32p;
else begin
tests = {tests32i, tests32p};//,tests32periph}; *** broken at the moment
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
else tests = {tests, tests32iNOc};