forked from Github_Repos/cvw
Initial Checkin
This commit is contained in:
parent
a609876074
commit
fd01e27a48
3
LICENSE
3
LICENSE
@ -1,6 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 davidharrishmc
|
||||
Copyright (c) 2021 Harvey Mudd College & Oklahoma State University
|
||||
Contact: Prof. David Harris David_Harris@hmc.edu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
1
riscv-o3
Submodule
1
riscv-o3
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit afb27bd558a9b6fabb6b768ae81ef122b4db9eea
|
1
wally-pipelined/.#modelsim.ini
Symbolic link
1
wally-pipelined/.#modelsim.ini
Symbolic link
@ -0,0 +1 @@
|
||||
harris@Tera.Eng.HMC.Edu.6921:1604012407
|
1
wally-pipelined/sim-wally
Executable file
1
wally-pipelined/sim-wally
Executable file
@ -0,0 +1 @@
|
||||
vsim -do wally-pipelined.do
|
1
wally-pipelined/sim-wally-batch
Executable file
1
wally-pipelined/sim-wally-batch
Executable file
@ -0,0 +1 @@
|
||||
vsim -c -do wally-pipelined-batch.do
|
88
wally-pipelined/src/alu.sv
Normal file
88
wally-pipelined/src/alu.sv
Normal file
@ -0,0 +1,88 @@
|
||||
///////////////////////////////////////////
|
||||
// alu.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: RISC-V Arithmetic/Logic Unit
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module alu #(parameter WIDTH=32) (
|
||||
input logic [WIDTH-1:0] a, b,
|
||||
input logic [4:0] alucontrol,
|
||||
output logic [WIDTH-1:0] result,
|
||||
output logic [2:0] flags);
|
||||
|
||||
logic [WIDTH-1:0] condinvb, presum, sum, shift, slt, sltu, bor;
|
||||
logic right, arith, w64;
|
||||
logic carry, zero, neg;
|
||||
logic lt, ltu;
|
||||
logic overflow;
|
||||
|
||||
// addition
|
||||
assign condinvb = alucontrol[3] ? ~b : b;
|
||||
assign {carry, presum} = a + condinvb + {{(WIDTH-1){1'b0}},alucontrol[3]};
|
||||
|
||||
// support W-type RV64I ADDW/SUBW/ADDIW that sign-extend 32-bit result to 64 bits
|
||||
generate
|
||||
if (WIDTH==64)
|
||||
assign sum = w64 ? {{32{presum[31]}}, presum[31:0]} : presum;
|
||||
else
|
||||
assign sum = presum;
|
||||
endgenerate
|
||||
|
||||
// shifts
|
||||
assign arith = alucontrol[3]; // sra
|
||||
assign w64 = alucontrol[4];
|
||||
assign right = (alucontrol[2:0] == 3'b101); // sra or srl
|
||||
shifter #(WIDTH) sh(a, b[5:0], right, arith, w64, shift);
|
||||
|
||||
// OR optionally passes zero when ALUControl[3] is set, supporting lui
|
||||
assign bor = alucontrol[3] ? b : a|b;
|
||||
|
||||
// condition code flags based on add/subtract output
|
||||
assign zero = (sum == 0);
|
||||
assign neg = sum[WIDTH-1];
|
||||
// overflow occurs when the numbers being added have the same sign
|
||||
// and the result has the opposite sign
|
||||
assign overflow = (a[WIDTH-1] ~^ condinvb[WIDTH-1]) & (a[WIDTH-1] ^ sum[WIDTH-1]);
|
||||
assign lt = neg ^ overflow;
|
||||
assign ltu = ~carry;
|
||||
assign flags = {zero, lt, ltu};
|
||||
|
||||
// slt
|
||||
assign slt = {{(WIDTH-1){1'b0}}, lt};
|
||||
assign sltu = {{(WIDTH-1){1'b0}}, ltu};
|
||||
|
||||
always_comb
|
||||
case (alucontrol[2:0])
|
||||
3'b000: result = sum; // add or sub
|
||||
3'b001: result = shift; // sll
|
||||
3'b010: result = slt; // slt
|
||||
3'b011: result = sltu; // sltu
|
||||
3'b100: result = a ^ b; // xor
|
||||
3'b101: result = shift; // sra or srl
|
||||
3'b110: result = bor; // or / pass through input b for lui
|
||||
3'b111: result = a & b; // and
|
||||
endcase
|
||||
|
||||
endmodule
|
||||
|
131
wally-pipelined/src/clint.sv
Normal file
131
wally-pipelined/src/clint.sv
Normal file
@ -0,0 +1,131 @@
|
||||
///////////////////////////////////////////
|
||||
// clint.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 14 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Core-Local Interruptor
|
||||
// See FE310-G002-Manual-v19p05 for specifications
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module clint #(parameter XLEN=32) (
|
||||
input logic clk, reset,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [7:0] ByteMaskM,
|
||||
input logic [15:0] AdrM,
|
||||
input logic [XLEN-1:0] WdM,
|
||||
output logic [XLEN-1:0] RdM,
|
||||
output logic TimerIntM, SwIntM);
|
||||
|
||||
logic [63:0] MTIMECMP, MTIME;
|
||||
logic MSIP;
|
||||
|
||||
logic [XLEN-1:0] read, write;
|
||||
logic [15:0] entry;
|
||||
logic memread, memwrite;
|
||||
|
||||
assign memread = MemRWM[1];
|
||||
assign memwrite = MemRWM[0];
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
if (XLEN==64)
|
||||
assign #2 entry = {AdrM[15:3], 3'b000};
|
||||
else
|
||||
assign #2 entry = {AdrM[15:2], 2'b00};
|
||||
endgenerate
|
||||
|
||||
|
||||
// register access
|
||||
generate
|
||||
if (XLEN==64) begin
|
||||
always_comb begin
|
||||
case(entry)
|
||||
16'h0000: read = {63'b0, MSIP};
|
||||
16'h4000: read = MTIMECMP;
|
||||
16'hBFF8: read = MTIME;
|
||||
default: read = 0;
|
||||
endcase
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
if (ByteMaskM[4]) write[39:32] = WdM[39:32];
|
||||
if (ByteMaskM[5]) write[47:40] = WdM[47:40];
|
||||
if (ByteMaskM[6]) write[55:48] = WdM[55:48];
|
||||
if (ByteMaskM[7]) write[63:56] = WdM[63:56];
|
||||
end
|
||||
always_ff @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
MSIP <= 0;
|
||||
MTIME <= 0;
|
||||
// MTIMECMP is not reset
|
||||
end else begin
|
||||
if (entry == 16'h0000) MSIP <= write[0];
|
||||
if (entry == 16'h4000) MTIMECMP <= write;
|
||||
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
|
||||
if (entry == 16'hBFF8) MTIME <= write;
|
||||
else MTIME <= MTIME + 1;
|
||||
end
|
||||
end else begin // 32-bit
|
||||
always_comb begin
|
||||
case(entry)
|
||||
16'h0000: read = {31'b0, MSIP};
|
||||
16'h4000: read = MTIMECMP[31:0];
|
||||
16'h4004: read = MTIMECMP[63:32];
|
||||
16'hBFF8: read = MTIME[31:0];
|
||||
16'hBFFC: read = MTIME[63:32];
|
||||
default: read = 0;
|
||||
endcase
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
end
|
||||
always_ff @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
MSIP <= 0;
|
||||
MTIME <= 0;
|
||||
// MTIMECMP is not reset
|
||||
end else begin
|
||||
if (entry == 16'h0000) MSIP <= write[0];
|
||||
if (entry == 16'h4000) MTIMECMP[31:0] <= write;
|
||||
if (entry == 16'h4004) MTIMECMP[63:32] <= write;
|
||||
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
|
||||
if (entry == 16'hBFF8) MTIME[31:0] <= write;
|
||||
else if (entry == 16'hBFFC) MTIME[63:32]<= write;
|
||||
else MTIME <= MTIME + 1;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// read
|
||||
assign RdM = memread ? read: 0;
|
||||
|
||||
// Software interrupt when MSIP is set
|
||||
assign SwIntM = MSIP;
|
||||
// Timer interrupt when MTIME >= MTIMECMP
|
||||
assign TimerIntM = ({1'b0, MTIME} >= {1'b0, MTIMECMP}); // unsigned comparison
|
||||
|
||||
endmodule
|
||||
|
171
wally-pipelined/src/controller.sv
Normal file
171
wally-pipelined/src/controller.sv
Normal file
@ -0,0 +1,171 @@
|
||||
///////////////////////////////////////////
|
||||
// controller.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Top level controller module
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
|
||||
module controller(
|
||||
input logic clk, reset,
|
||||
// Decode stage control signals
|
||||
input logic [6:0] OpD,
|
||||
input logic [2:0] Funct3D,
|
||||
input logic Funct7b5D,
|
||||
output logic [2:0] ImmSrcD,
|
||||
input logic StallD, FlushD,
|
||||
input logic IllegalCompInstrD,
|
||||
// Execute stage control signals
|
||||
input logic FlushE,
|
||||
input logic [2:0] FlagsE,
|
||||
output logic PCSrcE, // for datapath and Hazard Unit
|
||||
output logic [4:0] ALUControlE,
|
||||
output logic ALUSrcAE, ALUSrcBE,
|
||||
output logic TargetSrcE,
|
||||
output logic MemReadE, // for Hazard Unit
|
||||
// Memory stage control signals
|
||||
input logic FlushM,
|
||||
output logic [1:0] MemRWM,
|
||||
output logic CSRWriteM, PrivilegedM, IllegalInstrFaultM,
|
||||
output logic [2:0] Funct3M,
|
||||
output logic RegWriteM, // for Hazard Unit
|
||||
// Writeback stage control signals
|
||||
input logic FlushW,
|
||||
output logic RegWriteW, // for datapath and Hazard Unit
|
||||
output logic [1:0] ResultSrcW,
|
||||
output logic InstrValidW,
|
||||
// Stall during CSRs
|
||||
output logic CSRWritePendingDEM,
|
||||
// Exceptions
|
||||
input logic InstrAccessFaultF,
|
||||
output logic InstrAccessFaultM);
|
||||
|
||||
// pipelined control signals
|
||||
logic RegWriteD, RegWriteE;
|
||||
logic [1:0] ResultSrcD, ResultSrcE, ResultSrcM;
|
||||
logic [1:0] MemRWD, MemRWE;
|
||||
logic JumpD, JumpE;
|
||||
logic BranchD, BranchE;
|
||||
logic [1:0] ALUOpD;
|
||||
logic [4:0] ALUControlD;
|
||||
logic ALUSrcAD, ALUSrcBD;
|
||||
logic TargetSrcD, W64D;
|
||||
logic CSRWriteD, CSRWriteE;
|
||||
logic [2:0] Funct3E;
|
||||
logic InstrValidE, InstrValidM;
|
||||
logic PrivilegedD, PrivilegedE;
|
||||
logic InstrAccessFaultD, InstrAccessFaultE;
|
||||
logic IllegalInstrFaultD, IllegalInstrMergedD, IllegalInstrFaultE;
|
||||
logic [18:0] ControlsD;
|
||||
logic PreIllegalInstrFaultD;
|
||||
logic aluc3D;
|
||||
logic subD, sraD, sltD, sltuD;
|
||||
logic BranchTakenE;
|
||||
logic zeroE, ltE, ltuE;
|
||||
|
||||
// Decode stage pipeline control register and logic
|
||||
flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, InstrAccessFaultF, InstrAccessFaultD);
|
||||
|
||||
// Main Instruction Decoder
|
||||
always_comb
|
||||
case(OpD)
|
||||
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRWrite_Privileged_Illegal
|
||||
7'b0000011: ControlsD = 19'b1_000_01_10_01_0_00_0_0_0_0_0_0; // lw
|
||||
7'b0100011: ControlsD = 19'b0_001_01_01_00_0_00_0_0_0_0_0_0; // sw
|
||||
7'b0110011: ControlsD = 19'b1_000_00_00_00_0_10_0_0_0_0_0_0; // R-type
|
||||
7'b0111011: ControlsD = 19'b1_000_00_00_00_0_10_0_0_1_0_0_0; // R-type W instructions for RV64i
|
||||
7'b1100011: ControlsD = 19'b0_010_00_00_00_1_01_0_0_0_0_0_0; // beq
|
||||
7'b0010011: ControlsD = 19'b1_000_01_00_00_0_10_0_0_0_0_0_0; // I-type ALU
|
||||
7'b0011011: ControlsD = 19'b1_000_01_00_00_0_10_0_0_1_0_0_0; // IW-type ALU for RV64i
|
||||
7'b1101111: ControlsD = 19'b1_011_00_00_10_0_00_1_0_0_0_0_0; // jal
|
||||
7'b1100111: ControlsD = 19'b1_000_00_00_10_0_00_1_1_0_0_0_0; // jalr
|
||||
7'b0010111: ControlsD = 19'b1_100_11_00_00_0_00_0_0_0_0_0_0; // auipc
|
||||
7'b0110111: ControlsD = 19'b1_100_01_00_00_0_11_0_0_0_0_0_0; // lui
|
||||
7'b0001111: ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_0_0; // fence = nop
|
||||
7'b1110011: if (Funct3D == 3'b000)
|
||||
ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_1_0; // privileged; decoded further in priveleged modules
|
||||
else
|
||||
ControlsD = 19'b1_000_00_00_11_0_00_0_0_0_1_0_0; // csrs
|
||||
7'b0000000: ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_0_1; // illegal instruction
|
||||
default: ControlsD = 19'b0_000_00_00_00_0_00_0_0_0_0_0_1; // non-implemented instruction
|
||||
endcase
|
||||
|
||||
// unswizzle control bits
|
||||
// squash control signals if coming from an illegal compressed instruction
|
||||
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
||||
ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRWriteD,
|
||||
PrivilegedD, PreIllegalInstrFaultD} = ControlsD & ~IllegalCompInstrD;
|
||||
assign IllegalInstrFaultD = PreIllegalInstrFaultD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
|
||||
|
||||
// ALU Decoding
|
||||
assign sltD = (Funct3D == 3'b010);
|
||||
assign sltuD = (Funct3D == 3'b011);
|
||||
assign subD = (Funct3D == 3'b000 & Funct7b5D & OpD[5]);
|
||||
assign sraD = (Funct3D == 3'b101 & Funct7b5D);
|
||||
|
||||
assign aluc3D = subD | sraD | sltD | sltuD; // TRUE for R-type subtracts and sra, slt, sltu
|
||||
|
||||
always_comb
|
||||
case(ALUOpD)
|
||||
2'b00: ALUControlD = 5'b00000; // addition
|
||||
2'b01: ALUControlD = 5'b01000; // subtraction
|
||||
2'b11: ALUControlD = 5'b01110; // pass B through for lui
|
||||
default: ALUControlD = {W64D, aluc3D, Funct3D}; // R-type instructions
|
||||
endcase
|
||||
|
||||
// Execute stage pipeline control register and logic
|
||||
floprc #(23) controlregE(clk, reset, FlushE,
|
||||
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRWriteD, PrivilegedD, IllegalInstrFaultD, InstrAccessFaultD, Funct3D, 1'b1},
|
||||
{RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRWriteE, PrivilegedE, IllegalInstrFaultE, InstrAccessFaultE, Funct3E, InstrValidE});
|
||||
|
||||
|
||||
// Branch Logic
|
||||
assign {zeroE, ltE, ltuE} = FlagsE;
|
||||
|
||||
always_comb
|
||||
case(Funct3E)
|
||||
3'b000: BranchTakenE = zeroE; // beq
|
||||
3'b001: BranchTakenE = ~zeroE; // bne
|
||||
3'b100: BranchTakenE = ltE; // blt
|
||||
3'b101: BranchTakenE = ~ltE; // bge
|
||||
3'b110: BranchTakenE = ltuE; // bltu
|
||||
3'b111: BranchTakenE = ~ltuE; // bgeu
|
||||
default: BranchTakenE = 1'b0; // undefined mode
|
||||
endcase
|
||||
|
||||
assign PCSrcE = JumpE | BranchE & BranchTakenE;
|
||||
|
||||
assign MemReadE = MemRWE[1];
|
||||
|
||||
// Memory stage pipeline control register
|
||||
floprc #(13) controlregM(clk, reset, FlushM,
|
||||
{RegWriteE, ResultSrcE, MemRWE, CSRWriteE, PrivilegedE, IllegalInstrFaultE, InstrAccessFaultE, Funct3E, InstrValidE},
|
||||
{RegWriteM, ResultSrcM, MemRWM, CSRWriteM, PrivilegedM, IllegalInstrFaultM, InstrAccessFaultM, Funct3M, InstrValidM});
|
||||
|
||||
// Writeback stage pipeline control register
|
||||
floprc #(4) controlregW(clk, reset, FlushW,
|
||||
{RegWriteM, ResultSrcM, InstrValidM},
|
||||
{RegWriteW, ResultSrcW, InstrValidW});
|
||||
|
||||
assign CSRWritePendingDEM = CSRWriteD | CSRWriteE | CSRWriteM;
|
||||
endmodule
|
182
wally-pipelined/src/csr.sv
Normal file
182
wally-pipelined/src/csr.sv
Normal file
@ -0,0 +1,182 @@
|
||||
///////////////////////////////////////////
|
||||
// csr.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Counter Control and Status Registers
|
||||
// See RISC-V Privileged Mode Specification 20190608
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csr #(parameter XLEN = 64, MISA = 0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
input logic clk, reset,
|
||||
input logic [31:0] InstrM,
|
||||
input logic [XLEN-1:0] PCM, SrcAM,
|
||||
input logic CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
input logic InstrValidW, FloatRegWriteW, LoadStallD,
|
||||
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
|
||||
input logic [XLEN-1:0] CauseM, NextFaultMtvalM,
|
||||
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,
|
||||
output logic [XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic STATUS_MIE, STATUS_SIE,
|
||||
input logic [4:0] SetFflagsM,
|
||||
output logic [2:0] FRM_REGW,
|
||||
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
output logic [XLEN-1:0] CSRReadValM,
|
||||
output logic IllegalCSRAccessM
|
||||
);
|
||||
|
||||
logic [XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRNReadValM, CSRCReadValM;
|
||||
logic [XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM;
|
||||
|
||||
logic [XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW;
|
||||
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
|
||||
logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM;
|
||||
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
|
||||
logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM;
|
||||
|
||||
logic [XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
|
||||
|
||||
logic [XLEN-1:0] zero = 0;
|
||||
logic [XLEN-1:0] resetExceptionVector = {{(XLEN-32){1'b0}}, 32'h80000000}; // initial exception vector at reset
|
||||
|
||||
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;
|
||||
|
||||
generate
|
||||
if (`ZCSR_SUPPORTED) begin
|
||||
// modify CSRs
|
||||
always_comb begin
|
||||
// Choose either rs1 or uimm[4:0] as source
|
||||
CSRSrcM = InstrM[14] ? {{(XLEN-5){1'b0}}, InstrM[19:15]} : SrcAM;
|
||||
// Compute AND/OR modification
|
||||
CSRRWM = CSRSrcM;
|
||||
CSRRSM = CSRReadValM | CSRSrcM;
|
||||
CSRRCM = CSRReadValM & ~CSRSrcM;
|
||||
case (InstrM[13:12])
|
||||
2'b01: CSRWriteValM = CSRRWM;
|
||||
2'b10: CSRWriteValM = CSRRSM;
|
||||
2'b11: CSRWriteValM = CSRRCM;
|
||||
default: CSRWriteValM = CSRReadValM;
|
||||
endcase
|
||||
end
|
||||
|
||||
// write CSRs
|
||||
assign CSRAdrM = InstrM[31:20];
|
||||
assign UnalignedNextEPCM = TrapM ? PCM : 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;
|
||||
assign CSRMWriteM = CSRWriteM && (PrivilegeModeW == `M_MODE);
|
||||
assign CSRSWriteM = CSRWriteM && (PrivilegeModeW[0]);
|
||||
assign CSRUWriteM = CSRWriteM;
|
||||
|
||||
csri #(XLEN, MISA) csri(
|
||||
clk, reset, CSRMWriteM, CSRSWriteM, CSRAdrM, ExtIntM, TimerIntM, SwIntM,
|
||||
MIDELEG_REGW, MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, CSRWriteValM);
|
||||
|
||||
csrsr #(XLEN, MISA) csrsr(
|
||||
clk, reset,
|
||||
WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM, TrapM, FloatRegWriteW,
|
||||
NextPrivilegeModeM, PrivilegeModeW,
|
||||
mretM, sretM, uretM,
|
||||
CSRWriteValM,
|
||||
MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW,
|
||||
STATUS_MPP, STATUS_SPP, STATUS_TSR, STATUS_MIE, STATUS_SIE);
|
||||
|
||||
csrc #(XLEN, ZCOUNTERS) counters(
|
||||
clk, reset,
|
||||
InstrValidW, LoadStallD, CSRMWriteM, CSRAdrM, PrivilegeModeW, CSRWriteValM,
|
||||
MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
|
||||
CSRCReadValM, IllegalCSRCAccessM);
|
||||
|
||||
// Machine Mode CSRs
|
||||
csrm #(XLEN, MISA) csrm(
|
||||
clk, reset,
|
||||
CSRMWriteM, MTrapM, CSRAdrM,
|
||||
resetExceptionVector,
|
||||
NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW,
|
||||
CSRWriteValM, CSRMReadValM, MEPC_REGW, MTVEC_REGW, MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
|
||||
MEDELEG_REGW, MIDELEG_REGW, MIP_REGW, MIE_REGW, WriteMIPM, WriteMIEM, WriteMSTATUSM, IllegalCSRMAccessM
|
||||
);
|
||||
|
||||
csrs #(XLEN, MISA) csrs(
|
||||
clk, reset,
|
||||
CSRSWriteM, STrapM, CSRAdrM,
|
||||
resetExceptionVector,
|
||||
NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
||||
CSRWriteValM, CSRSReadValM, SEPC_REGW, STVEC_REGW, SCOUNTEREN_REGW,
|
||||
SEDELEG_REGW, SIDELEG_REGW, SIP_REGW, SIE_REGW, WriteSIPM, WriteSIEM, WriteSSTATUSM, IllegalCSRSAccessM
|
||||
);
|
||||
|
||||
csrn #(XLEN, MISA) csrn( // User Mode Exception Registers
|
||||
clk, reset,
|
||||
CSRUWriteM, UTrapM, CSRAdrM,
|
||||
resetExceptionVector,
|
||||
NextEPCM, NextCauseM, NextMtvalM, USTATUS_REGW,
|
||||
CSRWriteValM, CSRNReadValM, UEPC_REGW, UTVEC_REGW,
|
||||
UIP_REGW, UIE_REGW, WriteUIPM, WriteUIEM, WriteUSTATUSM, IllegalCSRNAccessM
|
||||
);
|
||||
|
||||
csru #(XLEN, MISA) csru( // Floating Point Flags are part of User MOde
|
||||
clk, reset, CSRUWriteM, CSRAdrM,
|
||||
CSRWriteValM, CSRUReadValM, SetFflagsM, FRM_REGW, IllegalCSRUAccessM
|
||||
);
|
||||
|
||||
// merge CSR Reads
|
||||
assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM | CSRNReadValM;
|
||||
|
||||
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
|
||||
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 && PrivilegeModeW != `M_MODE) ||
|
||||
(CSRAdrM[9:8] == 2'b01 && PrivilegeModeW == `U_MODE);
|
||||
assign IllegalCSRAccessM = (IllegalCSRCAccessM && IllegalCSRMAccessM &&
|
||||
IllegalCSRSAccessM && IllegalCSRUAccessM && IllegalCSRNAccessM ||
|
||||
InsufficientCSRPrivilegeM) && CSRWriteM;
|
||||
end else begin // CSRs not implemented
|
||||
assign STATUS_MPP = 2'b11;
|
||||
assign STATUS_SPP = 2'b0;
|
||||
assign STATUS_TSR = 0;
|
||||
assign MEPC_REGW = 0;
|
||||
assign SEPC_REGW = 0;
|
||||
assign UEPC_REGW = 0;
|
||||
assign UTVEC_REGW = 0;
|
||||
assign STVEC_REGW = 0;
|
||||
assign MTVEC_REGW = 0;
|
||||
assign MEDELEG_REGW = 0;
|
||||
assign MIDELEG_REGW = 0;
|
||||
assign SEDELEG_REGW = 0;
|
||||
assign SIDELEG_REGW = 0;
|
||||
assign MIP_REGW = 0;
|
||||
assign MIE_REGW = 0;
|
||||
assign STATUS_MIE = 0;
|
||||
assign STATUS_SIE = 0;
|
||||
assign FRM_REGW = 0;
|
||||
assign CSRReadValM = 0;
|
||||
assign IllegalCSRAccessM = CSRWriteM;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
226
wally-pipelined/src/csrc.sv
Normal file
226
wally-pipelined/src/csrc.sv
Normal file
@ -0,0 +1,226 @@
|
||||
///////////////////////////////////////////
|
||||
// csrc.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Counter CSRs
|
||||
// See RISC-V Privileged Mode Specification 20190608 3.1.10-11
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csrc #(parameter XLEN=64, ZCOUNTERS = 1,
|
||||
MCYCLE = 12'hB00,
|
||||
// MTIME = 12'hB01, // address not specified in privileged spec. Consider moving to CLINT to match SiFive
|
||||
// MTIMECMP = 12'hB21, // not specified in privileged spec. Move to CLINT
|
||||
MINSTRET = 12'hB02,
|
||||
MHPMCOUNTER3 = 12'hB03,
|
||||
MHPMCOUNTER4 = 12'hB04,
|
||||
// ... more counters
|
||||
MHPMCOUNTER31 = 12'hB1F,
|
||||
MCYCLEH = 12'hB80,
|
||||
// MTIMEH = 12'hB81, // address not specified in privileged spec. Consider moving to CLINT to match SiFive
|
||||
// MTIMECMPH = 12'hBA1, // not specified in privileged spec. Move to CLINT
|
||||
MINSTRETH = 12'hB82,
|
||||
MHPMCOUNTER3H = 12'hB83,
|
||||
MHPMCOUNTER4H = 12'hB84,
|
||||
// ... more counters
|
||||
MHPMCOUNTER31H = 12'hB9F,
|
||||
MCOUNTERINHIBIT = 12'h320,
|
||||
MHPMEVENT3 = 12'h323,
|
||||
MHPMEVENT4 = 12'h324,
|
||||
// ... more counters
|
||||
MHPMEVENT31 = 12'h33F,
|
||||
CYCLE = 12'hC00,
|
||||
// TIME = 12'hC01, // not specified
|
||||
INSTRET = 12'hC02,
|
||||
HPMCOUNTER3 = 12'hC03,
|
||||
HPMCOUNTER4 = 12'hC04,
|
||||
// ...more counters
|
||||
HPMCOUNTER31 = 12'hC1F,
|
||||
CYCLEH = 12'hC80,
|
||||
// TIMEH = 12'hC81, // not specified
|
||||
INSTRETH = 12'hC82,
|
||||
HPMCOUNTER3H = 12'hC83,
|
||||
HPMCOUNTER4H = 12'hC84,
|
||||
// ... more counters
|
||||
HPMCOUNTER31H = 12'hC9F
|
||||
) (
|
||||
input logic clk, reset,
|
||||
input logic InstrValidW, LoadStallD, CSRMWriteM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [XLEN-1:0] CSRWriteValM,
|
||||
input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
|
||||
output logic [XLEN-1:0] CSRCReadValM,
|
||||
output logic IllegalCSRCAccessM
|
||||
);
|
||||
|
||||
generate
|
||||
if (`ZCOUNTERS_SUPPORTED) begin
|
||||
// logic [63:0] TIME_REGW, TIMECMP_REGW;
|
||||
logic [63:0] CYCLE_REGW, INSTRET_REGW;
|
||||
logic [63:0] HPMCOUNTER3_REGW, HPMCOUNTER4_REGW; // add more performance counters here if desired
|
||||
logic [63:0] CYCLEPlusM, TIMEPlusM, INSTRETPlusM;
|
||||
logic [63:0] HPMCOUNTER3PlusM, HPMCOUNTER4PlusM;
|
||||
// logic [XLEN-1:0] NextTIMEM;
|
||||
logic [XLEN-1:0] NextCYCLEM, NextINSTRETM;
|
||||
logic [XLEN-1:0] NextHPMCOUNTER3M, NextHPMCOUNTER4M;
|
||||
logic WriteTIMEM, WriteTIMECMPM, WriteCYCLEM, WriteINSTRETM;
|
||||
logic WriteHPMCOUNTER3M, WriteHPMCOUNTER4M;
|
||||
logic [4:0] CounterNumM;
|
||||
|
||||
// Write enables
|
||||
// assign WriteTIMEM = CSRMWriteM && (CSRAdrM == MTIME);
|
||||
// assign WriteTIMECMPM = CSRMWriteM && (CSRAdrM == MTIMECMP);
|
||||
assign WriteCYCLEM = CSRMWriteM && (CSRAdrM == MCYCLE);
|
||||
assign WriteINSTRETM = CSRMWriteM && (CSRAdrM == MINSTRET);
|
||||
assign WriteHPMCOUNTER3M = CSRMWriteM && (CSRAdrM == MHPMCOUNTER3);
|
||||
assign WriteHPMCOUNTER4M = CSRMWriteM && (CSRAdrM == MHPMCOUNTER4);
|
||||
|
||||
// Counter adders with inhibits for power savings
|
||||
assign CYCLEPlusM = CYCLE_REGW + {63'b0, ~MCOUNTINHIBIT_REGW[0]};
|
||||
// assign TIMEPlusM = TIME_REGW + 1; // can't be inhibited
|
||||
assign INSTRETPlusM = INSTRET_REGW + {63'b0, InstrValidW & ~MCOUNTINHIBIT_REGW[2]};
|
||||
assign HPMCOUNTER3PlusM = HPMCOUNTER3_REGW + {63'b0, LoadStallD & ~MCOUNTINHIBIT_REGW[3]}; // count load stalls
|
||||
assign HPMCOUNTER4PlusM = HPMCOUNTER4_REGW + {63'b0, 1'b0 & ~MCOUNTINHIBIT_REGW[4]}; // change to count signals
|
||||
assign NextCYCLEM = WriteCYCLEM ? CSRWriteValM : CYCLEPlusM[XLEN-1:0];
|
||||
// assign NextTIMEM = WriteTIMEM ? CSRWriteValM : TIMEPlusM[XLEN-1:0];
|
||||
assign NextINSTRETM = WriteINSTRETM ? CSRWriteValM : INSTRETPlusM[XLEN-1:0];
|
||||
assign NextHPMCOUNTER3M = WriteHPMCOUNTER3M ? CSRWriteValM : HPMCOUNTER3PlusM[XLEN-1:0];
|
||||
assign NextHPMCOUNTER4M = WriteHPMCOUNTER4M ? CSRWriteValM : HPMCOUNTER4PlusM[XLEN-1:0];
|
||||
|
||||
// Write / update counters
|
||||
// Only the Machine mode versions of the counter CSRs are writable
|
||||
if (XLEN==64) begin// 64-bit counters
|
||||
// flopr #(64) TIMEreg(clk, reset, WriteTIMEM ? CSRWriteValM : TIME_REGW + 1, TIME_REGW); // may count off a different clock***
|
||||
// flopenr #(64) TIMECMPreg(clk, reset, WriteTIMECMPM, CSRWriteValM, TIMECMP_REGW);
|
||||
flopr #(64) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_REGW);
|
||||
flopr #(64) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW);
|
||||
flopr #(64) HPMCOUNTER3reg(clk, reset, NextHPMCOUNTER3M, HPMCOUNTER3_REGW);
|
||||
flopr #(64) HPMCOUNTER4reg(clk, reset, NextHPMCOUNTER4M, HPMCOUNTER4_REGW);
|
||||
end else begin // 32-bit low and high counters
|
||||
logic WriteTIMEHM, WriteTIMECMPHM, WriteCYCLEHM, WriteINSTRETHM;
|
||||
logic WriteHPMCOUNTER3HM, WriteHPMCOUNTER4HM;
|
||||
logic [XLEN-1:0] NextCYCLEHM, NextTIMEHM, NextINSTRETHM;
|
||||
logic [XLEN-1:0] NextHPMCOUNTER3HM, NextHPMCOUNTER4HM;
|
||||
|
||||
// Write Enables
|
||||
// assign WriteTIMEHM = CSRMWriteM && (CSRAdrM == MTIMEH);
|
||||
// assign WriteTIMECMPHM = CSRMWriteM && (CSRAdrM == MTIMECMPH);
|
||||
assign WriteCYCLEHM = CSRMWriteM && (CSRAdrM == MCYCLEH);
|
||||
assign WriteINSTRETHM = CSRMWriteM && (CSRAdrM == MINSTRETH);
|
||||
assign WriteHPMCOUNTER3HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER3H);
|
||||
assign WriteHPMCOUNTER4HM = CSRMWriteM && (CSRAdrM == MHPMCOUNTER4H);
|
||||
assign NextCYCLEHM = WriteCYCLEM ? CSRWriteValM : CYCLEPlusM[63:32];
|
||||
// assign NextTIMEHM = WriteTIMEHM ? CSRWriteValM : TIMEPlusM[63:32];
|
||||
assign NextINSTRETHM = WriteINSTRETHM ? CSRWriteValM : INSTRETPlusM[63:32];
|
||||
assign NextHPMCOUNTER3HM = WriteHPMCOUNTER3HM ? CSRWriteValM : HPMCOUNTER3PlusM[63:32];
|
||||
assign NextHPMCOUNTER4HM = WriteHPMCOUNTER4HM ? CSRWriteValM : HPMCOUNTER4PlusM[63:32];
|
||||
|
||||
// Counter CSRs
|
||||
// flopr #(32) TIMEreg(clk, reset, NextTIMEM, TIME_REGW); // may count off a different clock***
|
||||
// flopenr #(32) TIMECMPreg(clk, reset, WriteTIMECMPM, CSRWriteValM, TIMECMP_REGW[31:0]);
|
||||
flopr #(32) CYCLEreg(clk, reset, NextCYCLEM, CYCLE_REGW[31:0]);
|
||||
flopr #(32) INSTRETreg(clk, reset, NextINSTRETM, INSTRET_REGW[31:0]);
|
||||
flopr #(32) HPMCOUNTER3reg(clk, reset, NextHPMCOUNTER3M, HPMCOUNTER3_REGW[31:0]);
|
||||
flopr #(32) HPMCOUNTER4reg(clk, reset, NextHPMCOUNTER4M, HPMCOUNTER4_REGW[31:0]);
|
||||
// flopr #(32) TIMEHreg(clk, reset, NextTIMEHM, TIME_REGW); // may count off a different clock***
|
||||
// flopenr #(32) TIMECMPHreg(clk, reset, WriteTIMECMPHM, CSRWriteValM, TIMECMP_REGW[63:32]);
|
||||
flopr #(32) CYCLEHreg(clk, reset, NextCYCLEHM, CYCLE_REGW[63:32]);
|
||||
flopr #(32) INSTRETHreg(clk, reset, NextINSTRETHM, INSTRET_REGW[63:32]);
|
||||
flopr #(32) HPMCOUNTER3Hreg(clk, reset, NextHPMCOUNTER3HM, HPMCOUNTER3_REGW[63:32]);
|
||||
flopr #(32) HPMCOUNTER4Hreg(clk, reset, NextHPMCOUNTER4HM, HPMCOUNTER4_REGW[63:32]);
|
||||
end
|
||||
|
||||
// eventually move TIME and TIMECMP to the CLINT
|
||||
// run TIME off asynchronous reference clock
|
||||
// synchronize write enable to TIME
|
||||
// four phase handshake to synchronize reads from TIME
|
||||
|
||||
// interrupt on timer compare
|
||||
// ability to disable optional CSRs
|
||||
|
||||
// Read Counters, or cause excepiton if insufficient privilege in light of COUNTEREN flags
|
||||
assign CounterNumM = CSRAdrM[4:0]; // which counter to read?
|
||||
if (XLEN==64) // 64-bit counter reads
|
||||
always_comb
|
||||
if (PrivilegeModeW == `M_MODE ||
|
||||
MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin
|
||||
IllegalCSRCAccessM = 0;
|
||||
case (CSRAdrM)
|
||||
// MTIME: CSRCReadValM = TIME_REGW;
|
||||
// MTIMECMP: CSRCReadValM = TIMECMP_REGW;
|
||||
MCYCLE: CSRCReadValM = CYCLE_REGW;
|
||||
MINSTRET: CSRCReadValM = INSTRET_REGW;
|
||||
MHPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW;
|
||||
MHPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW;
|
||||
// TIME: CSRCReadValM = TIME_REGW;
|
||||
CYCLE: CSRCReadValM = CYCLE_REGW;
|
||||
INSTRET: CSRCReadValM = INSTRET_REGW;
|
||||
HPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW;
|
||||
HPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW;
|
||||
default: begin
|
||||
CSRCReadValM = 0;
|
||||
IllegalCSRCAccessM = 1;
|
||||
end
|
||||
endcase
|
||||
end else IllegalCSRCAccessM = 1; // no privileges for this coute
|
||||
else // 32-bit counter reads
|
||||
always_comb
|
||||
if (PrivilegeModeW == `M_MODE ||
|
||||
MCOUNTEREN_REGW[CounterNumM] && (PrivilegeModeW == `S_MODE || SCOUNTEREN_REGW[CounterNumM])) begin
|
||||
IllegalCSRCAccessM = 0;
|
||||
case (CSRAdrM)
|
||||
// MTIME: CSRCReadValM = TIME_REGW[31:0];
|
||||
// MTIMECMP: CSRCReadValM = TIMECMP_REGW[31:0];
|
||||
MCYCLE: CSRCReadValM = CYCLE_REGW[31:0];
|
||||
MINSTRET: CSRCReadValM = INSTRET_REGW[31:0];
|
||||
MHPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW[31:0];
|
||||
MHPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW[31:0];
|
||||
// TIME: CSRCReadValM = TIME_REGW[31:0];
|
||||
CYCLE: CSRCReadValM = CYCLE_REGW[31:0];
|
||||
INSTRET: CSRCReadValM = INSTRET_REGW[31:0];
|
||||
HPMCOUNTER3: CSRCReadValM = HPMCOUNTER3_REGW[31:0];
|
||||
HPMCOUNTER4: CSRCReadValM = HPMCOUNTER4_REGW[31:0];
|
||||
// MTIMEH: CSRCReadValM = TIME_REGW[63:32];
|
||||
// MTIMECMPH: CSRCReadValM = TIMECMP_REGW[63:32];
|
||||
MCYCLEH: CSRCReadValM = CYCLE_REGW[63:32];
|
||||
MINSTRETH: CSRCReadValM = INSTRET_REGW[63:32];
|
||||
MHPMCOUNTER3H: CSRCReadValM = HPMCOUNTER3_REGW[63:32];
|
||||
MHPMCOUNTER4H: CSRCReadValM = HPMCOUNTER4_REGW[63:32];
|
||||
// TIMEH: CSRCReadValM = TIME_REGW[63:32];
|
||||
CYCLEH: CSRCReadValM = CYCLE_REGW[63:32];
|
||||
INSTRETH: CSRCReadValM = INSTRET_REGW[63:32];
|
||||
HPMCOUNTER3H: CSRCReadValM = HPMCOUNTER3_REGW[63:32];
|
||||
HPMCOUNTER4H: CSRCReadValM = HPMCOUNTER4_REGW[63:32];
|
||||
default: begin
|
||||
CSRCReadValM = 0;
|
||||
IllegalCSRCAccessM = 1;
|
||||
end
|
||||
endcase
|
||||
end else IllegalCSRCAccessM = 1;
|
||||
end else begin
|
||||
assign CSRCReadValM = 0;
|
||||
assign IllegalCSRCAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
121
wally-pipelined/src/csri.sv
Normal file
121
wally-pipelined/src/csri.sv
Normal file
@ -0,0 +1,121 @@
|
||||
///////////////////////////////////////////
|
||||
// csri.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Interrupt Control & Status Registers (IP, EI)
|
||||
// See RISC-V Privileged Mode Specification 20190608 & 20210108 draft
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csri #(parameter XLEN=64, MISA=0,
|
||||
// Machine CSRs
|
||||
MIE = 12'h304,
|
||||
MIP = 12'h344,
|
||||
SIE = 12'h104,
|
||||
SIP = 12'h144) (
|
||||
input logic clk, reset,
|
||||
input logic CSRMWriteM, CSRSWriteM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic ExtIntM, TimerIntM, SwIntM,
|
||||
input logic [XLEN-1:0] MIDELEG_REGW,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
|
||||
input logic [XLEN-1:0] CSRWriteValM
|
||||
);
|
||||
|
||||
logic [11:0] IntInM, IP_REGW, IE_REGW;
|
||||
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK;
|
||||
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
|
||||
logic [XLEN-1:0] zero = 0;
|
||||
|
||||
// Determine which interrupts need to be set
|
||||
// assumes no N-mode user interrupts
|
||||
|
||||
always_comb begin
|
||||
IntInM = 0;
|
||||
IntInM[11] = ExtIntM & ~MIDELEG_REGW[9]; // MEIP
|
||||
IntInM[9] = ExtIntM & MIDELEG_REGW[9]; // SEIP
|
||||
IntInM[7] = TimerIntM & ~MIDELEG_REGW[5]; // MTIP
|
||||
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
|
||||
IntInM[3] = SwIntM & ~MIDELEG_REGW[1]; // MSIP
|
||||
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
|
||||
end
|
||||
|
||||
// Interrupt Write Enables
|
||||
assign WriteMIPM = CSRMWriteM && (CSRAdrM == MIP);
|
||||
assign WriteMIEM = CSRMWriteM && (CSRAdrM == MIE);
|
||||
assign WriteSIPM = CSRSWriteM && (CSRAdrM == SIP);
|
||||
assign WriteSIEM = CSRSWriteM && (CSRAdrM == SIE);
|
||||
|
||||
// Interrupt Pending and Enable Registers
|
||||
// MEIP, MTIP, MSIP are read-only
|
||||
// SEIP, STIP, SSIP is writable in MIP if S mode exists
|
||||
// SSIP is writable in SIP if S mode exists
|
||||
generate
|
||||
if (`S_SUPPORTED) begin
|
||||
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9)
|
||||
assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
|
||||
end else begin
|
||||
assign MIP_WRITE_MASK = 12'h000;
|
||||
assign SIP_WRITE_MASK = 12'h000;
|
||||
end
|
||||
always @(posedge clk, posedge reset) begin
|
||||
if (reset) IP_REGW = zero;
|
||||
else if (WriteMIPM) IP_REGW = (CSRWriteValM & MIP_WRITE_MASK) | IntInM; // MTIP unclearable
|
||||
else if (WriteSIPM) IP_REGW = (CSRWriteValM & SIP_WRITE_MASK) | IntInM; // MTIP unclearable
|
||||
// else if (WriteUIPM) IP_REGW = (CSRWriteValM & 12'hBBB) | (NextIPM & 12'h080); // MTIP unclearable
|
||||
else IP_REGW = IP_REGW | IntInM; // *** check this turns off interrupts properly even when MIDELEG changes
|
||||
end
|
||||
always @(posedge clk, posedge reset) begin
|
||||
if (reset) IE_REGW = zero;
|
||||
else if (WriteMIEM) IE_REGW = (CSRWriteValM & 12'hAAA); // MIE controls M and S fields
|
||||
else if (WriteSIEM) IE_REGW = (CSRWriteValM & 12'h222) | (IE_REGW & 12'h888); // only S fields
|
||||
// else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// restricted views of registers
|
||||
generate
|
||||
always_comb begin
|
||||
// Machine Mode
|
||||
MIP_REGW = IP_REGW;
|
||||
MIE_REGW = IE_REGW;
|
||||
|
||||
// Supervisor mode
|
||||
if (`S_SUPPORTED) begin
|
||||
SIP_REGW = IP_REGW & MIDELEG_REGW & 'h222; // only delegated interrupts visible
|
||||
SIE_REGW = IE_REGW & MIDELEG_REGW & 'h222;
|
||||
end else begin
|
||||
SIP_REGW = zero;
|
||||
SIE_REGW = zero;
|
||||
end
|
||||
|
||||
// User Modes iterrupts depricated
|
||||
/*if (`U_SUPPORTED & `N_SUPPORTED) begin
|
||||
UIP_REGW = IP_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible
|
||||
UIE_REGW = IE_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible
|
||||
end else begin
|
||||
UIP_REGW = zero;
|
||||
UIE_REGW = zero;
|
||||
end */
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
156
wally-pipelined/src/csrm.sv
Normal file
156
wally-pipelined/src/csrm.sv
Normal file
@ -0,0 +1,156 @@
|
||||
///////////////////////////////////////////
|
||||
// csrm.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Machine-Mode Control and Status Registers
|
||||
// See RISC-V Privileged Mode Specification 20190608
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csrm #(parameter XLEN=64, MISA=0,
|
||||
// Machine CSRs
|
||||
MVENDORID = 12'hF11,
|
||||
MARCHID = 12'hF12,
|
||||
MIMPID = 12'hF13,
|
||||
MHARTID = 12'hF14,
|
||||
MSTATUS = 12'h300,
|
||||
MISA_ADR = 12'h301,
|
||||
MEDELEG = 12'h302,
|
||||
MIDELEG = 12'h303,
|
||||
MIE = 12'h304,
|
||||
MTVEC = 12'h305,
|
||||
MCOUNTEREN = 12'h306,
|
||||
MSTATUSH = 12'h310,
|
||||
MCOUNTINHIBIT = 12'h320,
|
||||
MSCRATCH = 12'h340,
|
||||
MEPC = 12'h341,
|
||||
MCAUSE = 12'h342,
|
||||
MTVAL = 12'h343,
|
||||
MIP = 12'h344,
|
||||
PMPCFG0 = 12'h3A0,
|
||||
PMPCFG1 = 12'h3A1,
|
||||
PMPCFG2 = 12'h3A2,
|
||||
PMPCFG3 = 12'h3A3,
|
||||
PMPADDR0 = 12'h3B0,
|
||||
//... more physical memory protection
|
||||
PMPADDR15 = 12'h3BF,
|
||||
TSELECT = 12'h7A0,
|
||||
TDATA1 = 12'h7A1,
|
||||
TDATA2 = 12'h7A2,
|
||||
TDATA3 = 12'h7A3,
|
||||
DCSR = 12'h7B0,
|
||||
DPC = 12'h7B1,
|
||||
DSCRATCH0 = 12'h7B2,
|
||||
DSCRATCH1 = 12'h7B3) (
|
||||
input logic clk, reset,
|
||||
input logic CSRMWriteM, MTrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [XLEN-1:0] resetExceptionVector,
|
||||
input logic [XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW,
|
||||
input logic [XLEN-1:0] CSRWriteValM,
|
||||
output logic [XLEN-1:0] CSRMReadValM, MEPC_REGW, MTVEC_REGW,
|
||||
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
|
||||
output logic [XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW,
|
||||
input logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic WriteMIPM, WriteMIEM,
|
||||
output logic WriteMSTATUSM,
|
||||
output logic IllegalCSRMAccessM
|
||||
);
|
||||
|
||||
logic [XLEN-1:0] MISA_REGW;
|
||||
logic [XLEN-1:0] MSCRATCH_REGW,MCAUSE_REGW, MTVAL_REGW;
|
||||
logic [XLEN-1:0] zero = 0;
|
||||
logic [31:0] allones = {32{1'b1}};
|
||||
logic [XLEN-1:0] MEDELEG_MASK = ~(zero | 1'b1 << 11); // medeleg[11] hardwired to zero per Privileged Spec 3.1.8
|
||||
logic [XLEN-1:0] MIDELEG_MASK = {{(XLEN-12){1'b0}}, 12'h222}; // only allow delegating interrupts to supervisor mode
|
||||
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
|
||||
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
|
||||
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
|
||||
|
||||
// MISA is hardwired. Spec says it could be written to disable features, but this is not supported by Wally
|
||||
assign MISA_REGW = {(XLEN == 32 ? 2'b01 : 2'b10), {(XLEN-28){1'b0}}, MISA[25:0]};
|
||||
|
||||
// Write machine Mode CSRs
|
||||
assign WriteMSTATUSM = CSRMWriteM && (CSRAdrM == MSTATUS);
|
||||
assign WriteMTVECM = CSRMWriteM && (CSRAdrM == MTVEC);
|
||||
assign WriteMEDELEGM = CSRMWriteM && (CSRAdrM == MEDELEG);
|
||||
assign WriteMIDELEGM = CSRMWriteM && (CSRAdrM == MIDELEG);
|
||||
assign WriteMIPM = CSRMWriteM && (CSRAdrM == MIP);
|
||||
assign WriteMIEM = CSRMWriteM && (CSRAdrM == MIE);
|
||||
assign WriteMSCRATCHM = CSRMWriteM && (CSRAdrM == MSCRATCH);
|
||||
assign WriteMEPCM = MTrapM | (CSRMWriteM && (CSRAdrM == MEPC));
|
||||
assign WriteMCAUSEM = MTrapM | (CSRMWriteM && (CSRAdrM == MCAUSE));
|
||||
assign WriteMTVALM = MTrapM | (CSRMWriteM && (CSRAdrM == MTVAL));
|
||||
assign WriteMCOUNTERENM = CSRMWriteM && (CSRAdrM == MCOUNTEREN);
|
||||
assign WriteMCOUNTINHIBITM = CSRMWriteM && (CSRAdrM == MCOUNTINHIBIT);
|
||||
|
||||
// CSRs
|
||||
flopenl #(XLEN) MTVECreg(clk, reset, WriteMTVECM, CSRWriteValM, resetExceptionVector, MTVEC_REGW);
|
||||
generate
|
||||
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist
|
||||
flopenl #(XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, zero, MEDELEG_REGW);
|
||||
flopenl #(XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK, zero, MIDELEG_REGW);
|
||||
end else begin
|
||||
assign MEDELEG_REGW = 0;
|
||||
assign MIDELEG_REGW = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// flopenl #(XLEN) MIPreg(clk, reset, WriteMIPM, CSRWriteValM, zero, MIP_REGW);
|
||||
// flopenl #(XLEN) MIEreg(clk, reset, WriteMIEM, CSRWriteValM, zero, MIE_REGW);
|
||||
flopenr #(XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW);
|
||||
flopenr #(XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);
|
||||
flopenl #(XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, zero, MCAUSE_REGW);
|
||||
flopenr #(XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
|
||||
flopenl #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], allones, MCOUNTEREN_REGW);
|
||||
flopenl #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], allones, MCOUNTINHIBIT_REGW);
|
||||
|
||||
// Read machine mode CSRs
|
||||
always_comb begin
|
||||
IllegalCSRMAccessM = !(`S_SUPPORTED | `U_SUPPORTED & `N_SUPPORTED) &&
|
||||
(CSRAdrM == MEDELEG || CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
|
||||
case (CSRAdrM)
|
||||
MISA_ADR: CSRMReadValM = MISA_REGW;
|
||||
MVENDORID: CSRMReadValM = 0;
|
||||
MARCHID: CSRMReadValM = 0;
|
||||
MIMPID: CSRMReadValM = 'h100; // pipelined implementation
|
||||
MHARTID: CSRMReadValM = 0;
|
||||
MSTATUS: CSRMReadValM = MSTATUS_REGW;
|
||||
MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported
|
||||
MTVEC: CSRMReadValM = MTVEC_REGW;
|
||||
MEDELEG: CSRMReadValM = MEDELEG_REGW;
|
||||
MIDELEG: CSRMReadValM = MIDELEG_REGW;
|
||||
MIP: CSRMReadValM = {{(XLEN-12){1'b0}}, MIP_REGW};
|
||||
MIE: CSRMReadValM = {{(XLEN-12){1'b0}}, MIE_REGW};
|
||||
MSCRATCH: CSRMReadValM = MSCRATCH_REGW;
|
||||
MEPC: CSRMReadValM = MEPC_REGW;
|
||||
MCAUSE: CSRMReadValM = MCAUSE_REGW;
|
||||
MTVAL: CSRMReadValM = MTVAL_REGW;
|
||||
MCOUNTEREN:CSRMReadValM = {{(XLEN-32){1'b0}}, MCOUNTEREN_REGW};
|
||||
MCOUNTINHIBIT:CSRMReadValM = {{(XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
|
||||
default: begin
|
||||
CSRMReadValM = 0;
|
||||
IllegalCSRMAccessM = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
108
wally-pipelined/src/csrn.sv
Normal file
108
wally-pipelined/src/csrn.sv
Normal file
@ -0,0 +1,108 @@
|
||||
///////////////////////////////////////////
|
||||
// csrn.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: User-Mode Control and Status Registers for User Mode Exceptions
|
||||
// See RISC-V Privileged Mode Specification 20190608 Table 2.2
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csrn #(parameter XLEN=64, MISA=0,
|
||||
USTATUS =12'h000,
|
||||
UIE = 12'h004,
|
||||
UTVEC = 12'h005,
|
||||
USCRATCH = 12'h040,
|
||||
UEPC = 12'h041,
|
||||
UCAUSE = 12'h042,
|
||||
UTVAL = 12'h043,
|
||||
UIP = 12'h044) (
|
||||
input logic clk, reset,
|
||||
input logic CSRUWriteM, UTrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [XLEN-1:0] resetExceptionVector,
|
||||
input logic [XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, USTATUS_REGW,
|
||||
input logic [XLEN-1:0] CSRWriteValM,
|
||||
output logic [XLEN-1:0] CSRUReadValM, UEPC_REGW, UTVEC_REGW,
|
||||
input logic [11:0] UIP_REGW, UIE_REGW,
|
||||
output logic WriteUIPM, WriteUIEM,
|
||||
output logic WriteUSTATUSM,
|
||||
output logic IllegalCSRUAccessM
|
||||
);
|
||||
|
||||
logic [XLEN-1:0] zero = 0;
|
||||
|
||||
// *** add floating point CSRs here. Maybe move stuff below to csrn to support reading
|
||||
|
||||
// User mode CSRs below only needed when user mode traps are supported
|
||||
generate
|
||||
if (`N_SUPPORTED) begin
|
||||
logic WriteUTVECM;
|
||||
logic WriteUSCRATCHM, WriteUEPCM;
|
||||
logic WriteUCAUSEM, WriteUTVALM;
|
||||
logic [XLEN-1:0] UEDELEG_REGW, UIDELEG_REGW, UIP_REGW, UIE_REGW;
|
||||
logic [XLEN-1:0] USCRATCH_REGW, UCAUSE_REGW, UTVAL_REGW;
|
||||
|
||||
// Write enables
|
||||
assign WriteUSTATUSM = CSRUWriteM && (CSRAdrM == USTATUS);
|
||||
assign WriteUTVECM = CSRUWriteM && (CSRAdrM == UTVEC);
|
||||
assign WriteUIPM = CSRUWriteM && (CSRAdrM == UIP);
|
||||
assign WriteUIEM = CSRUWriteM && (CSRAdrM == UIE);
|
||||
assign WriteUEPCM = UTrapM | (CSRUWriteM && (CSRAdrM == UEPC));
|
||||
assign WriteUCAUSEM = UTrapM | (CSRUWriteM && (CSRAdrM == UCAUSE));
|
||||
assign WriteUTVALM = UTrapM | (CSRUWriteM && (CSRAdrM == UTVAL));
|
||||
|
||||
// CSRs
|
||||
flopenl #(XLEN) UTVECreg(clk, reset, WriteUTVECM, CSRWriteValM, resetExceptionVector, UTVEC_REGW);
|
||||
// flopenl #(XLEN) UIPreg(clk, reset, WriteUIPM, CSRWriteValM, zero, UIP_REGW);
|
||||
// flopenl #(XLEN) UIEreg(clk, reset, WriteUIEM, CSRWriteValM, zero, UIE_REGW);
|
||||
flopenr #(XLEN) USCRATCHreg(clk, reset, WriteUSCRATCHM, CSRWriteValM, USCRATCH_REGW);
|
||||
flopenr #(XLEN) UEPCreg(clk, reset, WriteUEPCM, NextEPCM, UEPC_REGW);
|
||||
flopenr #(XLEN) UCAUSEreg(clk, reset, WriteUCAUSEM, NextCauseM, UCAUSE_REGW);
|
||||
flopenr #(XLEN) UTVALreg(clk, reset, WriteUTVALM, NextMtvalM, UTVAL_REGW);
|
||||
|
||||
// CSR Reads
|
||||
always_comb begin
|
||||
IllegalCSRUAccessM = 0;
|
||||
case (CSRAdrM)
|
||||
USTATUS: CSRUReadValM = USTATUS_REGW;
|
||||
UTVEC: CSRUReadValM = UTVEC_REGW;
|
||||
UIP: CSRUReadValM = {{(XLEN-12){1'b0}}, UIP_REGW};
|
||||
UIE: CSRUReadValM = {{(XLEN-12){1'b0}}, UIE_REGW};
|
||||
USCRATCH: CSRUReadValM = USCRATCH_REGW;
|
||||
UEPC: CSRUReadValM = UEPC_REGW;
|
||||
UCAUSE: CSRUReadValM = UCAUSE_REGW;
|
||||
UTVAL: CSRUReadValM = UTVAL_REGW;
|
||||
default: begin
|
||||
CSRUReadValM = 0;
|
||||
IllegalCSRUAccessM = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin // if not supported
|
||||
assign WriteUSTATUSM = 0;
|
||||
assign CSRUReadValM = 0;
|
||||
assign UEPC_REGW = 0;
|
||||
assign UTVEC_REGW = 0;
|
||||
assign IllegalCSRUAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
126
wally-pipelined/src/csrs.sv
Normal file
126
wally-pipelined/src/csrs.sv
Normal file
@ -0,0 +1,126 @@
|
||||
///////////////////////////////////////////
|
||||
// csrs.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Supervisor-Mode Control and Status Registers
|
||||
// See RISC-V Privileged Mode Specification 20190608
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csrs #(parameter XLEN=64, MISA=0,
|
||||
// Supervisor CSRs
|
||||
SSTATUS = 12'h100,
|
||||
SEDELEG = 12'h102,
|
||||
SIDELEG = 12'h103,
|
||||
SIE = 12'h104,
|
||||
STVEC = 12'h105,
|
||||
SCOUNTEREN = 12'h106,
|
||||
SSCRATCH = 12'h140,
|
||||
SEPC = 12'h141,
|
||||
SCAUSE = 12'h142,
|
||||
STVAL = 12'h143,
|
||||
SIP= 12'h144,
|
||||
SATP = 12'h180) (
|
||||
input logic clk, reset,
|
||||
input logic CSRSWriteM, STrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [XLEN-1:0] resetExceptionVector,
|
||||
input logic [XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
||||
input logic [XLEN-1:0] CSRWriteValM,
|
||||
output logic [XLEN-1:0] CSRSReadValM, SEPC_REGW, STVEC_REGW,
|
||||
output logic [31:0] SCOUNTEREN_REGW,
|
||||
output logic [XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW,
|
||||
input logic [11:0] SIP_REGW, SIE_REGW,
|
||||
output logic WriteSIPM, WriteSIEM,
|
||||
output logic WriteSSTATUSM,
|
||||
output logic IllegalCSRSAccessM
|
||||
);
|
||||
|
||||
logic [XLEN-1:0] zero = 0;
|
||||
logic [31:0] allones = {32{1'b1}};
|
||||
logic [XLEN-1:0] SEDELEG_MASK = ~(zero | 3'b111 << 9); // sedeleg[11:9] hardwired to zero per Privileged Spec 3.1.8
|
||||
|
||||
// Supervisor mode CSRs sometimes supported
|
||||
generate
|
||||
if (`S_SUPPORTED) begin
|
||||
logic WriteSTVECM, WriteSEDELEGM, WriteSIDELEGM;
|
||||
logic WriteSSCRATCHM, WriteSEPCM;
|
||||
logic WriteSCAUSEM, WriteSTVALM, WriteSCOUNTERENM;
|
||||
logic [XLEN-1:0] SSCRATCH_REGW, SCAUSE_REGW, STVAL_REGW;
|
||||
|
||||
assign WriteSSTATUSM = CSRSWriteM && (CSRAdrM == SSTATUS);
|
||||
assign WriteSTVECM = CSRSWriteM && (CSRAdrM == STVEC);
|
||||
assign WriteSEDELEGM = CSRSWriteM && (CSRAdrM == SEDELEG);
|
||||
assign WriteSIDELEGM = CSRSWriteM && (CSRAdrM == SIDELEG);
|
||||
assign WriteSSCRATCHM = CSRSWriteM && (CSRAdrM == SSCRATCH);
|
||||
assign WriteSEPCM = STrapM | (CSRSWriteM && (CSRAdrM == SEPC));
|
||||
assign WriteSCAUSEM = STrapM | (CSRSWriteM && (CSRAdrM == SCAUSE));
|
||||
assign WriteSTVALM = STrapM | (CSRSWriteM && (CSRAdrM == STVAL));
|
||||
assign WriteSCOUNTERENM = CSRSWriteM && (CSRAdrM == SCOUNTEREN);
|
||||
|
||||
// CSRs
|
||||
flopenl #(XLEN) STVECreg(clk, reset, WriteSTVECM, CSRWriteValM, resetExceptionVector, STVEC_REGW);
|
||||
// flopenl #(XLEN) SIPreg(clk, reset, WriteSIPM, CSRWriteValM, zero, SIP_REGW);
|
||||
// flopenl #(XLEN) SIEreg(clk, reset, WriteSIEM, CSRWriteValM, zero, SIE_REGW);
|
||||
flopenr #(XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
|
||||
flopenr #(XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);
|
||||
flopenl #(XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, zero, SCAUSE_REGW);
|
||||
flopenr #(XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW);
|
||||
flopenl #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], allones, SCOUNTEREN_REGW);
|
||||
if (`N_SUPPORTED) begin
|
||||
flopenl #(XLEN) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM & SEDELEG_MASK, zero, SEDELEG_REGW);
|
||||
flopenl #(XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, zero, SIDELEG_REGW);
|
||||
end else begin
|
||||
assign SEDELEG_REGW = 0;
|
||||
assign SIDELEG_REGW = 0;
|
||||
end
|
||||
|
||||
// CSR Reads
|
||||
always_comb begin
|
||||
IllegalCSRSAccessM = !(`N_SUPPORTED) && (CSRAdrM == SEDELEG || CSRAdrM == SIDELEG); // trap on DELEG register access when no N-mode
|
||||
case (CSRAdrM)
|
||||
SSTATUS: CSRSReadValM = SSTATUS_REGW;
|
||||
STVEC: CSRSReadValM = STVEC_REGW;
|
||||
SEDELEG: CSRSReadValM = SEDELEG_REGW;
|
||||
SIDELEG: CSRSReadValM = SIDELEG_REGW;
|
||||
SIP: CSRSReadValM = {{(XLEN-12){1'b0}}, SIP_REGW};
|
||||
SIE: CSRSReadValM = {{(XLEN-12){1'b0}}, SIE_REGW};
|
||||
SSCRATCH: CSRSReadValM = SSCRATCH_REGW;
|
||||
SEPC: CSRSReadValM = SEPC_REGW;
|
||||
SCAUSE: CSRSReadValM = SCAUSE_REGW;
|
||||
STVAL: CSRSReadValM = STVAL_REGW;
|
||||
SCOUNTEREN:CSRSReadValM = {{(XLEN-32){1'b0}}, SCOUNTEREN_REGW};
|
||||
default: begin
|
||||
CSRSReadValM = 0;
|
||||
IllegalCSRSAccessM = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin
|
||||
assign WriteSSTATUSM = 0;
|
||||
assign CSRSReadValM = 0;
|
||||
assign SEPC_REGW = 0;
|
||||
assign STVEC_REGW = 0;
|
||||
assign IllegalCSRSAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
181
wally-pipelined/src/csrsr.sv
Normal file
181
wally-pipelined/src/csrsr.sv
Normal file
@ -0,0 +1,181 @@
|
||||
///////////////////////////////////////////
|
||||
// crsr.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Status register
|
||||
// See RISC-V Privileged Mode Specification 20190608
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csrsr #(parameter XLEN=64, MISA = 0)(
|
||||
input logic clk, reset,
|
||||
input logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM, TrapM, FloatRegWriteW,
|
||||
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
|
||||
input logic mretM, sretM, uretM,
|
||||
input logic [XLEN-1:0] CSRWriteValM,
|
||||
output logic [XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW,
|
||||
output logic [1:0] STATUS_MPP,
|
||||
output logic STATUS_SPP, STAUTS_TSR,
|
||||
output logic STATUS_MIE, STATUS_SIE
|
||||
);
|
||||
|
||||
logic STATUS_SD, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_SUM_INT, STATUS_MPRV, STATUS_MPRV_INT;
|
||||
logic [1:0] STATUS_SXL, STATUS_UXL, STATUS_XS, STATUS_FS, STATUS_FS_INT, STATUS_MPP_NEXT;
|
||||
logic STATUS_MPIE, STATUS_SPIE, STATUS_UPIE, STATUS_UIE;
|
||||
|
||||
// STATUS REGISTER FIELD
|
||||
// See Privileged Spec Section 3.1.6
|
||||
// Lower privilege status registers are a subset of the full status register
|
||||
// *** consider adding MBE, SBE, UBE fields later from 20210108 draft spec
|
||||
generate
|
||||
if (XLEN==64) begin// RV64
|
||||
assign MSTATUS_REGW = {STATUS_SD, 27'b0, STATUS_SXL, STATUS_UXL, 9'b0,
|
||||
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
|
||||
STATUS_SPP, STATUS_MPIE, 1'b0, STATUS_SPIE, STATUS_UPIE,
|
||||
STATUS_MIE, 1'b0, STATUS_SIE, STATUS_UIE};
|
||||
assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ STATUS_UXL, /*9'b0, */ 12'b0,
|
||||
/*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0,
|
||||
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
|
||||
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
|
||||
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
|
||||
assign USTATUS_REGW = {/*STATUS_SD, */ 59'b0, /*STATUS_SXL, STATUS_UXL, 9'b0, */
|
||||
/*STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, , 1'b0,*/
|
||||
/* STATUS_XS, STATUS_FS, /*STATUS_MPP, 8'b0, */
|
||||
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
|
||||
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
|
||||
end else begin// RV32
|
||||
assign MSTATUS_REGW = {STATUS_SD, 8'b0,
|
||||
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
|
||||
STATUS_SPP, STATUS_MPIE, 1'b0, STATUS_SPIE, STATUS_UPIE, STATUS_MIE, 1'b0, STATUS_SIE, STATUS_UIE};
|
||||
assign SSTATUS_REGW = {STATUS_SD, 11'b0,
|
||||
/*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0,
|
||||
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
|
||||
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
|
||||
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
|
||||
assign USTATUS_REGW = {/*STATUS_SD, */ 27'b0, /*STATUS_SXL, STATUS_UXL, 9'b0, */
|
||||
/*STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, , 1'b0,*/
|
||||
/*STATUS_XS, STATUS_FS, STATUS_MPP, 8'b0, */
|
||||
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
|
||||
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// harwired STATUS bits
|
||||
generate
|
||||
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
|
||||
assign STATUS_SXL = `S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
|
||||
assign STATUS_UXL = `U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
|
||||
assign STATUS_SUM = `S_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported
|
||||
assign STATUS_MPRV = `U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported
|
||||
assign STATUS_FS = (`S_SUPPORTED && (`F_SUPPORTED || `D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP
|
||||
endgenerate
|
||||
assign STATUS_SD = (STATUS_FS == 2'b11) || (STATUS_XS == 2'b11); // dirty state logic
|
||||
assign STATUS_TSR = 0; // Trap SRET not supported; revisit whether this is necessary for an OS
|
||||
assign STATUS_TW = 0; // Timeout Wait not supported
|
||||
assign STATUS_TVM = 0; // Trap Virtual Memory not supported (revisit if supporting virtualizations)
|
||||
assign STATUS_MXR = 0; // Make Executable Readable (may need to add support for VM later)
|
||||
assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty
|
||||
|
||||
always_comb
|
||||
if (CSRWriteValM[12:11] == `U_MODE && `U_SUPPORTED) STATUS_MPP_NEXT = `U_MODE;
|
||||
else if (CSRWriteValM[12:11] == `S_MODE && `S_SUPPORTED) STATUS_MPP_NEXT = `S_MODE;
|
||||
else STATUS_MPP_NEXT = `M_MODE;
|
||||
|
||||
// registers for STATUS bits
|
||||
// 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 <= 2'b01; // initial
|
||||
STATUS_MPP <= `M_MODE;
|
||||
STATUS_SPP <= 1'b1;
|
||||
STATUS_MPIE <= 1;
|
||||
STATUS_SPIE <= `S_SUPPORTED;
|
||||
STATUS_UPIE <= `U_SUPPORTED;
|
||||
STATUS_MIE <= 0; // Per Priv 3.3
|
||||
STATUS_SIE <= `S_SUPPORTED;
|
||||
STATUS_UIE <= `U_SUPPORTED;
|
||||
end else 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];
|
||||
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];
|
||||
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];
|
||||
end else begin
|
||||
if (FloatRegWriteW) STATUS_FS_INT <=2'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;
|
||||
end else if (NextPrivilegeModeM == `S_MODE) begin
|
||||
STATUS_SPIE <= STATUS_SIE;
|
||||
STATUS_SIE <= 0;
|
||||
STATUS_SPP <= PrivilegeModeW[0]; // *** seems to disagree with P. 56
|
||||
end else begin // user mode
|
||||
STATUS_UPIE <= STATUS_UIE;
|
||||
STATUS_UIE <= 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
|
||||
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
|
||||
end else if (uretM) begin
|
||||
STATUS_UIE <= STATUS_UPIE;
|
||||
STATUS_UPIE <= `U_SUPPORTED;
|
||||
end
|
||||
// *** add code to track STATUS_FS_INT for dirty floating point registers
|
||||
end
|
||||
end
|
||||
endmodule
|
84
wally-pipelined/src/csru.sv
Normal file
84
wally-pipelined/src/csru.sv
Normal file
@ -0,0 +1,84 @@
|
||||
///////////////////////////////////////////
|
||||
// csru.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: User-Mode Control and Status Registers for Floating Point
|
||||
|
||||
// See RISC-V Privileged Mode Specification 20190608 Table 2.2
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module csru #(parameter XLEN=64, MISA=0,
|
||||
FFLAGS = 12'h001,
|
||||
FRM = 12'h002,
|
||||
FCSR = 12'h003) (
|
||||
input logic clk, reset,
|
||||
input logic CSRUWriteM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [XLEN-1:0] CSRWriteValM,
|
||||
output logic [XLEN-1:0] CSRUReadValM,
|
||||
input logic [4:0] SetFflagsM,
|
||||
output logic [2:0] FRM_REGW,
|
||||
output logic IllegalCSRUAccessM
|
||||
);
|
||||
|
||||
// Floating Point CSRs in User Mode only needed if Floating Point is supported
|
||||
generate
|
||||
if (`F_SUPPORTED) begin
|
||||
logic [4:0] FFLAGS_REGW;
|
||||
logic WriteFFLAGSM, WriteFRMM, WriteFCSRM;
|
||||
logic [2:0] NextFRMM;
|
||||
logic [4:0] NextFFLAGSM;
|
||||
|
||||
// Write enables
|
||||
assign WriteFCSRM = CSRUWriteM && (CSRAdrM == FCSR);
|
||||
assign WriteFFLAGSM = CSRUWriteM && (CSRAdrM == FFLAGS) | WriteFCSRM ;
|
||||
assign WriteFRMM = CSRUWriteM && (CSRAdrM == FRM) | WriteFCSRM;
|
||||
|
||||
// Write Values
|
||||
assign NextFRMM = WriteFCSRM ? CSRWriteValM[7:5] : CSRWriteValM[2:0];
|
||||
assign NextFFLAGSM = WriteFFLAGSM ? CSRWriteValM[4:0] : FFLAGS_REGW | SetFflagsM;
|
||||
|
||||
// CSRs
|
||||
flopenr #(3) FRMreg(clk, reset, WriteFRMM, NextFRMM, FRM_REGW);
|
||||
flopr #(5) FFLAGSreg(clk, reset, NextFFLAGSM, FFLAGS_REGW);
|
||||
|
||||
// CSR Reads
|
||||
always_comb begin
|
||||
IllegalCSRUAccessM = 0;
|
||||
case (CSRAdrM)
|
||||
FFLAGS: CSRUReadValM = {{(XLEN-5){1'b0}}, FFLAGS_REGW};
|
||||
FRM: CSRUReadValM = {{(XLEN-3){1'b0}}, FRM_REGW};
|
||||
FCSR: CSRUReadValM = {{(XLEN-8){1'b0}}, FRM_REGW, FFLAGS_REGW};
|
||||
default: begin
|
||||
CSRUReadValM = 0;
|
||||
IllegalCSRUAccessM = 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end else begin // if not supported
|
||||
assign FRM_REGW = 0;
|
||||
assign CSRUReadValM = 0;
|
||||
assign IllegalCSRUAccessM = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
181
wally-pipelined/src/datapath.sv
Normal file
181
wally-pipelined/src/datapath.sv
Normal file
@ -0,0 +1,181 @@
|
||||
///////////////////////////////////////////
|
||||
// datapath.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Wally Datapath
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module datapath #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
input logic clk, reset,
|
||||
// Fetch stage signals
|
||||
input logic StallF,
|
||||
output logic [XLEN-1:0] PCF,
|
||||
input logic [31:0] InstrF,
|
||||
// Decode stage signals
|
||||
output logic [6:0] opD,
|
||||
output logic [2:0] funct3D,
|
||||
output logic funct7b5D,
|
||||
input logic StallD, FlushD,
|
||||
input logic [2:0] ImmSrcD,
|
||||
input logic LoadStallD, // for performance counter
|
||||
output logic IllegalCompInstrD,
|
||||
// Execute stage signals
|
||||
input logic FlushE,
|
||||
input logic [1:0] ForwardAE, ForwardBE,
|
||||
input logic PCSrcE,
|
||||
input logic [4:0] ALUControlE,
|
||||
input logic ALUSrcAE, ALUSrcBE,
|
||||
input logic TargetSrcE,
|
||||
output logic [2:0] FlagsE,
|
||||
// Memory stage signals
|
||||
input logic FlushM,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic CSRWriteM, PrivilegedM,
|
||||
input logic InstrAccessFaultM, IllegalInstrFaultM,
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
output logic InstrMisalignedFaultM,
|
||||
input logic [2:0] Funct3M,
|
||||
output logic [XLEN-1:0] WriteDataExtM, ALUResultM,
|
||||
input logic [XLEN-1:0] ReadDataM,
|
||||
output logic [7:0] ByteMaskM,
|
||||
output logic RetM, TrapM,
|
||||
input logic [4:0] SetFflagsM,
|
||||
input logic DataAccessFaultM,
|
||||
// Writeback stage signals
|
||||
input logic FlushW,
|
||||
input logic RegWriteW,
|
||||
input logic [1:0] ResultSrcW,
|
||||
input logic InstrValidW,
|
||||
input logic FloatRegWriteW,
|
||||
output logic [2:0] FRM_REGW,
|
||||
// Hazard Unit signals
|
||||
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
|
||||
output logic [4:0] RdE, RdM, RdW);
|
||||
|
||||
// Fetch stage signals
|
||||
logic [XLEN-1:0] PCPlus2or4F;
|
||||
// Decode stage signals
|
||||
logic [31:0] InstrD;
|
||||
logic [XLEN-1:0] PCD, PCPlus2or4D;
|
||||
logic [XLEN-1:0] RD1D, RD2D;
|
||||
logic [XLEN-1:0] ExtImmD;
|
||||
logic [31:0] InstrDecompD;
|
||||
logic [4:0] RdD;
|
||||
// Execute stage signals
|
||||
logic [31:0] InstrE;
|
||||
logic [XLEN-1:0] RD1E, RD2E;
|
||||
logic [XLEN-1:0] PCE, ExtImmE;
|
||||
logic [XLEN-1:0] PreSrcAE, SrcAE, SrcBE;
|
||||
logic [XLEN-1:0] ALUResultE;
|
||||
logic [XLEN-1:0] WriteDataE;
|
||||
logic [XLEN-1:0] TargetBaseE, PCTargetE;
|
||||
// Memory stage signals
|
||||
logic [31:0] InstrM;
|
||||
logic [XLEN-1:0] PCM;
|
||||
logic [XLEN-1:0] SrcAM;
|
||||
logic [XLEN-1:0] ReadDataExtM;
|
||||
logic [XLEN-1:0] WriteDataM;
|
||||
logic [XLEN-1:0] CSRReadValM;
|
||||
logic [XLEN-1:0] PrivilegedNextPCM;
|
||||
logic LoadMisalignedFaultM, LoadAccessFaultM;
|
||||
logic StoreMisalignedFaultM, StoreAccessFaultM;
|
||||
logic [XLEN-1:0] InstrMisalignedAdrM;
|
||||
// Writeback stage signals
|
||||
logic [XLEN-1:0] ALUResultW;
|
||||
logic [XLEN-1:0] ReadDataW;
|
||||
logic [XLEN-1:0] PCW;
|
||||
logic [XLEN-1:0] CSRValW;
|
||||
logic [XLEN-1:0] ResultW;
|
||||
|
||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
|
||||
// Fetch stage pipeline register and logic; also Ex stage for branches
|
||||
pclogic #(XLEN, MISA) pclogic(clk, reset, StallF, PCSrcE,
|
||||
InstrF, ExtImmE, TargetBaseE, RetM, TrapM, PrivilegedNextPCM, PCF, PCPlus2or4F,
|
||||
InstrMisalignedFaultM, InstrMisalignedAdrM);
|
||||
|
||||
// Decode stage pipeline register and logic
|
||||
flopenl #(32) InstrDReg(clk, reset, ~StallD, (FlushD ? nop : InstrF), nop, InstrD);
|
||||
flopenrc #(XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);
|
||||
flopenrc #(XLEN) PCPlus2or4DReg(clk, reset, FlushD, ~StallD, PCPlus2or4F, PCPlus2or4D);
|
||||
|
||||
instrDecompress #(XLEN, MISA) decomp(InstrD, InstrDecompD, IllegalCompInstrD);
|
||||
assign opD = InstrDecompD[6:0];
|
||||
assign funct3D = InstrDecompD[14:12];
|
||||
assign funct7b5D = InstrDecompD[30];
|
||||
assign Rs1D = InstrDecompD[19:15];
|
||||
assign Rs2D = InstrDecompD[24:20];
|
||||
assign RdD = InstrDecompD[11:7];
|
||||
|
||||
regfile #(XLEN) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, RD1D, RD2D);
|
||||
extend #(XLEN) ext(InstrDecompD[31:7], ImmSrcD, ExtImmD);
|
||||
|
||||
// Execute stage pipeline register and logic
|
||||
floprc #(XLEN) RD1EReg(clk, reset, FlushE, RD1D, RD1E);
|
||||
floprc #(XLEN) RD2EReg(clk, reset, FlushE, RD2D, RD2E);
|
||||
floprc #(XLEN) PCEReg(clk, reset, FlushE, PCD, PCE);
|
||||
floprc #(XLEN) ExtImmEReg(clk, reset, FlushE, ExtImmD, ExtImmE);
|
||||
flopr #(32) InstrEReg(clk, reset, FlushE ? nop : InstrDecompD, InstrE);
|
||||
floprc #(5) Rs1EReg(clk, reset, FlushE, Rs1D, Rs1E);
|
||||
floprc #(5) Rs2EReg(clk, reset, FlushE, Rs2D, Rs2E);
|
||||
floprc #(5) RdEReg(clk, reset, FlushE, RdD, RdE);
|
||||
|
||||
mux3 #(XLEN) faemux(RD1E, ResultW, ALUResultM, ForwardAE, PreSrcAE);
|
||||
mux3 #(XLEN) fbemux(RD2E, ResultW, ALUResultM, ForwardBE, WriteDataE);
|
||||
mux2 #(XLEN) srcamux(PreSrcAE, PCE, ALUSrcAE, SrcAE);
|
||||
mux2 #(XLEN) srcbmux(WriteDataE, ExtImmE, ALUSrcBE, SrcBE);
|
||||
alu #(XLEN) alu(SrcAE, SrcBE, ALUControlE, ALUResultE, FlagsE);
|
||||
mux2 #(XLEN) targetsrcmux(PCE, SrcAE, TargetSrcE, TargetBaseE);
|
||||
|
||||
// Memory stage pipeline register
|
||||
floprc #(XLEN) SrcAMReg(clk, reset, FlushM, SrcAE, SrcAM);
|
||||
floprc #(XLEN) ALUResultMReg(clk, reset, FlushM, ALUResultE, ALUResultM);
|
||||
floprc #(XLEN) WriteDataMReg(clk, reset, FlushM, WriteDataE, WriteDataM);
|
||||
floprc #(XLEN) PCMReg(clk, reset, FlushM, PCE, PCM);
|
||||
flopr #(32) InstrMReg(clk, reset, FlushM ? nop : InstrE, InstrM);
|
||||
floprc #(5) RdMEg(clk, reset, FlushM, RdE, RdM);
|
||||
|
||||
memdp #(XLEN) memdp(
|
||||
MemRWM, ReadDataM, ALUResultM, Funct3M, ReadDataExtM, WriteDataM, WriteDataExtM, ByteMaskM,
|
||||
DataAccessFaultM, LoadMisalignedFaultM, LoadAccessFaultM, StoreMisalignedFaultM, StoreAccessFaultM);
|
||||
|
||||
// Priveleged block operates in M and W stages, handling CSRs and exceptions
|
||||
privileged #(XLEN, MISA, ZCSR, ZCOUNTERS) priv(
|
||||
clk, reset, CSRWriteM, SrcAM, InstrM, PCM,
|
||||
CSRReadValM, PrivilegedNextPCM, RetM, TrapM,
|
||||
InstrValidW, FloatRegWriteW, LoadStallD, PrivilegedM,
|
||||
InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
|
||||
LoadMisalignedFaultM, LoadAccessFaultM, StoreMisalignedFaultM, StoreAccessFaultM,
|
||||
TimerIntM, ExtIntM, SwIntM,
|
||||
InstrMisalignedAdrM, ALUResultM,
|
||||
SetFflagsM, FRM_REGW);
|
||||
|
||||
// Writeback stage pipeline register and logic
|
||||
floprc #(XLEN) ALUResultWReg(clk, reset, FlushW, ALUResultM, ALUResultW);
|
||||
floprc #(XLEN) ReadDataWReg(clk, reset, FlushW, ReadDataExtM, ReadDataW);
|
||||
floprc #(XLEN) PCWReg(clk, reset, FlushW, PCM, PCW);
|
||||
floprc #(XLEN) CSRValWReg(clk, reset, FlushW, CSRReadValM, CSRValW);
|
||||
floprc #(5) RdWEg(clk, reset, FlushW, RdM, RdW);
|
||||
|
||||
mux4 #(XLEN) resultmux(ALUResultW, ReadDataW, PCW, CSRValW, ResultSrcW, ResultW);
|
||||
endmodule
|
60
wally-pipelined/src/dmem.sv
Normal file
60
wally-pipelined/src/dmem.sv
Normal file
@ -0,0 +1,60 @@
|
||||
///////////////////////////////////////////
|
||||
// dmem.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Data memory
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
// *** need idiom to map onto cache RAM with byte writes
|
||||
// *** and use memread signal to reduce power when reads aren't needed
|
||||
module dmem #(parameter XLEN=32) (
|
||||
input logic clk, reset,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [7:0] ByteMaskM,
|
||||
input logic [XLEN-1:0] AdrM, WdM,
|
||||
output logic [XLEN-1:0] RdM,
|
||||
output logic AccessFaultM,
|
||||
output logic TimerIntM, SwIntM);
|
||||
|
||||
logic [XLEN-1:0] RdTimM, RdClintM;
|
||||
logic TimEnM, ClintEnM;
|
||||
|
||||
// Address decoding
|
||||
assign TimEnM = AdrM[31] & ~(|AdrM[30:19]); // 0x80000000 - 0x8007FFFF *** check top bits too
|
||||
assign ClintEnM = ~(|AdrM[XLEN-1:26]) & AdrM[25] & ~(|AdrM[24:16]); // 0x02000000-0x0200FFFF
|
||||
|
||||
// tightly integrated memory
|
||||
dtim #(XLEN) dtim(clk, MemRWM & {2{TimEnM}}, ByteMaskM, AdrM[18:0], WdM, RdTimM);
|
||||
|
||||
// memory-mapped I/O peripherals
|
||||
clint #(XLEN) clint(clk, reset, MemRWM & {2{ClintEnM}}, ByteMaskM, AdrM[15:0], WdM, RdClintM,
|
||||
TimerIntM, SwIntM);
|
||||
|
||||
// *** add cache and interface to external memory & other peripherals
|
||||
|
||||
// merge reads
|
||||
assign RdM = RdTimM | RdClintM;
|
||||
assign AccessFaultM = ~(|TimEnM | ClintEnM);
|
||||
|
||||
endmodule
|
||||
|
85
wally-pipelined/src/dtim.sv
Normal file
85
wally-pipelined/src/dtim.sv
Normal file
@ -0,0 +1,85 @@
|
||||
///////////////////////////////////////////
|
||||
// dtim.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Data tightly integrated memory
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module dtim #(parameter XLEN=32) (
|
||||
input logic clk,
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [7:0] ByteMaskM,
|
||||
input logic [18:0] AdrM,
|
||||
// input logic [XLEN-1:0] AdrM,
|
||||
input logic [XLEN-1:0] WdM,
|
||||
output logic [XLEN-1:0] RdM);
|
||||
|
||||
logic [XLEN-1:0] RAM[0:65535];
|
||||
logic [XLEN-1:0] read, write;
|
||||
logic [15:0] entry;
|
||||
logic memread, memwrite;
|
||||
|
||||
assign memread = MemRWM[1];
|
||||
assign memwrite = MemRWM[0];
|
||||
|
||||
// word aligned reads
|
||||
generate
|
||||
if (XLEN==64)
|
||||
assign #2 entry = AdrM[18:3];
|
||||
else
|
||||
assign #2 entry = AdrM[17:2];
|
||||
endgenerate
|
||||
assign read = RAM[entry];
|
||||
assign RdM = memread ? read: 0;
|
||||
|
||||
// write each byte based on the byte mask
|
||||
generate
|
||||
|
||||
if (XLEN==64) begin
|
||||
always_comb begin
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
if (ByteMaskM[4]) write[39:32] = WdM[39:32];
|
||||
if (ByteMaskM[5]) write[47:40] = WdM[47:40];
|
||||
if (ByteMaskM[6]) write[55:48] = WdM[55:48];
|
||||
if (ByteMaskM[7]) write[63:56] = WdM[63:56];
|
||||
end
|
||||
always_ff @(posedge clk)
|
||||
if (memwrite) RAM[AdrM[18:3]] <= write;
|
||||
end else begin // 32-bit
|
||||
always_comb begin
|
||||
write=read;
|
||||
if (ByteMaskM[0]) write[7:0] = WdM[7:0];
|
||||
if (ByteMaskM[1]) write[15:8] = WdM[15:8];
|
||||
if (ByteMaskM[2]) write[23:16] = WdM[23:16];
|
||||
if (ByteMaskM[3]) write[31:24] = WdM[31:24];
|
||||
end
|
||||
always_ff @(posedge clk)
|
||||
if (memwrite) RAM[AdrM[17:2]] <= write;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
49
wally-pipelined/src/extend.sv
Normal file
49
wally-pipelined/src/extend.sv
Normal file
@ -0,0 +1,49 @@
|
||||
///////////////////////////////////////////
|
||||
// extend.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module extend #(parameter XLEN=32) (
|
||||
input logic [31:7] instr,
|
||||
input logic [2:0] immsrc,
|
||||
output logic [XLEN-1:0] immext);
|
||||
|
||||
always_comb
|
||||
case(immsrc)
|
||||
// I-type
|
||||
3'b000: immext = {{(XLEN-12){instr[31]}}, instr[31:20]};
|
||||
// S-type (stores)
|
||||
3'b001: immext = {{(XLEN-12){instr[31]}}, instr[31:25], instr[11:7]};
|
||||
// B-type (branches)
|
||||
3'b010: immext = {{(XLEN-12){instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0};
|
||||
// J-type (jal)
|
||||
3'b011: immext = {{(XLEN-20){instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0};
|
||||
// U-type (lui, auipc)
|
||||
3'b100: immext = {{(XLEN-31){instr[31]}}, instr[30:12], 12'b0};
|
||||
/* verilator lint_off WIDTH */
|
||||
default: immext = 'bx; // undefined
|
||||
/* verilator lint_on WIDTH */
|
||||
endcase
|
||||
endmodule
|
98
wally-pipelined/src/flop.sv
Normal file
98
wally-pipelined/src/flop.sv
Normal file
@ -0,0 +1,98 @@
|
||||
///////////////////////////////////////////
|
||||
// flop.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: arious flavors of flip-flops
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
// ordinary flip-flop
|
||||
module flop #(parameter WIDTH = 8) (
|
||||
input logic clk,
|
||||
input logic [WIDTH-1:0] d,
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk)
|
||||
q <= #1 d;
|
||||
endmodule
|
||||
|
||||
// flop with asynchronous reset
|
||||
module flopr #(parameter WIDTH = 8) (
|
||||
input logic clk, reset,
|
||||
input logic [WIDTH-1:0] d,
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk, posedge reset)
|
||||
if (reset) q <= #1 0;
|
||||
else q <= #1 d;
|
||||
endmodule
|
||||
|
||||
// flop with enable, asynchronous reset, synchronous clear
|
||||
module flopenrc #(parameter WIDTH = 8) (
|
||||
input logic clk, reset, clear, en,
|
||||
input logic [WIDTH-1:0] d,
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk, posedge reset)
|
||||
if (reset) q <= #1 0;
|
||||
else if (en)
|
||||
if (clear) q <= #1 0;
|
||||
else q <= #1 d;
|
||||
endmodule
|
||||
|
||||
// flop with enable, asynchronous reset
|
||||
module flopenr #(parameter WIDTH = 8) (
|
||||
input logic clk, reset, en,
|
||||
input logic [WIDTH-1:0] d,
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk, posedge reset)
|
||||
if (reset) q <= #1 0;
|
||||
else if (en) q <= #1 d;
|
||||
endmodule
|
||||
|
||||
// flop with enable, asynchronous load
|
||||
module flopenl #(parameter WIDTH = 8) (
|
||||
input logic clk, load, en,
|
||||
input logic [WIDTH-1:0] d,
|
||||
input logic [WIDTH-1:0] val,
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk, posedge load)
|
||||
if (load) q <= #1 val;
|
||||
else if (en) q <= #1 d;
|
||||
endmodule
|
||||
|
||||
// flop with asynchronous reset, synchronous clear
|
||||
module floprc #(parameter WIDTH = 8) (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic clear,
|
||||
input logic [WIDTH-1:0] d,
|
||||
output logic [WIDTH-1:0] q);
|
||||
|
||||
always_ff @(posedge clk, posedge reset)
|
||||
if (reset) q <= #1 0;
|
||||
else
|
||||
if (clear) q <= #1 0;
|
||||
else q <= #1 d;
|
||||
endmodule
|
64
wally-pipelined/src/hazard.sv
Normal file
64
wally-pipelined/src/hazard.sv
Normal file
@ -0,0 +1,64 @@
|
||||
///////////////////////////////////////////
|
||||
// hazard.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Determine forwarding, stalls and flushes
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module hazard(
|
||||
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
|
||||
input logic PCSrcE, MemReadE,
|
||||
input logic RegWriteM, RegWriteW, CSRWritePendingDEM, RetM, TrapM,
|
||||
output logic [1:0] ForwardAE, ForwardBE,
|
||||
output logic StallF, StallD, FlushD, FlushE, FlushM, FlushW,
|
||||
output logic loadStallD);
|
||||
|
||||
// forwarding logic
|
||||
always_comb begin
|
||||
ForwardAE = 2'b00;
|
||||
ForwardBE = 2'b00;
|
||||
if (Rs1E != 5'b0)
|
||||
if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
|
||||
else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01;
|
||||
|
||||
if (Rs2E != 5'b0)
|
||||
if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
|
||||
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
|
||||
end
|
||||
|
||||
// stalls and flushes
|
||||
// loads: stall for one cycle if the subsequent instruction depends on the load
|
||||
// branches and jumps: flush the next two instructions if the branch is taken in EXE
|
||||
// CSR Writes: stall all instructions after the CSR until it completes, except that PC must change when branch is resolved
|
||||
// this also applies to other privileged instructions such as M/S/URET, ECALL/EBREAK
|
||||
// Exceptions: flush entire pipeline
|
||||
// Ret instructions: occur in M stage. Might be possible to move earlier, but be careful about hazards
|
||||
|
||||
assign loadStallD = MemReadE & ((Rs1D == RdE) | (Rs2D == RdE));
|
||||
assign StallD = loadStallD;
|
||||
assign StallF = loadStallD | CSRWritePendingDEM;
|
||||
assign FlushD = PCSrcE | CSRWritePendingDEM | RetM | TrapM;
|
||||
assign FlushE = loadStallD | PCSrcE | RetM | TrapM;
|
||||
assign FlushM = RetM | TrapM;
|
||||
assign FlushW = TrapM;
|
||||
endmodule
|
60
wally-pipelined/src/imem.sv
Normal file
60
wally-pipelined/src/imem.sv
Normal file
@ -0,0 +1,60 @@
|
||||
///////////////////////////////////////////
|
||||
// imem.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module imem #(parameter XLEN=32) (
|
||||
input logic [XLEN-1:0] AdrF,
|
||||
output logic [31:0] InstrF,
|
||||
output logic InstrAccessFaultF);
|
||||
|
||||
logic [XLEN-1:0] RAM[0:65535];
|
||||
logic [15:0] adrbits;
|
||||
logic [XLEN-1:0] rd, rd2;
|
||||
|
||||
generate
|
||||
if (XLEN==32) assign adrbits = AdrF[17:2];
|
||||
else assign adrbits = AdrF[18:3];
|
||||
endgenerate
|
||||
|
||||
assign #2 rd = RAM[adrbits]; // word aligned
|
||||
|
||||
// hack right now for unaligned 32-bit instructions
|
||||
// eventually this will need to cause a stall like a cache miss
|
||||
// when the instruction wraps around a cache line
|
||||
// could be optimized to only stall when the instruction wrapping is 32 bits
|
||||
assign #2 rd2 = RAM[adrbits+1];
|
||||
generate
|
||||
if (XLEN==32) begin
|
||||
assign InstrF = AdrF[1] ? {rd2[15:0], rd[31:16]} : rd;
|
||||
assign InstrAccessFaultF = ~AdrF[31] | (|AdrF[30:16]); // memory mapped to 0x80000000-0x8000FFFF
|
||||
end else begin
|
||||
assign InstrF = AdrF[2] ? (AdrF[1] ? {rd2[15:0], rd[63:48]} : rd[63:32])
|
||||
: (AdrF[1] ? rd[47:16] : rd[31:0]);
|
||||
assign InstrAccessFaultF = (|AdrF[XLEN-1:32]) | ~AdrF[31] | (|AdrF[30:16]); // memory mapped to 0x80000000-0x8000FFFF]
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
178
wally-pipelined/src/instrDecompress.sv
Normal file
178
wally-pipelined/src/instrDecompress.sv
Normal file
@ -0,0 +1,178 @@
|
||||
///////////////////////////////////////////
|
||||
// instrDecompress.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Expand 16-bit compressed instructions to 32 bits
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module instrDecompress #(parameter XLEN=32, MISA=1) (
|
||||
input logic [31:0] InstrD,
|
||||
output logic [31:0] InstrDecompD,
|
||||
output logic IllegalCompInstrD);
|
||||
|
||||
logic [15:0] instr16;
|
||||
logic [4:0] rds1, rs2, rs1p, rs2p, rds1p, rdp;
|
||||
logic [11:0] immCILSP, immCILSPD, immCSS, immCSSD, immCL, immCLD, immCI, immCS, immCSD, immCB, immCIASP, immCIW;
|
||||
logic [19:0] immCJ, immCILUI;
|
||||
logic [5:0] immSH;
|
||||
logic [1:0] op;
|
||||
|
||||
// if the system handles compressed instructions, decode appropriately
|
||||
generate
|
||||
if (!(`C_SUPPORTED)) begin // no compressed mode
|
||||
assign InstrDecompD = InstrD;
|
||||
assign IllegalCompInstrD = 0;
|
||||
end else begin // COMPRESSED mode supported
|
||||
assign instr16 = InstrD[15:0]; // instruction is alreay aligned
|
||||
assign op = instr16[1:0];
|
||||
assign rds1 = instr16[11:7];
|
||||
assign rs2 = instr16[6:2];
|
||||
assign rs1p = {2'b01, instr16[9:7]};
|
||||
assign rds1p = {2'b01, instr16[9:7]};
|
||||
assign rs2p = {2'b01, instr16[4:2]};
|
||||
assign rdp = {2'b01, instr16[4:2]};
|
||||
|
||||
// many compressed immediate formats
|
||||
assign immCILSP = {{4{instr16[3]}}, instr16[3:2], instr16[12], instr16[6:4], 2'b00};
|
||||
assign immCILSPD = {{3{instr16[4]}}, instr16[4:2], instr16[12], instr16[6:5], 3'b000};
|
||||
assign immCSS = {{4{instr16[8]}}, instr16[8:7], instr16[12:9], 2'b00};
|
||||
assign immCSSD = {{3{instr16[9]}}, instr16[9:7], instr16[12:10], 3'b000};
|
||||
assign immCL = {5'b0, instr16[5], instr16[12:10], instr16[6], 2'b00};
|
||||
assign immCLD = {4'b0, instr16[6:5], instr16[12:10], 3'b000};
|
||||
assign immCS = {5'b0, instr16[5], instr16[12:10], instr16[6], 2'b00};
|
||||
assign immCSD = {4'b0, instr16[6:5], instr16[12:10], 3'b000};
|
||||
assign immCJ = {instr16[12], instr16[8], instr16[10:9], instr16[6], instr16[7], instr16[2], instr16[11], instr16[5:3], {9{instr16[12]}}};
|
||||
assign immCB = {{4{instr16[12]}}, instr16[6:5], instr16[2], instr16[11:10], instr16[4:3], instr16[12]};
|
||||
assign immCI = {{7{instr16[12]}}, instr16[6:2]};
|
||||
assign immCILUI = {{15{instr16[12]}}, instr16[6:2]};
|
||||
assign immCIASP = {{3{instr16[12]}}, instr16[4:3], instr16[5], instr16[2], instr16[6], 4'b0000};
|
||||
assign immCIW = {2'b00, instr16[10:7], instr16[12:11], instr16[5], instr16[6], 2'b00};
|
||||
assign immSH = {instr16[12], instr16[6:2]};
|
||||
|
||||
// only for RV128
|
||||
// assign immCILSPQ = {2{instr16[5]}, instr16[5:2], instr16[12], instr16[6], 4'b0000};
|
||||
// assign immCSSQ = {2{instr16[10]}, instr16[10:7], instr16[12:11], 4'b0000};
|
||||
// assign immCLQ = {4{instr16[10]}, instr16[6:5], instr16[12:11], 4'b0000};
|
||||
// assign immCSQ = {4{instr16[10]}, instr16[6:5], instr16[12:11], 4'b0000};
|
||||
|
||||
always_comb
|
||||
if (op == 2'b11) begin // noncompressed instruction
|
||||
InstrDecompD = InstrD;
|
||||
IllegalCompInstrD = 0;
|
||||
end else begin // convert compressed instruction into uncompressed
|
||||
IllegalCompInstrD = 0;
|
||||
case ({op, instr16[15:13]})
|
||||
5'b00000: if (immCIW != 0) InstrDecompD = {immCIW, 5'b00010, 3'b000, rdp, 7'b0010011}; // c.addi4spn
|
||||
else begin // illegal instruction
|
||||
IllegalCompInstrD = 1;
|
||||
InstrDecompD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b00001: InstrDecompD = {immCLD, rs1p, 3'b011, rdp, 7'b0000111}; // c.fld
|
||||
5'b00010: InstrDecompD = {immCL, rs1p, 3'b010, rdp, 7'b0000011}; // c.lw
|
||||
5'b00011: if (XLEN==32)
|
||||
InstrDecompD = {immCL, rs1p, 3'b010, rdp, 7'b0000111}; // c.flw
|
||||
else
|
||||
InstrDecompD = {immCLD, rs1p, 3'b011, rdp, 7'b0000011}; // c.ld;
|
||||
5'b00101: InstrDecompD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100111}; // c.fsd
|
||||
5'b00110: InstrDecompD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100011}; // c.sw
|
||||
5'b00111: if (XLEN==32)
|
||||
InstrDecompD = {immCS[11:5], rs2p, rs1p, 3'b010, immCS[4:0], 7'b0100111}; // c.fsw
|
||||
else
|
||||
InstrDecompD = {immCSD[11:5], rs2p, rs1p, 3'b011, immCSD[4:0], 7'b0100011}; //c.sd
|
||||
5'b01000: InstrDecompD = {immCI, rds1, 3'b000, rds1, 7'b0010011}; // c.addi
|
||||
5'b01001: if (XLEN==32)
|
||||
InstrDecompD = {immCJ, 5'b00001, 7'b1101111}; // c.jal
|
||||
else
|
||||
InstrDecompD = {immCI, rds1, 3'b000, rds1, 7'b0011011}; // c.addiw
|
||||
5'b01010: InstrDecompD = {immCI, 5'b00000, 3'b000, rds1, 7'b0010011}; // c.li
|
||||
5'b01011: if (rds1 != 5'b00010)
|
||||
InstrDecompD = {immCILUI, rds1, 7'b0110111}; // c.lui
|
||||
else
|
||||
InstrDecompD = {immCIASP, rds1, 3'b000, rds1, 7'b0010011}; // c.addi16sp
|
||||
5'b01100: if (instr16[11:10] == 2'b00)
|
||||
InstrDecompD = {6'b000000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srli
|
||||
else if (instr16[11:10] == 2'b01)
|
||||
InstrDecompD = {6'b010000, immSH, rds1p, 3'b101, rds1p, 7'b0010011}; // c.srai
|
||||
else if (instr16[11:10] == 2'b10)
|
||||
InstrDecompD = {immCI, rds1p, 3'b111, rds1p, 7'b0010011}; // c.andi
|
||||
else if (instr16[12:10] == 3'b011)
|
||||
if (instr16[6:5] == 2'b00)
|
||||
InstrDecompD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0110011}; // c.sub
|
||||
else if (instr16[6:5] == 2'b01)
|
||||
InstrDecompD = {7'b0000000, rs2p, rds1p, 3'b100, rds1p, 7'b0110011}; // c.xor
|
||||
else if (instr16[6:5] == 2'b10)
|
||||
InstrDecompD = {7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or
|
||||
else // if (instr16[6:5] == 2'b11)
|
||||
InstrDecompD = {7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and
|
||||
else if (instr16[12:10] == 3'b111 && XLEN > 32)
|
||||
if (instr16[6:5] == 2'b00)
|
||||
InstrDecompD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw
|
||||
else if (instr16[6:5] == 2'b01)
|
||||
InstrDecompD = {7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw
|
||||
else begin // reserved
|
||||
IllegalCompInstrD = 1;
|
||||
InstrDecompD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
else begin // illegal instruction
|
||||
IllegalCompInstrD = 1;
|
||||
InstrDecompD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
5'b01101: InstrDecompD = {immCJ, 5'b00000, 7'b1101111}; // c.j
|
||||
5'b01110: InstrDecompD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz
|
||||
5'b01111: InstrDecompD = {immCB[11:5], 5'b00000, rs1p, 3'b001, immCB[4:0], 7'b1100011}; // c.bnez
|
||||
5'b10000: InstrDecompD = {6'b000000, immSH, rds1, 3'b001, rds1, 7'b0010011}; // c.slli
|
||||
5'b10001: InstrDecompD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000111}; // c.fldsp
|
||||
5'b10010: InstrDecompD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000011}; // c.lwsp
|
||||
5'b10011: if (XLEN == 32)
|
||||
InstrDecompD = {immCILSP, 5'b00010, 3'b010, rds1, 7'b0000111}; // c.flwsp
|
||||
else
|
||||
InstrDecompD = {immCILSPD, 5'b00010, 3'b011, rds1, 7'b0000011}; // c.ldsp
|
||||
5'b10100: if (instr16[12] == 0)
|
||||
if (instr16[6:2] == 5'b00000)
|
||||
InstrDecompD = {7'b0000000, 5'b00000, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr
|
||||
else
|
||||
InstrDecompD = {7'b0000000, rs2, 5'b00000, 3'b000, rds1, 7'b0110011}; // c.mv
|
||||
else
|
||||
if (rs2 == 5'b00000)
|
||||
if (rds1 == 5'b00000)
|
||||
InstrDecompD = {12'b1, 5'b00000, 3'b000, 5'b00000, 7'b1110011}; // c.ebreak
|
||||
else
|
||||
InstrDecompD = {12'b0, rds1, 3'b000, 5'b00001, 7'b1100111}; // c.jalr
|
||||
else
|
||||
InstrDecompD = {7'b0000000, rs2, rds1, 3'b000, rds1, 7'b0110011}; // c.add
|
||||
5'b10101: InstrDecompD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100111}; // c.fsdsp
|
||||
5'b10110: InstrDecompD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100011}; // c.swsp
|
||||
5'b10111: if (XLEN==32)
|
||||
InstrDecompD = {immCSS[11:5], rs2, 5'b00010, 3'b010, immCSS[4:0], 7'b0100111}; // c.fswsp
|
||||
else
|
||||
InstrDecompD = {immCSSD[11:5], rs2, 5'b00010, 3'b011, immCSSD[4:0], 7'b0100011}; // c.sdsp
|
||||
default: begin // illegal instruction
|
||||
IllegalCompInstrD = 1;
|
||||
InstrDecompD = {16'b0, instr16}; // preserve instruction for mtval on trap
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
189
wally-pipelined/src/memdp.sv
Normal file
189
wally-pipelined/src/memdp.sv
Normal file
@ -0,0 +1,189 @@
|
||||
///////////////////////////////////////////
|
||||
// memdp.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Memory datapath for subword accesses
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module memdp #(parameter XLEN=32) (
|
||||
input logic [1:0] MemRWM,
|
||||
input logic [XLEN-1:0] ReadDataM,
|
||||
input logic [XLEN-1:0] AdrM,
|
||||
input logic [2:0] Funct3M,
|
||||
output logic [XLEN-1:0] ReadDataExtM,
|
||||
input logic [XLEN-1:0] WriteDataM,
|
||||
output logic [XLEN-1:0] WriteDataExtM,
|
||||
output logic [7:0] ByteMaskM,
|
||||
input logic DataAccessFaultM,
|
||||
output logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||
output logic StoreMisalignedFaultM, StoreAccessFaultM);
|
||||
|
||||
logic [7:0] bytM;
|
||||
logic [15:0] HalfwordM;
|
||||
logic UnalignedM, AccessFaultM;
|
||||
|
||||
generate
|
||||
if (XLEN == 64) begin
|
||||
// bytMe mux
|
||||
always_comb
|
||||
case(AdrM[2:0])
|
||||
3'b000: bytM = ReadDataM[7:0];
|
||||
3'b001: bytM = ReadDataM[15:8];
|
||||
3'b010: bytM = ReadDataM[23:16];
|
||||
3'b011: bytM = ReadDataM[31:24];
|
||||
3'b100: bytM = ReadDataM[39:32];
|
||||
3'b101: bytM = ReadDataM[47:40];
|
||||
3'b110: bytM = ReadDataM[55:48];
|
||||
3'b111: bytM = ReadDataM[63:56];
|
||||
endcase
|
||||
|
||||
// halfword mux
|
||||
always_comb
|
||||
case(AdrM[2:1])
|
||||
2'b00: HalfwordM = ReadDataM[15:0];
|
||||
2'b01: HalfwordM = ReadDataM[31:16];
|
||||
2'b10: HalfwordM = ReadDataM[47:32];
|
||||
2'b11: HalfwordM = ReadDataM[63:48];
|
||||
endcase
|
||||
|
||||
logic [31:0] word;
|
||||
|
||||
always_comb
|
||||
case(AdrM[2])
|
||||
1'b0: word = ReadDataM[31:0];
|
||||
1'b1: word = ReadDataM[63:32];
|
||||
endcase
|
||||
|
||||
// sign extension
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: ReadDataExtM = {{56{bytM[7]}}, bytM}; // lb
|
||||
3'b001: ReadDataExtM = {{48{HalfwordM[15]}}, HalfwordM[15:0]}; // lh
|
||||
3'b010: ReadDataExtM = {{32{word[31]}}, word[31:0]}; // lw
|
||||
3'b011: ReadDataExtM = ReadDataM; // ld
|
||||
3'b100: ReadDataExtM = {56'b0, bytM[7:0]}; // lbu
|
||||
3'b101: ReadDataExtM = {48'b0, HalfwordM[15:0]}; // lhu
|
||||
3'b110: ReadDataExtM = {32'b0, word[31:0]}; // lwu
|
||||
default: ReadDataExtM = 64'b0;
|
||||
endcase
|
||||
|
||||
// Memory control
|
||||
|
||||
// Compute write mask
|
||||
always_comb
|
||||
if (StoreMisalignedFaultM || StoreAccessFaultM) ByteMaskM = 8'b00000000; // discard Unaligned stores
|
||||
else case(Funct3M)
|
||||
3'b000: begin ByteMaskM = 8'b00000000; ByteMaskM[AdrM[2:0]] = 1; end // sb
|
||||
3'b001: case (AdrM[2:1])
|
||||
2'b00: ByteMaskM = 8'b00000011;
|
||||
2'b01: ByteMaskM = 8'b00001100;
|
||||
2'b10: ByteMaskM = 8'b00110000;
|
||||
2'b11: ByteMaskM = 8'b11000000;
|
||||
endcase
|
||||
3'b010: if (AdrM[2]) ByteMaskM = 8'b11110000;
|
||||
else ByteMaskM = 8'b00001111;
|
||||
3'b011: ByteMaskM = 8'b11111111;
|
||||
default: ByteMaskM = 8'b00000000;
|
||||
endcase
|
||||
|
||||
// Handle subword writes
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: WriteDataExtM = {8{WriteDataM[7:0]}}; // sb
|
||||
3'b001: WriteDataExtM = {4{WriteDataM[15:0]}}; // sh
|
||||
3'b010: WriteDataExtM = {2{WriteDataM[31:0]}}; // sw
|
||||
3'b011: WriteDataExtM = WriteDataM; // sw
|
||||
default: WriteDataExtM = 64'b0;
|
||||
endcase
|
||||
|
||||
end else begin // 32-bit
|
||||
// byte mux
|
||||
always_comb
|
||||
case(AdrM[1:0])
|
||||
2'b00: bytM = ReadDataM[7:0];
|
||||
2'b01: bytM = ReadDataM[15:8];
|
||||
2'b10: bytM = ReadDataM[23:16];
|
||||
2'b11: bytM = ReadDataM[31:24];
|
||||
endcase
|
||||
|
||||
// halfword mux
|
||||
always_comb
|
||||
case(AdrM[1])
|
||||
1'b0: HalfwordM = ReadDataM[15:0];
|
||||
1'b1: HalfwordM = ReadDataM[31:16];
|
||||
endcase
|
||||
|
||||
// sign extension
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: ReadDataExtM = {{24{bytM[7]}}, bytM}; // lb
|
||||
3'b001: ReadDataExtM = {{16{HalfwordM[15]}}, HalfwordM[15:0]}; // lh
|
||||
3'b010: ReadDataExtM = ReadDataM; // lw
|
||||
3'b100: ReadDataExtM = {24'b0, bytM[7:0]}; // lbu
|
||||
3'b101: ReadDataExtM = {16'b0, HalfwordM[15:0]}; // lhu
|
||||
default: ReadDataExtM = 32'b0;
|
||||
endcase
|
||||
|
||||
// Memory control
|
||||
|
||||
// Compute write mask
|
||||
always_comb
|
||||
if (StoreMisalignedFaultM || StoreAccessFaultM) ByteMaskM = 8'b0000; // discard Unaligned stores
|
||||
else case(Funct3M)
|
||||
3'b000: begin ByteMaskM = 8'b0000; ByteMaskM[{1'b0,AdrM[1:0]}] = 1; end // sb
|
||||
3'b001: if (AdrM[1]) ByteMaskM = 8'b1100;
|
||||
else ByteMaskM = 8'b0011;
|
||||
3'b010: ByteMaskM = 8'b1111;
|
||||
default: ByteMaskM = 8'b0000;
|
||||
endcase
|
||||
|
||||
// Handle subword writes
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: WriteDataExtM = {4{WriteDataM[7:0]}}; // sb
|
||||
3'b001: WriteDataExtM = {2{WriteDataM[15:0]}}; // sh
|
||||
3'b010: WriteDataExtM = WriteDataM; // sw
|
||||
default: WriteDataExtM = 32'b0;
|
||||
endcase
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Determine if an Unaligned access is taking place
|
||||
always_comb
|
||||
case(Funct3M)
|
||||
3'b000: UnalignedM = 0; // lb, sb
|
||||
3'b001: UnalignedM = AdrM[0]; // lh, sh
|
||||
3'b010: UnalignedM = AdrM[1] | AdrM[0]; // lw, sw, flw, fsw
|
||||
3'b011: UnalignedM = |AdrM[2:0]; // ld, sd, fld, fsd
|
||||
3'b100: UnalignedM = 0; // lbu
|
||||
3'b101: UnalignedM = AdrM[0]; // lhu
|
||||
3'b110: UnalignedM = |AdrM[1:0]; // lwu
|
||||
default: UnalignedM = 0;
|
||||
endcase
|
||||
|
||||
// Determine if address is valid
|
||||
assign LoadMisalignedFaultM = UnalignedM & MemRWM[1];
|
||||
assign LoadAccessFaultM = DataAccessFaultM & MemRWM[0];
|
||||
assign StoreMisalignedFaultM = UnalignedM & MemRWM[0];
|
||||
assign StoreAccessFaultM = DataAccessFaultM & MemRWM[0];
|
||||
endmodule
|
52
wally-pipelined/src/mux.sv
Normal file
52
wally-pipelined/src/mux.sv
Normal file
@ -0,0 +1,52 @@
|
||||
///////////////////////////////////////////
|
||||
// mux.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Various flavors of multiplexers
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
|
||||
module mux2 #(parameter WIDTH = 8) (
|
||||
input logic [WIDTH-1:0] d0, d1,
|
||||
input logic s,
|
||||
output logic [WIDTH-1:0] y);
|
||||
|
||||
assign y = s ? d1 : d0;
|
||||
endmodule
|
||||
|
||||
module mux3 #(parameter WIDTH = 8) (
|
||||
input logic [WIDTH-1:0] d0, d1, d2,
|
||||
input logic [1:0] s,
|
||||
output logic [WIDTH-1:0] y);
|
||||
|
||||
assign y = s[1] ? d2 : (s[0] ? d1 : d0);
|
||||
endmodule
|
||||
|
||||
module mux4 #(parameter WIDTH = 8) (
|
||||
input logic [WIDTH-1:0] d0, d1, d2, d3,
|
||||
input logic [1:0] s,
|
||||
output logic [WIDTH-1:0] y);
|
||||
|
||||
assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0);
|
||||
endmodule
|
||||
|
50
wally-pipelined/src/pcadder.sv
Normal file
50
wally-pipelined/src/pcadder.sv
Normal file
@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////
|
||||
// pcadder.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Determine next PC = PC+2 or PC+4
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module pcadder #(parameter XLEN=32) (
|
||||
input logic [XLEN-1:0] pc,
|
||||
input logic [31:0] instr,
|
||||
output logic [XLEN-1:0] pcplus);
|
||||
|
||||
logic [1:0] op;
|
||||
logic [XLEN-3:0] pcplusupper;
|
||||
logic compressed;
|
||||
|
||||
// add 2 or 4 to the PC, based on whether the instruction is 16 bits or 32
|
||||
assign op = instr[1:0];
|
||||
assign compressed = (op != 2'b11); // is it a 16-bit compressed instruction?
|
||||
|
||||
assign pcplusupper = pc[XLEN-1:2] + 1; // add 4 to PC
|
||||
|
||||
// choose PC+2 or PC+4
|
||||
always_comb
|
||||
if (compressed) // add 2
|
||||
if (pc[1]) pcplus = {pcplusupper, 2'b00};
|
||||
else pcplus = {pc[XLEN-1:2], 2'b10};
|
||||
else pcplus = {pcplusupper, pc[1:0]}; // add 4
|
||||
endmodule
|
||||
|
73
wally-pipelined/src/pclogic.sv
Normal file
73
wally-pipelined/src/pclogic.sv
Normal file
@ -0,0 +1,73 @@
|
||||
///////////////////////////////////////////
|
||||
// pclogic.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Determine Program Counter considering branches, exceptions, ret, reset
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module pclogic #(parameter XLEN=64, MISA=0) (
|
||||
input logic clk, reset,
|
||||
input logic StallF, PCSrcE,
|
||||
input logic [31:0] InstrF,
|
||||
input logic [XLEN-1:0] ExtImmE, TargetBaseE,
|
||||
input logic RetM, TrapM,
|
||||
input logic [XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic [XLEN-1:0] PCF, PCPlus2or4F,
|
||||
output logic InstrMisalignedFaultM,
|
||||
output logic [XLEN-1:0] InstrMisalignedAdrM);
|
||||
|
||||
logic [XLEN-1:0] UnalignedPCNextF, PCNextF, PCTargetE;
|
||||
// logic [XLEN-1:0] ResetVector = 'h100;
|
||||
// logic [XLEN-1:0] ResetVector = 'he4;
|
||||
logic [XLEN-1:0] ResetVector = {{(XLEN-32){1'b0}}, 32'h80000000};
|
||||
logic misaligned, BranchMisalignedFaultE, BranchMisalignedFaultM, TrapMisalignedFaultM;
|
||||
logic StallExceptResolveBranchesF, PrivilegedChangePCM;
|
||||
|
||||
assign PrivilegedChangePCM = RetM | TrapM;
|
||||
|
||||
assign StallExceptResolveBranchesF = StallF & ~(PCSrcE | PrivilegedChangePCM);
|
||||
|
||||
assign PCTargetE = ExtImmE + TargetBaseE;
|
||||
mux3 #(XLEN) pcmux(PCPlus2or4F, PCTargetE, PrivilegedNextPCM, {PrivilegedChangePCM, PCSrcE}, UnalignedPCNextF);
|
||||
assign PCNextF = {UnalignedPCNextF[XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
||||
flopenl #(XLEN) pcreg(clk, reset, ~StallExceptResolveBranchesF, PCNextF, ResetVector, PCF);
|
||||
pcadder #(XLEN) pcadd(PCF, InstrF, PCPlus2or4F);
|
||||
|
||||
// Misaligned PC logic
|
||||
|
||||
generate
|
||||
if (`C_SUPPORTED) // C supports compressed instructions on halfword boundaries
|
||||
assign misaligned = PCNextF[0];
|
||||
else // instructions must be on word boundaries
|
||||
assign misaligned = |PCNextF[1:0];
|
||||
endgenerate
|
||||
|
||||
// pipeline misaligned faults to M stage
|
||||
assign BranchMisalignedFaultE = misaligned & PCSrcE; // E-stage (Branch/Jump) misaligned
|
||||
flopr #(1) InstrMisalginedReg(clk, reset, BranchMisalignedFaultE, BranchMisalignedFaultM);
|
||||
flopr #(XLEN) InstrMisalignedAdrReg(clk, reset, PCNextF, InstrMisalignedAdrM);
|
||||
assign TrapMisalignedFaultM = misaligned & PrivilegedChangePCM;
|
||||
assign InstrMisalignedFaultM = BranchMisalignedFaultM; // | TrapMisalignedFaultM; *** put this back in without causing a cyclic path
|
||||
|
||||
endmodule
|
||||
|
54
wally-pipelined/src/privilegeDecoder.sv
Normal file
54
wally-pipelined/src/privilegeDecoder.sv
Normal file
@ -0,0 +1,54 @@
|
||||
///////////////////////////////////////////
|
||||
// privilegeDecoder.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Decode Privileged & related instructions
|
||||
// See RISC-V Privileged Mode Specification 20190608 3.1.10-11
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module privilegeDecoder #(parameter MISA=0) (
|
||||
input logic [31:20] InstrM,
|
||||
input logic PrivilegedM, IllegalInstrFaultInM, IllegalCSRAccessM,
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic STATUS_TSR,
|
||||
output logic IllegalInstrFaultM,
|
||||
output logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
|
||||
|
||||
logic IllegalPrivilegedInstrM;
|
||||
|
||||
// xRET defined in Privileged Spect 3.2.2
|
||||
assign uretM = PrivilegedM & (InstrM[31:20] == 12'b000000000010) & `N_SUPPORTED;
|
||||
assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & `S_SUPPORTED &&
|
||||
PrivilegeModeW[0] & ~STATUS_TSR;
|
||||
assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) && (PrivilegeModeW == `M_MODE);
|
||||
|
||||
assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000);
|
||||
assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001);
|
||||
assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101);
|
||||
assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001);
|
||||
assign IllegalPrivilegedInstrM = PrivilegedM & ~(uretM|sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
|
||||
assign IllegalInstrFaultM = IllegalInstrFaultInM | IllegalPrivilegedInstrM | IllegalCSRAccessM;
|
||||
|
||||
// *** initially, wfi and sfencevma are nop
|
||||
// *** zfenci extension?
|
||||
endmodule
|
59
wally-pipelined/src/privilegeModeReg.sv
Normal file
59
wally-pipelined/src/privilegeModeReg.sv
Normal file
@ -0,0 +1,59 @@
|
||||
///////////////////////////////////////////
|
||||
// privilegeModeReg.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Track current privilege mode
|
||||
// See RISC-V Privileged Mode Specification 20190608
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module privilegeModeReg #(parameter XLEN=32, MISA=0) (
|
||||
input logic clk, reset,
|
||||
input logic mretM, sretM, uretM, TrapM,
|
||||
input logic [1:0] STATUS_MPP,
|
||||
input logic STATUS_SPP,
|
||||
input logic [XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW, CauseM,
|
||||
output logic [1:0] NextPrivilegeModeM, PrivilegeModeW);
|
||||
|
||||
logic md, sd;
|
||||
// get bits of DELEG registers based on CAUSE
|
||||
assign md = CauseM[XLEN-1] ? MIDELEG_REGW[CauseM[4:0]] : MEDELEG_REGW[CauseM[4:0]];
|
||||
assign sd = CauseM[XLEN-1] ? SIDELEG_REGW[CauseM[4:0]] : SEDELEG_REGW[CauseM[4:0]]; // depricated
|
||||
|
||||
always_comb
|
||||
if (reset) NextPrivilegeModeM = `M_MODE; // Privilege resets to 11 (Machine Mode)
|
||||
else if (mretM) NextPrivilegeModeM = STATUS_MPP;
|
||||
else if (sretM) NextPrivilegeModeM = {1'b0, STATUS_SPP};
|
||||
else if (uretM) NextPrivilegeModeM = `U_MODE;
|
||||
else if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
|
||||
if (PrivilegeModeW == `U_MODE)
|
||||
if (`N_SUPPORTED & `U_SUPPORTED & md & sd) NextPrivilegeModeM = `U_MODE;
|
||||
else if (`S_SUPPORTED & md) NextPrivilegeModeM = `S_MODE;
|
||||
else NextPrivilegeModeM = `M_MODE;
|
||||
else if (PrivilegeModeW == `S_MODE)
|
||||
if (`S_SUPPORTED & md) NextPrivilegeModeM = `S_MODE;
|
||||
else NextPrivilegeModeM = `M_MODE;
|
||||
else NextPrivilegeModeM = `M_MODE;
|
||||
end else NextPrivilegeModeM = PrivilegeModeW; // stay at same level when there is no exception or return
|
||||
flop #(2) PrivlegeReg(clk, NextPrivilegeModeM, PrivilegeModeW);
|
||||
|
||||
endmodule
|
117
wally-pipelined/src/privileged.sv
Normal file
117
wally-pipelined/src/privileged.sv
Normal file
@ -0,0 +1,117 @@
|
||||
///////////////////////////////////////////
|
||||
// exceptions.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 5 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Implements the CSRs, Exceptions, and Privileged operations
|
||||
// See RISC-V Privileged Mode Specification 20190608
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module privileged #(parameter XLEN=32, MISA = 0, ZCSR = 1, ZCOUNTERS = 1)(
|
||||
input logic clk, reset,
|
||||
input logic CSRWriteM,
|
||||
input logic [XLEN-1:0] SrcAM,
|
||||
input logic [31:0] InstrM,
|
||||
input logic [XLEN-1:0] PCM,
|
||||
output logic [XLEN-1:0] CSRReadValM,
|
||||
output logic [XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic RetM, TrapM,
|
||||
input logic InstrValidW, FloatRegWriteW, LoadStallD,
|
||||
input logic PrivilegedM,
|
||||
input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultInM,
|
||||
input logic LoadMisalignedFaultM, LoadAccessFaultM,
|
||||
input logic StoreMisalignedFaultM, StoreAccessFaultM,
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
input logic [XLEN-1:0] InstrMisalignedAdrM, ALUResultM,
|
||||
input logic [4:0] SetFflagsM,
|
||||
output logic [2:0] FRM_REGW
|
||||
);
|
||||
|
||||
logic [1:0] NextPrivilegeModeM, PrivilegeModeW;
|
||||
|
||||
logic [XLEN-1:0] CauseM, NextFaultMtvalM;
|
||||
logic [XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW;
|
||||
logic [XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW;
|
||||
// logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW;
|
||||
|
||||
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
|
||||
logic IllegalCSRAccess, IllegalInstrFaultM;
|
||||
|
||||
logic SwInt, TimerInt, ExtInt;
|
||||
logic BreakpointFaultM, EcallFaultM;
|
||||
logic InstrPageFaultM, LoadPageFaultM, StorePageFaultM;
|
||||
logic MTrapM, STrapM, UTrapM;
|
||||
|
||||
logic [1:0] STATUS_MPP;
|
||||
logic STATUS_SPP, STATUS_TSR;
|
||||
logic STATUS_MIE, STATUS_SIE;
|
||||
logic [11:0] MIP_REGW, MIE_REGW;
|
||||
|
||||
// track the current privilege level
|
||||
privilegeModeReg #(XLEN, MISA) pmr (clk, reset, mretM, sretM, uretM, TrapM,
|
||||
STATUS_MPP, STATUS_SPP, MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW,
|
||||
CauseM, NextPrivilegeModeM, PrivilegeModeW);
|
||||
|
||||
// decode privileged instructions
|
||||
privilegeDecoder #(MISA) pmd(InstrM[31:20], PrivilegedM, IllegalInstrFaultInM, IllegalCSRAccess, PrivilegeModeW, STATUS_TSR,
|
||||
IllegalInstrFaultM, uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
|
||||
|
||||
// Extract exceptions by name and handle them
|
||||
assign BreakpointFaultM = ebreakM; // could have other causes too
|
||||
assign EcallFaultM = ecallM;
|
||||
assign InstrPageFaultM = 0;
|
||||
assign LoadPageFaultM = 0;
|
||||
assign StorePageFaultM = 0;
|
||||
trap #(XLEN, MISA) trap(clk, reset, InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
|
||||
BreakpointFaultM, LoadMisalignedFaultM, StoreMisalignedFaultM,
|
||||
LoadAccessFaultM, StoreAccessFaultM, EcallFaultM, InstrPageFaultM,
|
||||
LoadPageFaultM, StorePageFaultM,
|
||||
mretM, sretM, uretM, PrivilegeModeW, NextPrivilegeModeM,
|
||||
MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
|
||||
MIP_REGW, MIE_REGW, STATUS_MIE, STATUS_SIE,
|
||||
InstrMisalignedAdrM, ALUResultM, InstrM,
|
||||
TrapM, MTrapM, STrapM, UTrapM, RetM,
|
||||
PrivilegedNextPCM, CauseM, NextFaultMtvalM
|
||||
// MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
);
|
||||
|
||||
// Control and Status Registers
|
||||
csr #(XLEN, MISA, ZCSR, ZCOUNTERS) csr(clk, reset,
|
||||
InstrM, PCM, SrcAM,
|
||||
CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM,
|
||||
TimerIntM, ExtIntM, SwIntM,
|
||||
InstrValidW, FloatRegWriteW, LoadStallD,
|
||||
NextPrivilegeModeM, PrivilegeModeW,
|
||||
CauseM, NextFaultMtvalM,
|
||||
STATUS_MPP, STATUS_SPP, STATUS_TSR,
|
||||
MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
|
||||
MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW,
|
||||
MIP_REGW, MIE_REGW, STATUS_MIE, STATUS_SIE,
|
||||
SetFflagsM, FRM_REGW,
|
||||
// MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
CSRReadValM, IllegalCSRAccess
|
||||
);
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
52
wally-pipelined/src/regfile.sv
Normal file
52
wally-pipelined/src/regfile.sv
Normal file
@ -0,0 +1,52 @@
|
||||
///////////////////////////////////////////
|
||||
// regfile.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: 3-port register file
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module regfile #(parameter XLEN=32) (
|
||||
input logic clk, reset,
|
||||
input logic we3,
|
||||
input logic [ 4:0] a1, a2, a3,
|
||||
input logic [XLEN-1:0] wd3,
|
||||
output logic [XLEN-1:0] rd1, rd2);
|
||||
|
||||
logic [XLEN-1:0] rf[31:0];
|
||||
integer i;
|
||||
|
||||
// three ported register file
|
||||
// read two ports combinationally (A1/RD1, A2/RD2)
|
||||
// write third port on rising edge of clock (A3/WD3/WE3)
|
||||
// write occurs on falling edge of clock
|
||||
// register 0 hardwired to 0
|
||||
|
||||
// reset is intended for simulation only, not synthesis
|
||||
|
||||
always_ff @(negedge clk or posedge reset)
|
||||
if (reset) for(i=0; i<32; i++) rf[i] <= 0;
|
||||
else if (we3) rf[a3] <= wd3;
|
||||
|
||||
assign #2 rd1 = (a1 != 0) ? rf[a1] : 0;
|
||||
assign #2 rd2 = (a2 != 0) ? rf[a2] : 0;
|
||||
endmodule
|
96
wally-pipelined/src/shifter.sv
Normal file
96
wally-pipelined/src/shifter.sv
Normal file
@ -0,0 +1,96 @@
|
||||
///////////////////////////////////////////
|
||||
// shifter.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: RISC-V 32/64 bit shifter
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module shifter #(parameter WIDTH=32) (
|
||||
input logic [WIDTH-1:0] a,
|
||||
input logic [5:0] amt,
|
||||
input logic right, arith, w64,
|
||||
output logic [WIDTH-1:0] y);
|
||||
|
||||
// The best shifter architecture differs based on XLEN.
|
||||
// for RV32, only 32-bit shifts are needed. These are
|
||||
// most efficiently implemented with a funnel shifter.
|
||||
// For RV64, 32 and 64-bit shifts are needed, with sign
|
||||
// extension.
|
||||
|
||||
generate
|
||||
if (WIDTH==32) begin
|
||||
// funnel shifter (see CMOS VLSI Design 4e Section 11.8.1, note Table 11.11 shift types wrong)
|
||||
logic [62:0] z, zshift;
|
||||
logic [4:0] offset;
|
||||
|
||||
// funnel input
|
||||
always_comb
|
||||
if (right)
|
||||
if (arith) z = {{31{a[31]}}, a};
|
||||
else z = {31'b0, a};
|
||||
else z = {a, 31'b0};
|
||||
|
||||
// shift amount
|
||||
assign offset = right ? amt[4:0] : ~amt[4:0];
|
||||
|
||||
// funnel operation
|
||||
assign zshift = z >> offset;
|
||||
assign y = zshift[WIDTH-1:0];
|
||||
end else begin // RV64
|
||||
// funnel shifter followed by masking
|
||||
// research idea: investigate shifter designs for mixed 32/64-bit shifts
|
||||
logic [126:0] z, zshift;
|
||||
logic [31:0] ylower, yupper;
|
||||
logic [5:0] offset, amt6;
|
||||
|
||||
// funnel input
|
||||
always_comb
|
||||
if (w64) begin // 32-bit shifts
|
||||
if (right)
|
||||
if (arith) z = {64'b0, {31{a[31]}}, a[31:0]};
|
||||
else z = {95'b0, a[31:0]};
|
||||
else z = {32'b0, a[31:0], 63'b0};
|
||||
end else begin
|
||||
if (right)
|
||||
if (arith) z = {{63{a[63]}}, a};
|
||||
else z = {63'b0, a};
|
||||
else z = {a, 63'b0};
|
||||
end
|
||||
|
||||
// shift amount
|
||||
assign amt6 = w64 ? {1'b0, amt[4:0]} : amt[5:0]; // 32 or 64-bit shift
|
||||
assign offset = right ? amt6 : ~amt6;
|
||||
|
||||
// funnel operation
|
||||
assign zshift = z >> offset;
|
||||
assign ylower = zshift[31:0];
|
||||
|
||||
// mask upper 32 bits for W-type 32-bit shifts
|
||||
// harris: is there a clever way to get zshift[31] earlier for arithmetic right shifts to speed up critical path?
|
||||
assign yupper = w64 ? {32{zshift[31]}} : zshift[63:32];
|
||||
assign y = {yupper, ylower};
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
|
465
wally-pipelined/src/testbench.sv
Normal file
465
wally-pipelined/src/testbench.sv
Normal file
@ -0,0 +1,465 @@
|
||||
///////////////////////////////////////////
|
||||
// testbench.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Wally Testbench and helper modules
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module testbench #(parameter XLEN=64, MISA=32'h00000104, ZCSR = 1, ZCOUNTERS = 1)();
|
||||
logic clk;
|
||||
logic reset;
|
||||
|
||||
logic [XLEN-1:0] WriteData, DataAdr;
|
||||
logic [1:0] MemRW;
|
||||
|
||||
int test, i, errors, totalerrors;
|
||||
logic [31:0] sig32[0:10000];
|
||||
logic [XLEN-1:0] signature[0:10000];
|
||||
logic [XLEN-1:0] testadr;
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
logic [31:0] InstrW;
|
||||
logic [XLEN-1:0] meminit;
|
||||
string tests64ic[] = '{
|
||||
|
||||
"rv64ic/I-C-ADD-01", "3000",
|
||||
"rv64ic/I-C-ADDI-01", "3000",
|
||||
"rv64ic/I-C-ADDIW-01", "3000",
|
||||
"rv64ic/I-C-ADDW-01", "3000",
|
||||
"rv64ic/I-C-AND-01", "3000",
|
||||
"rv64ic/I-C-ANDI-01", "3000",
|
||||
"rv64ic/I-C-BEQZ-01", "3000",
|
||||
"rv64ic/I-C-BNEZ-01", "3000",
|
||||
"rv64ic/I-C-EBREAK-01", "2000",
|
||||
"rv64ic/I-C-J-01", "3000",
|
||||
"rv64ic/I-C-JALR-01", "4000",
|
||||
"rv64ic/I-C-JR-01", "4000",
|
||||
"rv64ic/I-C-LD-01", "3420",
|
||||
"rv64ic/I-C-LDSP-01", "3420",
|
||||
"rv64ic/I-C-LI-01", "3000",
|
||||
"rv64ic/I-C-LUI-01", "2000",
|
||||
"rv64ic/I-C-LW-01", "3110",
|
||||
"rv64ic/I-C-LWSP-01", "3110",
|
||||
"rv64ic/I-C-MV-01", "3000",
|
||||
"rv64ic/I-C-NOP-01", "2000",
|
||||
"rv64ic/I-C-OR-01", "3000",
|
||||
"rv64ic/I-C-SD-01", "3000",
|
||||
"rv64ic/I-C-SDSP-01", "3000",
|
||||
"rv64ic/I-C-SLLI-01", "3000",
|
||||
"rv64ic/I-C-SRAI-01", "3000",
|
||||
"rv64ic/I-C-SRLI-01", "3000",
|
||||
"rv64ic/I-C-SUB-01", "3000",
|
||||
"rv64ic/I-C-SUBW-01", "3000",
|
||||
"rv64ic/I-C-SW-01", "3000",
|
||||
"rv64ic/I-C-SWSP-01", "3000",
|
||||
"rv64ic/I-C-XOR-01", "3000"
|
||||
};
|
||||
string tests64iNOc[] = {
|
||||
"rv64i/I-MISALIGN_JMP-01","2000"
|
||||
};
|
||||
string tests64i[] = '{
|
||||
"rv64i/I-ADD-01", "3000",
|
||||
"rv64i/I-ADDI-01", "3000",
|
||||
"rv64i/I-ADDIW-01", "3000",
|
||||
"rv64i/I-ADDW-01", "3000",
|
||||
"rv64i/I-AND-01", "3000",
|
||||
"rv64i/I-ANDI-01", "3000",
|
||||
"rv64i/I-AUIPC-01", "3000",
|
||||
"rv64i/I-BEQ-01", "4000",
|
||||
"rv64i/I-BGE-01", "4000",
|
||||
"rv64i/I-BGEU-01", "4000",
|
||||
"rv64i/I-BLT-01", "4000",
|
||||
"rv64i/I-BLTU-01", "4000",
|
||||
"rv64i/I-BNE-01", "4000",
|
||||
"rv64i/I-DELAY_SLOTS-01", "2000",
|
||||
"rv64i/I-EBREAK-01", "2000",
|
||||
"rv64i/I-ECALL-01", "2000",
|
||||
"rv64i/I-ENDIANESS-01", "2010",
|
||||
"rv64i/I-IO-01", "2050",
|
||||
"rv64i/I-JAL-01", "3000",
|
||||
"rv64i/I-JALR-01", "4000",
|
||||
"rv64i/I-LB-01", "4020",
|
||||
"rv64i/I-LBU-01", "4020",
|
||||
"rv64i/I-LD-01", "4420",
|
||||
"rv64i/I-LH-01", "4050",
|
||||
"rv64i/I-LHU-01", "4050",
|
||||
"rv64i/I-LUI-01", "2000",
|
||||
"rv64i/I-LW-01", "4110",
|
||||
"rv64i/I-LWU-01", "4110",
|
||||
"rv64i/I-MISALIGN_LDST-01", "2010",
|
||||
"rv64i/I-NOP-01", "2000",
|
||||
"rv64i/I-OR-01", "3000",
|
||||
"rv64i/I-ORI-01", "3000",
|
||||
"rv64i/I-RF_size-01", "2000",
|
||||
"rv64i/I-RF_width-01", "2000",
|
||||
"rv64i/I-RF_x0-01", "2010",
|
||||
"rv64i/I-SB-01", "4000",
|
||||
"rv64i/I-SD-01", "4000",
|
||||
"rv64i/I-SH-01", "4000",
|
||||
"rv64i/I-SLL-01", "3000",
|
||||
"rv64i/I-SLLI-01", "3000",
|
||||
"rv64i/I-SLLIW-01", "3000",
|
||||
"rv64i/I-SLLW-01", "3000",
|
||||
"rv64i/I-SLT-01", "3000",
|
||||
"rv64i/I-SLTI-01", "3000",
|
||||
"rv64i/I-SLTIU-01", "3000",
|
||||
"rv64i/I-SLTU-01", "3000",
|
||||
"rv64i/I-SRA-01", "3000",
|
||||
"rv64i/I-SRAI-01", "3000",
|
||||
"rv64i/I-SRAIW-01", "3000",
|
||||
"rv64i/I-SRAW-01", "3000",
|
||||
"rv64i/I-SRL-01", "3000",
|
||||
"rv64i/I-SRLI-01", "3000",
|
||||
"rv64i/I-SRLIW-01", "3000",
|
||||
"rv64i/I-SRLW-01", "3000",
|
||||
"rv64i/I-SUB-01", "3000",
|
||||
"rv64i/I-SUBW-01", "3000",
|
||||
"rv64i/I-SW-01", "4000",
|
||||
"rv64i/I-XOR-01", "3000",
|
||||
"rv64i/I-XORI-01", "3000"
|
||||
};
|
||||
string tests32ic[] = '{
|
||||
// "rv32ic/WALLY-C-ADHOC-01", "2000",
|
||||
"rv32ic/I-C-ADD-01", "2000",
|
||||
"rv32ic/I-C-ADDI-01", "2000",
|
||||
"rv32ic/I-C-AND-01", "2000",
|
||||
"rv32ic/I-C-ANDI-01", "2000",
|
||||
"rv32ic/I-C-BEQZ-01", "2000",
|
||||
"rv32ic/I-C-BNEZ-01", "2000",
|
||||
"rv32ic/I-C-EBREAK-01", "2000",
|
||||
"rv32ic/I-C-J-01", "2000",
|
||||
"rv32ic/I-C-JALR-01", "3000",
|
||||
"rv32ic/I-C-JR-01", "3000",
|
||||
"rv32ic/I-C-LI-01", "2000",
|
||||
"rv32ic/I-C-LUI-01", "2000",
|
||||
"rv32ic/I-C-LW-01", "2110",
|
||||
"rv32ic/I-C-LWSP-01", "2110",
|
||||
"rv32ic/I-C-MV-01", "2000",
|
||||
"rv32ic/I-C-NOP-01", "2000",
|
||||
"rv32ic/I-C-OR-01", "2000",
|
||||
"rv32ic/I-C-SLLI-01", "2000",
|
||||
"rv32ic/I-C-SRAI-01", "2000",
|
||||
"rv32ic/I-C-SRLI-01", "2000",
|
||||
"rv32ic/I-C-SUB-01", "2000",
|
||||
"rv32ic/I-C-SW-01", "2000",
|
||||
"rv32ic/I-C-SWSP-01", "2000",
|
||||
"rv32ic/I-C-XOR-01", "2000"
|
||||
};
|
||||
string tests32iNOc[] = {
|
||||
"rv32i/I-MISALIGN_JMP-01","2000"
|
||||
};
|
||||
string tests32i[] = {
|
||||
"rv32i/I-ADD-01", "2000",
|
||||
"rv32i/I-ADDI-01","2000",
|
||||
"rv32i/I-AND-01","2000",
|
||||
"rv32i/I-ANDI-01","2000",
|
||||
"rv32i/I-AUIPC-01","2000",
|
||||
"rv32i/I-BEQ-01","3000",
|
||||
"rv32i/I-BGE-01","3000",
|
||||
"rv32i/I-BGEU-01","3000",
|
||||
"rv32i/I-BLT-01","3000",
|
||||
"rv32i/I-BLTU-01","3000",
|
||||
"rv32i/I-BNE-01","3000",
|
||||
"rv32i/I-DELAY_SLOTS-01","2000",
|
||||
"rv32i/I-EBREAK-01","2000",
|
||||
"rv32i/I-ECALL-01","2000",
|
||||
"rv32i/I-ENDIANESS-01","2010",
|
||||
"rv32i/I-IO-01","2030",
|
||||
"rv32i/I-JAL-01","3000",
|
||||
"rv32i/I-JALR-01","3000",
|
||||
"rv32i/I-LB-01","3020",
|
||||
"rv32i/I-LBU-01","3020",
|
||||
"rv32i/I-LH-01","3050",
|
||||
"rv32i/I-LHU-01","3050",
|
||||
"rv32i/I-LUI-01","2000",
|
||||
"rv32i/I-LW-01","3110",
|
||||
"rv32i/I-MISALIGN_LDST-01","2010",
|
||||
"rv32i/I-NOP-01","2000",
|
||||
"rv32i/I-OR-01","2000",
|
||||
"rv32i/I-ORI-01","2000",
|
||||
"rv32i/I-RF_size-01","2000",
|
||||
"rv32i/I-RF_width-01","2000",
|
||||
"rv32i/I-RF_x0-01","2010",
|
||||
"rv32i/I-SB-01","3000",
|
||||
"rv32i/I-SH-01","3000",
|
||||
"rv32i/I-SLL-01","2000",
|
||||
"rv32i/I-SLLI-01","2000",
|
||||
"rv32i/I-SLT-01","2000",
|
||||
"rv32i/I-SLTI-01","2000",
|
||||
"rv32i/I-SLTIU-01","2000",
|
||||
"rv32i/I-SLTU-01","2000",
|
||||
"rv32i/I-SRA-01","2000",
|
||||
"rv32i/I-SRAI-01","2000",
|
||||
"rv32i/I-SRL-01","2000",
|
||||
"rv32i/I-SRLI-01","2000",
|
||||
"rv32i/I-SUB-01","2000",
|
||||
"rv32i/I-SW-01","3000",
|
||||
"rv32i/I-XOR-01","2000",
|
||||
"rv32i/I-XORI-01","2000"
|
||||
};
|
||||
string tests[];
|
||||
|
||||
// pick tests based on modes supported
|
||||
initial
|
||||
if (XLEN == 64) begin // RV64
|
||||
tests = {tests64i};
|
||||
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests64ic};
|
||||
else tests = {tests, tests64iNOc};
|
||||
end else begin // RV32
|
||||
tests = {tests32i};
|
||||
if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic};
|
||||
else tests = {tests, tests32iNOc};
|
||||
end
|
||||
string signame, memfilename;
|
||||
|
||||
// instantiate device to be tested
|
||||
wallypipelined #(XLEN, MISA, ZCSR, ZCOUNTERS) dut(clk, reset, WriteData, DataAdr, MemRW);
|
||||
|
||||
// Track names of instructions
|
||||
instrTrackerTB #(XLEN) it(clk, reset, dut.hart.dp.FlushE,
|
||||
dut.hart.dp.InstrDecompD, dut.hart.dp.InstrE,
|
||||
dut.hart.dp.InstrM, InstrW,
|
||||
InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// initialize test
|
||||
initial
|
||||
begin
|
||||
test = 0;
|
||||
totalerrors = 0;
|
||||
testadr = 0;
|
||||
// fill memory with defined values to reduce Xs in simulation
|
||||
if (XLEN == 32) meminit = 32'hFEDC0123;
|
||||
else meminit = 64'hFEDCBA9876543210;
|
||||
for (i=0; i<=65535; i = i+1) begin
|
||||
//dut.imem.RAM[i] = meminit;
|
||||
// dut.dmem.RAM[i] = meminit;
|
||||
end
|
||||
// read test vectors into memory
|
||||
memfilename = {"../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
||||
$readmemh(memfilename, dut.imem.RAM);
|
||||
$readmemh(memfilename, dut.dmem.dtim.RAM);
|
||||
reset = 1; # 22; reset = 0;
|
||||
end
|
||||
|
||||
// generate clock to sequence tests
|
||||
always
|
||||
begin
|
||||
clk = 1; # 5; clk = 0; # 5;
|
||||
end
|
||||
|
||||
// check results
|
||||
always @(negedge clk)
|
||||
begin
|
||||
if (dut.hart.dp.priv.EcallFaultM &&
|
||||
(dut.hart.dp.regf.rf[3] == 1 || (dut.hart.dp.regf.we3 && dut.hart.dp.regf.a3 == 3 && dut.hart.dp.regf.wd3 == 1))) begin
|
||||
$display("Code ended with ecall with gp = 1");
|
||||
#60; // give time for instructions in pipeline to finish
|
||||
// clear signature to prevent contamination from previous tests
|
||||
for(i=0; i<10000; i=i+1) begin
|
||||
sig32[i] = 'bx;
|
||||
end
|
||||
|
||||
// read signature, reformat in 64 bits if necessary
|
||||
signame = {"../imperas-riscv-tests/work/", tests[test], ".signature.output"};
|
||||
$readmemh(signame, sig32);
|
||||
i = 0;
|
||||
while (i < 10000) begin
|
||||
if (XLEN == 32) begin
|
||||
signature[i] = sig32[i];
|
||||
i = i+1;
|
||||
end else begin
|
||||
signature[i/2] = {sig32[i+1], sig32[i]};
|
||||
i = i + 2;
|
||||
end
|
||||
end
|
||||
|
||||
// Check errors
|
||||
i = 0;
|
||||
errors = 0;
|
||||
if (XLEN == 32)
|
||||
testadr = tests[test+1].atohex()/4;
|
||||
else
|
||||
testadr = tests[test+1].atohex()/8;
|
||||
/* verilator lint_off INFINITELOOP */
|
||||
while (signature[i] !== 'bx) begin
|
||||
//$display("signature[%h] = %h", i, signature[i]);
|
||||
if (signature[i] !== dut.dmem.dtim.RAM[testadr+i]) begin
|
||||
if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) begin
|
||||
// report errors unless they are garbage at the end of the sim
|
||||
// kind of hacky test for garbage right now
|
||||
errors = errors+1;
|
||||
$display(" Error on test %s result %d: adr = %h sim = %h, signature = %h",
|
||||
tests[test], i, (testadr+i)*XLEN/8, dut.dmem.dtim.RAM[testadr+i], signature[i]);
|
||||
end
|
||||
end
|
||||
i = i + 1;
|
||||
end
|
||||
/* verilator lint_on INFINITELOOP */
|
||||
if (errors == 0) $display("%s succeeded. Brilliant!!!", tests[test]);
|
||||
else begin
|
||||
$display("%s failed with %d errors. :(", tests[test], errors);
|
||||
totalerrors = totalerrors+1;
|
||||
end
|
||||
test = test + 2;
|
||||
if (test == tests.size()) begin
|
||||
if (totalerrors == 0) $display("SUCCESS! All tests ran without failures.");
|
||||
else $display("FAIL: %d test programs had errors", totalerrors);
|
||||
$stop;
|
||||
end
|
||||
else begin
|
||||
memfilename = {"../imperas-riscv-tests/work/", tests[test], ".elf.memfile"};
|
||||
$readmemh(memfilename, dut.imem.RAM);
|
||||
$readmemh(memfilename, dut.dmem.dtim.RAM);
|
||||
$display("Read memfile %s", memfilename);
|
||||
reset = 1; # 17; reset = 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
/* verilator lint_on STMTDLY */
|
||||
/* verilator lint_on WIDTH */
|
||||
|
||||
module instrTrackerTB #(parameter XLEN=32) (
|
||||
input logic clk, reset, FlushE,
|
||||
input logic [31:0] InstrD,
|
||||
input logic [31:0] InstrE, InstrM,
|
||||
output logic [31:0] InstrW,
|
||||
output string InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
||||
// stage Instr to Writeback for visualization
|
||||
flopr #(32) InstrWReg(clk, reset, InstrM, InstrW);
|
||||
|
||||
instrNameDecTB ddec(InstrD, InstrDName);
|
||||
instrNameDecTB edec(InstrE, InstrEName);
|
||||
instrNameDecTB mdec(InstrM, InstrMName);
|
||||
instrNameDecTB wdec(InstrW, InstrWName);
|
||||
endmodule
|
||||
|
||||
// decode the instruction name, to help the test bench
|
||||
module instrNameDecTB(
|
||||
input logic [31:0] instr,
|
||||
output string name);
|
||||
|
||||
logic [6:0] op;
|
||||
logic [2:0] funct3;
|
||||
logic [6:0] funct7;
|
||||
logic [11:0] imm;
|
||||
|
||||
assign op = instr[6:0];
|
||||
assign funct3 = instr[14:12];
|
||||
assign funct7 = instr[31:25];
|
||||
assign imm = instr[31:20];
|
||||
|
||||
// it would be nice to add the operands to the name
|
||||
// create another variable called decoded
|
||||
|
||||
always_comb
|
||||
casez({op, funct3})
|
||||
10'b0000000_000: name = "BAD";
|
||||
10'b0000011_000: name = "LB";
|
||||
10'b0000011_001: name = "LH";
|
||||
10'b0000011_010: name = "LW";
|
||||
10'b0000011_011: name = "LD";
|
||||
10'b0000011_100: name = "LBU";
|
||||
10'b0000011_101: name = "LHU";
|
||||
10'b0000011_110: name = "LWU";
|
||||
10'b0010011_000: if (instr[31:15] == 0 && instr[11:7] ==0) name = "NOP/FLUSH";
|
||||
else name = "ADDI";
|
||||
10'b0010011_001: if (funct7[6:1] == 6'b000000) name = "SLLI";
|
||||
else name = "ILLEGAL";
|
||||
10'b0010011_010: name = "SLTI";
|
||||
10'b0010011_011: name = "SLTIU";
|
||||
10'b0010011_100: name = "XORI";
|
||||
10'b0010011_101: if (funct7[6:1] == 6'b000000) name = "SRLI";
|
||||
else if (funct7[6:1] == 6'b010000) name = "SRAI";
|
||||
else name = "ILLEGAL";
|
||||
10'b0010011_110: name = "ORI";
|
||||
10'b0010011_111: name = "ANDI";
|
||||
10'b0010111_???: name = "AUIPC";
|
||||
10'b0100011_000: name = "SB";
|
||||
10'b0100011_001: name = "SH";
|
||||
10'b0100011_010: name = "SW";
|
||||
10'b0100011_011: name = "SD";
|
||||
10'b0011011_000: name = "ADDIW";
|
||||
10'b0011011_001: name = "SLLIW";
|
||||
10'b0011011_101: if (funct7 == 7'b0000000) name = "SRLIW";
|
||||
else if (funct7 == 7'b0100000) name = "SRAIW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0111011_000: if (funct7 == 7'b0000000) name = "ADDW";
|
||||
else if (funct7 == 7'b0100000) name = "SUBW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0111011_001: name = "SLLW";
|
||||
10'b0111011_101: if (funct7 == 7'b0000000) name = "SRLW";
|
||||
else if (funct7 == 7'b0100000) name = "SRAW";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_000: if (funct7 == 7'b0000000) name = "ADD";
|
||||
else if (funct7 == 7'b0000001) name = "MUL";
|
||||
else if (funct7 == 7'b0100000) name = "SUB";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_001: if (funct7 == 7'b0000000) name = "SLL";
|
||||
else if (funct7 == 7'b0000001) name = "MULH";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_010: if (funct7 == 7'b0000000) name = "SLT";
|
||||
else if (funct7 == 7'b0000001) name = "MULHSU";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_011: if (funct7 == 7'b0000000) name = "SLTU";
|
||||
else if (funct7 == 7'b0000001) name = "DIV";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_100: if (funct7 == 7'b0000000) name = "XOR";
|
||||
else if (funct7 == 7'b0000001) name = "MUL";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_101: if (funct7 == 7'b0000000) name = "SRL";
|
||||
else if (funct7 == 7'b0000001) name = "DIVU";
|
||||
else if (funct7 == 7'b0100000) name = "SRA";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_110: if (funct7 == 7'b0000000) name = "OR";
|
||||
else if (funct7 == 7'b0000001) name = "REM";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110011_111: if (funct7 == 7'b0000000) name = "AND";
|
||||
else if (funct7 == 7'b0000001) name = "REMU";
|
||||
else name = "ILLEGAL";
|
||||
10'b0110111_???: name = "LUI";
|
||||
10'b1100011_000: name = "BEQ";
|
||||
10'b1100011_001: name = "BNE";
|
||||
10'b1100011_100: name = "BLT";
|
||||
10'b1100011_101: name = "BGE";
|
||||
10'b1100011_110: name = "BLTU";
|
||||
10'b1100011_111: name = "BGEU";
|
||||
10'b1100111_000: name = "JALR";
|
||||
10'b1101111_???: name = "JAL";
|
||||
10'b1110011_000: if (imm == 0) name = "ECALL";
|
||||
else if (imm == 1) name = "EBREAK";
|
||||
else if (imm == 2) name = "URET";
|
||||
else if (imm == 258) name = "SRET";
|
||||
else if (imm == 770) name = "MRET";
|
||||
else name = "ILLEGAL";
|
||||
10'b1110011_001: name = "CSRRW";
|
||||
10'b1110011_010: name = "CSRRS";
|
||||
10'b1110011_011: name = "CSRRC";
|
||||
10'b1110011_101: name = "CSRRWI";
|
||||
10'b1110011_110: name = "CSRRSI";
|
||||
10'b1110011_111: name = "CSRRCI";
|
||||
10'b0001111_???: name = "FENCE";
|
||||
default: name = "ILLEGAL";
|
||||
endcase
|
||||
endmodule
|
117
wally-pipelined/src/trap.sv
Normal file
117
wally-pipelined/src/trap.sv
Normal file
@ -0,0 +1,117 @@
|
||||
///////////////////////////////////////////
|
||||
// trap.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Handle Traps: Exceptions and Interrupt
|
||||
// See RISC-V Privileged Mode Specification 20190608 3.1.10-11
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module trap #(parameter XLEN=32, MISA=0) (
|
||||
input logic clk, reset,
|
||||
input logic InstrMisalignedFaultM, InstrAccessFaultM, IllegalInstrFaultM,
|
||||
input logic BreakpointFaultM, LoadMisalignedFaultM, StoreMisalignedFaultM,
|
||||
input logic LoadAccessFaultM, StoreAccessFaultM, EcallFaultM, InstrPageFaultM,
|
||||
input logic LoadPageFaultM, StorePageFaultM,
|
||||
input logic mretM, sretM, uretM,
|
||||
input logic [1:0] PrivilegeModeW, NextPrivilegeModeM,
|
||||
input logic [XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW,
|
||||
input logic [11:0] MIP_REGW, MIE_REGW,
|
||||
input logic STATUS_MIE, STATUS_SIE,
|
||||
input logic [XLEN-1:0] InstrMisalignedAdrM, ALUResultM,
|
||||
input logic [31:0] InstrM,
|
||||
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
|
||||
output logic [XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
|
||||
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
|
||||
// input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
|
||||
);
|
||||
|
||||
logic [11:0] MIntGlobalEnM, SIntGlobalEnM, PendingIntsM;
|
||||
logic InterruptM;
|
||||
|
||||
// Determine pending enabled interrupts
|
||||
assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) || STATUS_MIE; // if M ints enabled or lower priv 3.1.9
|
||||
assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) || STATUS_SIE; // if S ints enabled or lower priv 3.1.9
|
||||
assign PendingIntsM = (MIP_REGW & MIE_REGW) & ((MIntGlobalEnM & 12'h888) | (SIntGlobalEnM & 12'h222));
|
||||
assign InterruptM = |PendingIntsM; // interrupt if any sources are pending
|
||||
|
||||
// Trigger Traps and RET
|
||||
assign TrapM = InstrMisalignedFaultM | InstrAccessFaultM | IllegalInstrFaultM |
|
||||
BreakpointFaultM | LoadMisalignedFaultM | StoreMisalignedFaultM |
|
||||
LoadAccessFaultM | StoreAccessFaultM | EcallFaultM | InstrPageFaultM |
|
||||
LoadPageFaultM | StorePageFaultM | InterruptM;
|
||||
assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE);
|
||||
assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED;
|
||||
assign UTrapM = TrapM & (NextPrivilegeModeM == `U_MODE) & `N_SUPPORTED;
|
||||
assign RetM = mretM | sretM | uretM;
|
||||
|
||||
always_comb
|
||||
if (mretM) PrivilegedNextPCM = MEPC_REGW;
|
||||
else if (sretM) PrivilegedNextPCM = SEPC_REGW;
|
||||
else if (uretM) PrivilegedNextPCM = UEPC_REGW;
|
||||
else if (NextPrivilegeModeM == `U_MODE) PrivilegedNextPCM = UTVEC_REGW;
|
||||
else if (NextPrivilegeModeM == `S_MODE) PrivilegedNextPCM = STVEC_REGW;
|
||||
else PrivilegedNextPCM = MTVEC_REGW;
|
||||
|
||||
// Cause priority defined in table 3.7 of 20190608 privileged spec
|
||||
// Exceptions are of lower priority than all interrupts (3.1.9)
|
||||
always_comb
|
||||
if (reset) CauseM = 0; // hard reset 3.3
|
||||
else if (PendingIntsM[11]) CauseM = (1 << (XLEN-1)) + 11; // Machine External Int
|
||||
else if (PendingIntsM[3]) CauseM = (1 << (XLEN-1)) + 3; // Machine Sw Int
|
||||
else if (PendingIntsM[7]) CauseM = (1 << (XLEN-1)) + 7; // Machine Timer Int
|
||||
else if (PendingIntsM[9]) CauseM = (1 << (XLEN-1)) + 9; // Supervisor External Int
|
||||
else if (PendingIntsM[1]) CauseM = (1 << (XLEN-1)) + 1; // Supervisor Sw Int
|
||||
else if (PendingIntsM[5]) CauseM = (1 << (XLEN-1)) + 5; // Supervisor Timer Int
|
||||
else if (InstrPageFaultM) CauseM = 12;
|
||||
else if (InstrAccessFaultM) CauseM = 1;
|
||||
else if (InstrMisalignedFaultM) CauseM = 0;
|
||||
else if (IllegalInstrFaultM) CauseM = 2;
|
||||
else if (BreakpointFaultM) CauseM = 3;
|
||||
else if (EcallFaultM) CauseM = {{(XLEN-2){1'b0}}, PrivilegeModeW} + 8;
|
||||
else if (LoadMisalignedFaultM) CauseM = 4;
|
||||
else if (StoreMisalignedFaultM) CauseM = 6;
|
||||
else if (LoadPageFaultM) CauseM = 13;
|
||||
else if (StorePageFaultM) CauseM = 15;
|
||||
else if (LoadAccessFaultM) CauseM = 5;
|
||||
else if (StoreAccessFaultM) CauseM = 7;
|
||||
else CauseM = 0;
|
||||
|
||||
// MTVAL
|
||||
// 3.1.17: on instruction fetch, load, or store address misaligned access or page fault
|
||||
// mtval is written with the faulting virtual address.
|
||||
// On illegal instruction trap, mtval may be written with faulting instruction
|
||||
// For other traps (including interrupts), mtval is set to 0
|
||||
// *** hardware breakpoint is supposed to write faulting virtual address per priv p. 38
|
||||
// *** Page faults not yet implemented
|
||||
// Technically
|
||||
|
||||
always_comb
|
||||
if (InstrMisalignedFaultM) NextFaultMtvalM = InstrMisalignedAdrM;
|
||||
else if (LoadMisalignedFaultM) NextFaultMtvalM = ALUResultM;
|
||||
else if (StoreMisalignedFaultM) NextFaultMtvalM = ALUResultM;
|
||||
else if (InstrPageFaultM) NextFaultMtvalM = 0; // *** implement
|
||||
else if (LoadPageFaultM) NextFaultMtvalM = ALUResultM;
|
||||
else if (StorePageFaultM) NextFaultMtvalM = ALUResultM;
|
||||
else if (IllegalInstrFaultM) NextFaultMtvalM = {{(XLEN-32){1'b0}}, InstrM};
|
||||
else NextFaultMtvalM = 0;
|
||||
endmodule
|
24
wally-pipelined/src/wally-macros.sv
Normal file
24
wally-pipelined/src/wally-macros.sv
Normal file
@ -0,0 +1,24 @@
|
||||
// wally-macros.sv
|
||||
// David_Harris@hmc.edu 5 January 2021
|
||||
|
||||
// Macros to determine which mode is supported based on MISA
|
||||
|
||||
`define A_SUPPORTED ((MISA >> 0) % 2 == 1)
|
||||
`define C_SUPPORTED ((MISA >> 2) % 2 == 1)
|
||||
`define D_SUPPORTED ((MISA >> 3) % 2 == 1)
|
||||
`define F_SUPPORTED ((MISA >> 5) % 2 == 1)
|
||||
`define M_SUPPORTED ((MISA >> 12) % 2 == 1)
|
||||
`define S_SUPPORTED ((MISA >> 18) % 2 == 1)
|
||||
`define U_SUPPORTED ((MISA >> 20) % 2 == 1)
|
||||
`define ZCSR_SUPPORTED (ZCSR != 0)
|
||||
`define ZCOUNTERS_SUPPORTED (ZCOUNTERS != 0)
|
||||
// N-mode user-level interrupts are depricated per Andrew Waterman 1/13/21
|
||||
//`define N_SUPPORTED ((MISA >> 13) % 2 == 1)
|
||||
`define N_SUPPORTED 0
|
||||
|
||||
`define M_MODE (2'b11)
|
||||
`define S_MODE (2'b01)
|
||||
`define U_MODE (2'b00)
|
||||
|
||||
/* verilator lint_off STMTDLY */
|
||||
/* verilator lint_off WIDTH */
|
75
wally-pipelined/src/wallypipelined.sv
Normal file
75
wally-pipelined/src/wallypipelined.sv
Normal file
@ -0,0 +1,75 @@
|
||||
///////////////////////////////////////////
|
||||
// wally-pipelined.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 6 November 2020
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Top level module for pipelined processor and memories
|
||||
// Full RV32/64IC instruction set
|
||||
//
|
||||
// To Do:
|
||||
// Sort out terminology of faults, traps, interrputs, exceptions
|
||||
// Long names for instruction decoder
|
||||
// *Consitency in capitalizaiton
|
||||
// *Divide into many files
|
||||
// *Keep lint clean
|
||||
// *Put in git repo
|
||||
// Sort out memory map
|
||||
// *Automate testing based on MISA
|
||||
// Drop Funct3 from Controller pipeline if not needed
|
||||
// Finish exceptions & test
|
||||
// *Flushes caused by exceptions
|
||||
// Generate statements to reduce hardware for unneeded exception logic
|
||||
// *RET
|
||||
// *Status register
|
||||
// Misaligned instruction faults on other aults
|
||||
//
|
||||
//
|
||||
// Note: the CSRs do not support the following features
|
||||
//- Disabling portions of the instruction set with bits of the MISA register
|
||||
//- Changing from RV64 to RV32 by writing the SXL/UXL bits of the STATUS register
|
||||
// As of January 2020, virtual memory is not yet supported
|
||||
//
|
||||
// Reference MISA Values:
|
||||
// 104: C compressed
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module wallypipelined #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
input logic clk, reset,
|
||||
output logic [XLEN-1:0] WriteDataM, DataAdrM,
|
||||
output logic [1:0] MemRWM);
|
||||
|
||||
logic [XLEN-1:0] PCF, ReadDataM;
|
||||
logic [31:0] InstrF;
|
||||
logic [7:0] ByteMaskM;
|
||||
logic InstrAccessFaultF, DataAccessFaultM;
|
||||
logic TimerIntM, SwIntM; // from CLINT
|
||||
logic ExtIntM = 0; // not yet connected
|
||||
|
||||
// instantiate processor and memories
|
||||
wallypipelinedhart #(XLEN, MISA, ZCSR, ZCOUNTERS) hart(
|
||||
clk, reset, PCF, InstrF, MemRWM, ByteMaskM, DataAdrM,
|
||||
WriteDataM, ReadDataM, TimerIntM, ExtIntM, SwIntM, InstrAccessFaultF, DataAccessFaultM);
|
||||
|
||||
imem #(XLEN) imem(PCF, InstrF, InstrAccessFaultF);
|
||||
dmem #(XLEN) dmem(clk, reset, MemRWM, ByteMaskM, DataAdrM, WriteDataM, ReadDataM,
|
||||
DataAccessFaultM, TimerIntM, SwIntM);
|
||||
endmodule
|
100
wally-pipelined/src/wallypipelinedhart.sv
Normal file
100
wally-pipelined/src/wallypipelinedhart.sv
Normal file
@ -0,0 +1,100 @@
|
||||
///////////////////////////////////////////
|
||||
// wallypipelinedhart.sv
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 9 January 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: Pipelined RISC-V Processor
|
||||
//
|
||||
// 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-macros.sv"
|
||||
|
||||
module wallypipelinedhart #(parameter XLEN=32, MISA=0, ZCSR = 1, ZCOUNTERS = 1) (
|
||||
input logic clk, reset,
|
||||
output logic [XLEN-1:0] PCF,
|
||||
input logic [31:0] InstrF,
|
||||
output logic [1:0] MemRWM,
|
||||
output logic [7:0] ByteMaskM,
|
||||
output logic [XLEN-1:0] ALUResultM, WriteDataM,
|
||||
input logic [XLEN-1:0] ReadDataM,
|
||||
input logic TimerIntM, ExtIntM, SwIntM,
|
||||
input logic InstrAccessFaultF,
|
||||
input logic DataAccessFaultM);
|
||||
|
||||
logic [6:0] opD;
|
||||
logic [2:0] funct3D;
|
||||
logic funct7b5D;
|
||||
logic [2:0] ImmSrcD;
|
||||
logic IllegalCompInstrD;
|
||||
logic [2:0] FlagsE;
|
||||
logic PCSrcE;
|
||||
logic [4:0] ALUControlE;
|
||||
logic ALUSrcAE, ALUSrcBE;
|
||||
logic MemReadE;
|
||||
logic RegWriteM;
|
||||
logic CSRWriteM;
|
||||
logic PrivilegedM;
|
||||
logic IllegalInstrFaultM;
|
||||
logic InstrAccessFaultM;
|
||||
logic [2:0] Funct3M;
|
||||
logic [1:0] ResultSrcW;
|
||||
logic RegWriteW;
|
||||
logic InstrValidW, LoadStallD;
|
||||
logic CSRWritePendingDEM;
|
||||
logic InstrMisalignedFaultM;
|
||||
|
||||
logic [1:0] ForwardAE, ForwardBE;
|
||||
logic StallF, StallD, FlushD, FlushE, FlushM, FlushW;
|
||||
logic PrivilegedChangePCM, TrapM;
|
||||
|
||||
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW;
|
||||
logic TargetSrcE;
|
||||
logic [4:0] SetFflagsM;
|
||||
logic [2:0] FRM_REGW;
|
||||
logic FloatRegWriteW;
|
||||
|
||||
controller c(clk, reset,
|
||||
opD, funct3D, funct7b5D, ImmSrcD,
|
||||
StallD, FlushD, IllegalCompInstrD,
|
||||
FlushE, FlagsE, PCSrcE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, MemReadE,
|
||||
FlushM, MemRWM, CSRWriteM, PrivilegedM, IllegalInstrFaultM, Funct3M, RegWriteM,
|
||||
FlushW, RegWriteW, ResultSrcW, InstrValidW, CSRWritePendingDEM,
|
||||
InstrAccessFaultF, InstrAccessFaultM);
|
||||
|
||||
datapath #(XLEN, MISA, ZCSR, ZCOUNTERS)
|
||||
dp(clk, reset,
|
||||
StallF, PCF, InstrF,
|
||||
opD, funct3D, funct7b5D, StallD, FlushD, ImmSrcD, LoadStallD, IllegalCompInstrD,
|
||||
FlushE, ForwardAE, ForwardBE, PCSrcE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, FlagsE,
|
||||
FlushM, MemRWM, CSRWriteM, PrivilegedM, InstrAccessFaultM, IllegalInstrFaultM,
|
||||
TimerIntM, ExtIntM, SwIntM, InstrMisalignedFaultM,
|
||||
Funct3M, WriteDataM, ALUResultM, ReadDataM, ByteMaskM, PrivilegedChangePCM, TrapM,
|
||||
SetFflagsM, DataAccessFaultM,
|
||||
FlushW, RegWriteW, ResultSrcW, InstrValidW, FloatRegWriteW, FRM_REGW,
|
||||
Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW);
|
||||
|
||||
// add FPU here, with SetFflagsM, FRM_REGW
|
||||
// presently stub out SetFlagsM and FloatRegWriteW
|
||||
assign SetFflagsM = 0;
|
||||
assign FloatRegWriteW = 0;
|
||||
|
||||
hazard hz(Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
|
||||
PCSrcE, MemReadE, RegWriteM, RegWriteW, CSRWritePendingDEM, PrivilegedChangePCM, TrapM,
|
||||
ForwardAE, ForwardBE, StallF, StallD, FlushD, FlushE, FlushM, FlushW, LoadStallD);
|
||||
endmodule
|
38
wally-pipelined/wally-pipelined-batch.do
Normal file
38
wally-pipelined/wally-pipelined-batch.do
Normal file
@ -0,0 +1,38 @@
|
||||
# wally-pipelined-batch.do
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with Testbench
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
# 11 seconds to run batch mode
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-pipelined.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work] {
|
||||
vdel -all
|
||||
}
|
||||
vlib work
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
vlog src/*.sv -suppress 2583
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
run -all
|
||||
quit
|
91
wally-pipelined/wally-pipelined.do
Normal file
91
wally-pipelined/wally-pipelined.do
Normal file
@ -0,0 +1,91 @@
|
||||
# wally-pipelined.do
|
||||
#
|
||||
# Modification by Oklahoma State University & Harvey Mudd College
|
||||
# Use with Testbench
|
||||
# James Stine, 2008; David Harris 2021
|
||||
# Go Cowboys!!!!!!
|
||||
#
|
||||
# Takes 1:10 to run RV64IC tests using gui
|
||||
|
||||
# Use this wally-pipelined.do file to run this example.
|
||||
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
|
||||
# do wally-pipelined.do
|
||||
# or, to run from a shell, type the following at the shell prompt:
|
||||
# vsim -do wally-pipelined.do -c
|
||||
# (omit the "-c" to see the GUI while running from the shell)
|
||||
|
||||
onbreak {resume}
|
||||
|
||||
# create library
|
||||
if [file exists work] {
|
||||
vdel -all
|
||||
}
|
||||
vlib work
|
||||
|
||||
# compile source files
|
||||
# suppress spurious warnngs about
|
||||
# "Extra checking for conflicts with always_comb done at vopt time"
|
||||
# because vsim will run vopt
|
||||
vlog src/*.sv -suppress 2583
|
||||
|
||||
# start and run simulation
|
||||
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
|
||||
vopt +acc work.testbench -o workopt
|
||||
vsim workopt
|
||||
|
||||
view wave
|
||||
|
||||
-- display input and output signals as hexidecimal values
|
||||
# Diplays All Signals recursively
|
||||
add wave /testbench/clk
|
||||
add wave /testbench/reset
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/dp/PCF
|
||||
add wave -hex /testbench/dut/hart/dp/InstrF
|
||||
add wave /testbench/InstrFName
|
||||
#add wave -hex /testbench/dut/hart/dp/PCD
|
||||
add wave -hex /testbench/dut/hart/dp/InstrD
|
||||
add wave /testbench/InstrDName
|
||||
add wave -divider
|
||||
#add wave -hex /testbench/dut/hart/dp/PCE
|
||||
#add wave -hex /testbench/dut/hart/dp/InstrE
|
||||
add wave /testbench/InstrEName
|
||||
add wave -hex /testbench/dut/hart/dp/SrcAE
|
||||
add wave -hex /testbench/dut/hart/dp/SrcBE
|
||||
add wave -hex /testbench/dut/hart/dp/ALUResultE
|
||||
add wave /testbench/dut/hart/dp/PCSrcE
|
||||
add wave -divider
|
||||
#add wave -hex /testbench/dut/hart/dp/PCM
|
||||
#add wave -hex /testbench/dut/hart/dp/InstrM
|
||||
add wave /testbench/InstrMName
|
||||
add wave /testbench/dut/dmem/dtim/memwrite
|
||||
add wave -hex /testbench/dut/dmem/AdrM
|
||||
add wave -hex /testbench/dut/dmem/WdM
|
||||
add wave -divider
|
||||
add wave -hex /testbench/dut/hart/dp/PCW
|
||||
#add wave -hex /testbench/dut/hart/dp/InstrW
|
||||
add wave /testbench/InstrWName
|
||||
add wave /testbench/dut/hart/dp/RegWriteW
|
||||
add wave -hex /testbench/dut/hart/dp/ResultW
|
||||
add wave -hex /testbench/dut/hart/dp/RdW
|
||||
add wave -divider
|
||||
#add ww
|
||||
add wave -hex -r /testbench/*
|
||||
|
||||
-- Set Wave Output Items
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreZoom {0 ps} {100 ps}
|
||||
configure wave -namecolwidth 250
|
||||
configure wave -valuecolwidth 120
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 0
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
set DefaultRadix hexadecimal
|
||||
|
||||
-- Run the Simulation
|
||||
#run 1000
|
||||
run -all
|
||||
#quit
|
13
wally-pipelined/wally.old
Normal file
13
wally-pipelined/wally.old
Normal file
@ -0,0 +1,13 @@
|
||||
// riscvfullpipelined.sv
|
||||
|
||||
|
||||
|
||||
`include "wally-macros.sv"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user