mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
42af5f9818
@ -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
|
||||
|
@ -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
|
||||
|
195
wally-pipelined/src/generic/lzd.sv
Executable file
195
wally-pipelined/src/generic/lzd.sv
Executable 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 */
|
195
wally-pipelined/src/generic/lzd.sv~
Executable file
195
wally-pipelined/src/generic/lzd.sv~
Executable 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 */
|
76
wally-pipelined/src/generic/shift.sv
Executable file
76
wally-pipelined/src/generic/shift.sv
Executable 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 */
|
@ -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
|
||||
|
@ -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
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
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user