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 view wave
-- display input and output signals as hexidecimal values -- display input and output signals as hexidecimal values
do ./wave-dos/default-waves.do do ./wave-dos/peripheral-waves.do
-- Run the Simulation -- Run the Simulation
#run 5000 #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/ResultW
add wave -hex /testbench/dut/hart/ieu/dp/RdW add wave -hex /testbench/dut/hart/ieu/dp/RdW
add wave -divider 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 add wave -divider
# peripherals # 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, input logic reset,
// Detect hazards // Detect hazards
input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM, input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
input logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD, input logic LoadStallD, MulDivStallD, CSRRdStallD,
input logic DataStall, ICacheStallF, input logic DataStall, ICacheStallF,
input logic FStallD, input logic FPUStallD,
input logic DivBusyE, input logic DivBusyE,
// Stall & flush outputs // Stall & flush outputs
output logic StallF, StallD, StallE, StallM, StallW, output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushF, FlushD, FlushE, FlushM, FlushW output logic FlushF, FlushD, FlushE, FlushM, FlushW
); );
logic BranchFlushDE;
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause; logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;
logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW; logic FirstUnstalledD, FirstUnstalledE, FirstUnstalledM, FirstUnstalledW;
@ -56,34 +55,29 @@ module hazard(
// A stage must stall if the next stage is stalled // A stage must stall if the next stage is stalled
// If any stages are stalled, the first stage that isn't stalled must flush. // If any stages are stalled, the first stage that isn't stalled must flush.
assign BranchFlushDE = BPPredWrongE | RetM | TrapM; 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 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 StallECause = DivBusyE; assign StallECause = DivBusyE;
assign StallMCause = 0; 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 = StallFCause || StallD;
assign StallF = StallD | StallFCause; assign StallD = StallDCause || StallE;
assign StallE = StallECause || StallM;
assign StallD = StallE | StallDCause; assign StallM = StallMCause || StallW;
assign StallE = StallM | StallECause;
assign StallM = StallW | StallMCause;
assign StallW = StallWCause; assign StallW = StallWCause;
//assign FirstUnstalledD = (~StallD & StallF & ~MulDivStallD); //assign FirstUnstalledD = (~StallD & StallF & ~MulDivStallD);
assign FirstUnstalledD = (~StallD & StallF);
//assign FirstUnstalledE = (~StallE & StallD & ~MulDivStallD); //assign FirstUnstalledE = (~StallE & StallD & ~MulDivStallD);
assign FirstUnstalledE = (~StallE & StallD); assign FirstUnstalledD = (~StallD && StallF);
assign FirstUnstalledM = (~StallM & StallE); assign FirstUnstalledE = (~StallE && StallD);
assign FirstUnstalledW = (~StallW & StallM);; 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 // 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 FlushF = BPPredWrongE;
assign FlushD = FirstUnstalledD || BranchFlushDE; // PCSrcE |InstrStall | CSRWritePendingDEM | RetM | TrapM; assign FlushD = FirstUnstalledD || TrapM || RetM || BPPredWrongE;
assign FlushE = FirstUnstalledE || BranchFlushDE; // LoadStallD | PCSrcE | RetM | TrapM; assign FlushE = FirstUnstalledE || TrapM || RetM || BPPredWrongE;
assign FlushM = FirstUnstalledM || RetM || TrapM; assign FlushM = FirstUnstalledM || TrapM || RetM;
assign FlushW = FirstUnstalledW | TrapM; assign FlushW = FirstUnstalledW || TrapM;
endmodule endmodule

View File

@ -38,6 +38,7 @@ module ifu (
output logic InstrReadF, output logic InstrReadF,
output logic ICacheStallF, output logic ICacheStallF,
// Decode // Decode
output logic [`XLEN-1:0] PCD,
// Execute // Execute
output logic [`XLEN-1:0] PCLinkE, output logic [`XLEN-1:0] PCLinkE,
input logic PCSrcE, input logic PCSrcE,
@ -47,7 +48,7 @@ module ifu (
// Mem // Mem
input logic RetM, TrapM, input logic RetM, TrapM,
input logic [`XLEN-1:0] PrivilegedNextPCM, 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 [`XLEN-1:0] PCM,
output logic [4:0] InstrClassM, output logic [4:0] InstrClassM,
output logic BPPredDirWrongM, output logic BPPredDirWrongM,
@ -76,9 +77,9 @@ module ifu (
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM; logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
logic PrivilegedChangePCM; logic PrivilegedChangePCM;
logic IllegalCompInstrD; 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 CompressedF;
logic [31:0] InstrRawD, InstrE, InstrW; logic [31:0] InstrRawD;
localparam [31:0] nop = 32'h00000013; // instruction for NOP localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic reset_q; // *** look at this later. 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] MulDivResultE, MulDivResultM;
logic [`XLEN-1:0] PrelimResultE; logic [`XLEN-1:0] PrelimResultE;
logic [`XLEN-1:0] QuotE, RemE; logic [`XLEN-1:0] QuotE, RemE;
//logic [`XLEN-1:0] Q, R;
logic [`XLEN*2-1:0] ProdE; logic [`XLEN*2-1:0] ProdE;
logic enable_q; logic enable_q;
@ -78,7 +77,7 @@ module muldiv (
.en(startDivideE), .clear(DivDoneE), .en(startDivideE), .clear(DivDoneE),
.reset(reset), .clk(~gclk)); .reset(reset), .clk(~gclk));
assign signedDivide = (Funct3E[2]&~Funct3E[1]&~Funct3E[0]) | (Funct3E[2]&Funct3E[1]&~Funct3E[0]); 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 // Added for debugging of start signal for divide
assign startDivideE = MulDivE&DivStartE&~DivBusyE; assign startDivideE = MulDivE&DivStartE&~DivBusyE;
@ -93,7 +92,6 @@ module muldiv (
// Select result // Select result
always_comb always_comb
// case (DivDoneE ? Funct3E_Q : Funct3E)
case (Funct3E) case (Funct3E)
3'b000: PrelimResultE = ProdE[`XLEN-1:0]; 3'b000: PrelimResultE = ProdE[`XLEN-1:0];
3'b001: PrelimResultE = ProdE[`XLEN*2-1:`XLEN]; 3'b001: PrelimResultE = ProdE[`XLEN*2-1:`XLEN];

View File

@ -34,8 +34,8 @@ module csr #(parameter
) ( ) (
input logic clk, reset, input logic clk, reset,
input logic FlushW, StallD, StallE, StallM, StallW, input logic FlushW, StallD, StallE, StallM, StallW,
input logic [31:0] InstrM, input logic [31:0] InstrD,InstrE,InstrM,
input logic [`XLEN-1:0] PCM, SrcAM, input logic [`XLEN-1:0] PCF, PCD, PCE, PCM, SrcAM,
input logic InterruptM, input logic InterruptM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM, input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
input logic TimerIntM, ExtIntM, SwIntM, input logic TimerIntM, ExtIntM, SwIntM,
@ -47,6 +47,9 @@ module csr #(parameter
input logic [4:0] InstrClassM, input logic [4:0] InstrClassM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic [`XLEN-1:0] CauseM, NextFaultMtvalM, 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 [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, output logic STATUS_SPP, STATUS_TSR,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW, 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 output logic IllegalCSRAccessM
); );
localparam NOP = 32'h13;
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRNReadValM, CSRCReadValM, CSRReadValM; logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRNReadValM, CSRCReadValM, CSRReadValM;
logic [`XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM; logic [`XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM;
@ -73,22 +77,32 @@ module csr #(parameter
logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM; logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, preservedPCM, readPCM, NextCauseM, NextMtvalM; logic MStageFailed;
logic [`XLEN-1:0] ProposedEPCM, UnalignedNextEPCM, NextEPCM, 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 [11:0] CSRAdrM; logic [11:0] CSRAdrM;
logic [11:0] SIP_REGW, SIE_REGW; logic [11:0] SIP_REGW, SIE_REGW;
//logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported //logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, IllegalCSRNAccessM, InsufficientCSRPrivilegeM; logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, IllegalCSRNAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM; 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 generate
if (`ZCSR_SUPPORTED) begin if (`ZCSR_SUPPORTED) begin
// modify CSRs // modify CSRs
@ -109,7 +123,7 @@ module csr #(parameter
// write CSRs // write CSRs
assign CSRAdrM = InstrM[31:20]; 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 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 NextCauseM = TrapM ? CauseM : CSRWriteValM;
assign NextMtvalM = TrapM ? NextFaultMtvalM : 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 // complex register with reset, write enable, and the ability to update other bits in certain cases
always_ff @(posedge clk, posedge reset) always_ff @(posedge clk, posedge reset)
if (reset) begin if (reset) begin
STATUS_SUM_INT <= 0; STATUS_SUM_INT <= #1 0;
STATUS_MPRV_INT <= 0; // Per Priv 3.3 STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
STATUS_FS_INT <= 0; //2'b01; // busybear: change all these reset values to 0 STATUS_FS_INT <= #1 0; //2'b01; // busybear: change all these reset values to 0
STATUS_MPP <= 0; //`M_MODE; STATUS_MPP <= #1 0; //`M_MODE;
STATUS_SPP <= 0; //1'b1; STATUS_SPP <= #1 0; //1'b1;
STATUS_MPIE <= 0; //1; STATUS_MPIE <= #1 0; //1;
STATUS_SPIE <= 0; //`S_SUPPORTED; STATUS_SPIE <= #1 0; //`S_SUPPORTED;
STATUS_UPIE <= 0; // `U_SUPPORTED; STATUS_UPIE <= #1 0; // `U_SUPPORTED;
STATUS_MIE <= 0; // Per Priv 3.3 STATUS_MIE <= #1 0; // Per Priv 3.3
STATUS_SIE <= 0; //`S_SUPPORTED; STATUS_SIE <= #1 0; //`S_SUPPORTED;
STATUS_UIE <= 0; //`U_SUPPORTED; STATUS_UIE <= #1 0; //`U_SUPPORTED;
end else if (~StallW) begin end else if (~StallW) begin
if (WriteMSTATUSM) begin if (WriteMSTATUSM) begin
STATUS_SUM_INT <= CSRWriteValM[18]; STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_MPRV_INT <= CSRWriteValM[17]; STATUS_MPRV_INT <= #1 CSRWriteValM[17];
STATUS_FS_INT <= CSRWriteValM[14:13]; STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_MPP <= STATUS_MPP_NEXT; STATUS_MPP <= #1 STATUS_MPP_NEXT;
STATUS_SPP <= `S_SUPPORTED & CSRWriteValM[8]; STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_MPIE <= CSRWriteValM[7]; STATUS_MPIE <= #1 CSRWriteValM[7];
STATUS_SPIE <= `S_SUPPORTED & CSRWriteValM[5]; STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4]; STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_MIE <= CSRWriteValM[3]; STATUS_MIE <= #1 CSRWriteValM[3];
STATUS_SIE <= `S_SUPPORTED & CSRWriteValM[1]; STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0]; STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_SUM_INT <= CSRWriteValM[18]; STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_FS_INT <= CSRWriteValM[14:13]; STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_SPP <= `S_SUPPORTED & CSRWriteValM[8]; STATUS_SPP <= #1 `S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= `S_SUPPORTED & CSRWriteValM[5]; STATUS_SPIE <= #1 `S_SUPPORTED & CSRWriteValM[5];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4]; STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_SIE <= `S_SUPPORTED & CSRWriteValM[1]; STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0]; STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteUSTATUSM) begin // write a subset of the STATUS bits end else if (WriteUSTATUSM) begin // write a subset of the STATUS bits
STATUS_FS_INT <= CSRWriteValM[14:13]; STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_UPIE <= `U_SUPPORTED & CSRWriteValM[4]; STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_UIE <= `U_SUPPORTED & CSRWriteValM[0]; STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else begin 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 if (TrapM) begin
// Update interrupt enables per Privileged Spec p. 21 // Update interrupt enables per Privileged Spec p. 21
// y = PrivilegeModeW // y = PrivilegeModeW
// x = NextPrivilegeModeM // x = NextPrivilegeModeM
// Modes: 11 = Machine, 01 = Supervisor, 00 = User // Modes: 11 = Machine, 01 = Supervisor, 00 = User
if (NextPrivilegeModeM == `M_MODE) begin if (NextPrivilegeModeM == `M_MODE) begin
STATUS_MPIE <= STATUS_MIE; STATUS_MPIE <= #1 STATUS_MIE;
STATUS_MIE <= 0; STATUS_MIE <= #1 0;
STATUS_MPP <= PrivilegeModeW; STATUS_MPP <= #1 PrivilegeModeW;
end else if (NextPrivilegeModeM == `S_MODE) begin end else if (NextPrivilegeModeM == `S_MODE) begin
STATUS_SPIE <= STATUS_SIE; STATUS_SPIE <= #1 STATUS_SIE;
STATUS_SIE <= 0; STATUS_SIE <= #1 0;
STATUS_SPP <= PrivilegeModeW[0]; // *** seems to disagree with P. 56 STATUS_SPP <= #1 PrivilegeModeW[0]; // *** seems to disagree with P. 56
end else begin // user mode end else begin // user mode
STATUS_UPIE <= STATUS_UIE; STATUS_UPIE <= #1 STATUS_UIE;
STATUS_UIE <= 0; STATUS_UIE <= #1 0;
end end
end else if (mretM) begin // Privileged 3.1.6.1 end else if (mretM) begin // Privileged 3.1.6.1
STATUS_MIE <= STATUS_MPIE; STATUS_MIE <= #1 STATUS_MPIE;
STATUS_MPIE <= 1; STATUS_MPIE <= #1 1;
STATUS_MPP <= `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why STATUS_MPP <= #1 `U_SUPPORTED ? `U_MODE : `M_MODE; // per spec, not sure why
STATUS_MPRV_INT <= 0; // per 20210108 draft spec STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (sretM) begin end else if (sretM) begin
STATUS_SIE <= STATUS_SPIE; STATUS_SIE <= #1 STATUS_SPIE;
STATUS_SPIE <= `S_SUPPORTED; STATUS_SPIE <= #1 `S_SUPPORTED;
STATUS_SPP <= 0; // Privileged 4.1.1 STATUS_SPP <= #1 0; // Privileged 4.1.1
STATUS_MPRV_INT <= 0; // per 20210108 draft spec STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (uretM) begin end else if (uretM) begin
STATUS_UIE <= STATUS_UPIE; STATUS_UIE <= #1 STATUS_UPIE;
STATUS_UPIE <= `U_SUPPORTED; STATUS_UPIE <= #1 `U_SUPPORTED;
end end
// *** add code to track STATUS_FS_INT for dirty floating point registers // *** add code to track STATUS_FS_INT for dirty floating point registers
end end

View File

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

View File

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

View File

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