Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2022-03-30 17:28:30 -05:00
commit 07eba7df45
33 changed files with 459 additions and 321 deletions

@ -1 +1 @@
Subproject commit 261a65e0a2d3e8d62d81b1d8fe7e309a096bc6a9 Subproject commit 2d2aaa7b85c60219c591555b647dfa1785ffe1b3

@ -1 +1 @@
Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 Subproject commit effd553a6a91ed9b0ba251796a8a44505a45174f

@ -1 +1 @@
Subproject commit a7e27bc046405f0dbcde091be99f5a5d564e2172 Subproject commit cb4295f9ce5da2881d7746015a6105adb8f09071

@ -1 +1 @@
Subproject commit cf04274f50621fd9ef9147793cca6dd1657985c7 Subproject commit 3e2bf06b071a77ae62c09bf07c5229d1f9397d94

View File

@ -1,4 +1,5 @@
for index in {450..500} #!/bin/bash
for index in {450..500};
do do
instrs=$(($index*1000000)) instrs=$(($index*1000000))
echo "y" | nice -n 5 ./genCheckpoint.sh $instrs echo "y" | nice -n 5 ./genCheckpoint.sh $instrs

View File

@ -70,7 +70,7 @@ for test in tests64gc:
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!", cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!",
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a", "imperas32c", "wally32priv"] #, "imperas32mmu""wally32i", tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32m", "wally32a", "imperas32c"] #, "imperas32mmu""wally32i",
for test in tests32gc: for test in tests32gc:
tc = TestCase( tc = TestCase(
name=test, name=test,
@ -79,6 +79,25 @@ for test in tests32gc:
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
tests64ia = ["wally64priv"]
for test in tests64ia:
tc = TestCase(
name=test,
variant="rv64ia",
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64ia "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32ia = ["wally32priv"]
for test in tests32ia:
tc = TestCase(
name=test,
variant="rv32ia",
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv32ia "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c"] tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c"]
for test in tests32ic: for test in tests32ic:
tc = TestCase( tc = TestCase(

View File

@ -47,7 +47,8 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) (
always_ff @(posedge clk) AdrD <= Adr; always_ff @(posedge clk) AdrD <= Adr;
genvar index; integer index;
/* -----\/----- EXCLUDED -----\/-----
for(index = 0; index < WIDTH/8; index++) begin for(index = 0; index < WIDTH/8; index++) begin
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (WriteEnable & ByteMask[index]) begin if (WriteEnable & ByteMask[index]) begin
@ -55,6 +56,18 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) (
end end
end end
end end
-----/\----- EXCLUDED -----/\----- */
always_ff @(posedge clk) begin
if (WriteEnable) begin
for(index = 0; index < WIDTH/8; index++) begin
if(ByteMask[index]) begin
StoredData[Adr][index*8 +: 8] <= #1 CacheWriteData[index*8 +: 8];
end
end
end
end
// if not a multiple of 8, MSByte is not 8 bits long. // if not a multiple of 8, MSByte is not 8 bits long.
if(WIDTH%8 != 0) begin if(WIDTH%8 != 0) begin
always_ff @(posedge clk) begin always_ff @(posedge clk) begin

View File

@ -23,40 +23,32 @@ module fcmp (
output logic [`FLEN-1:0] CmpResE // compare resilt output logic [`FLEN-1:0] CmpResE // compare resilt
); );
logic LT, EQ; // is X < or > or = Y logic LTabs, LT, EQ; // is X < or > or = Y
logic BothZeroE, EitherNaNE, EitherSNaNE;
// X is less than Y:
// Signs: assign LTabs= {1'b0, XExpE, XManE} < {1'b0, YExpE, YManE}; // unsigned comparison, treating FP as integers
// X Y answer assign LT = (XSgnE & ~YSgnE) | (XSgnE & YSgnE & ~LTabs & ~EQ) | (~XSgnE & ~YSgnE & LTabs);
// pos pos idk - keep checking //assign LT = $signed({XSgnE, XExpE, XManE[`NF-1:0]}) < $signed({YSgnE, YExpE, YManE[`NF-1:0]});
// pos neg no //assign LT = XInt < YInt;
// neg pos yes // assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
// neg neg idk - keep checking
// Exponent
// - if XExp < YExp
// - if negitive - no
// - if positive - yes
// - otherwise keep checking
// Mantissa
// - XMan < YMan then
// - if negitive - no
// - if positive - yes
// note: LT does -0 < 0
//*** compare Exp and Man together
assign LT = XSgnE^YSgnE ? XSgnE : XExpE==YExpE ? ((XManE<YManE)^XSgnE)&~EQ : (XExpE<YExpE)^XSgnE;
assign EQ = (FSrcXE == FSrcYE); assign EQ = (FSrcXE == FSrcYE);
assign BothZeroE = XZeroE&YZeroE;
assign EitherNaNE = XNaNE|YNaNE;
assign EitherSNaNE = XSNaNE|YSNaNE;
// flags // flags
// Min/Max - if an input is a signaling NaN set invalid flag // Min/Max - if an input is a signaling NaN set invalid flag
// LT/LE - signaling - sets invalid if NaN input // LT/LE - signaling - sets invalid if NaN input
// EQ - quiet - sets invalid if signaling NaN input // EQ - quiet - sets invalid if signaling NaN input
always_comb begin always_comb begin
case (FOpCtrlE[2:0]) case (FOpCtrlE[2:0])
3'b111: CmpNVE = XSNaNE|YSNaNE;//min 3'b111: CmpNVE = EitherSNaNE;//min
3'b101: CmpNVE = XSNaNE|YSNaNE;//max 3'b101: CmpNVE = EitherSNaNE;//max
3'b010: CmpNVE = XSNaNE|YSNaNE;//equal 3'b010: CmpNVE = EitherSNaNE;//equal
3'b001: CmpNVE = XNaNE|YNaNE;//less than 3'b001: CmpNVE = EitherNaNE;//less than
3'b011: CmpNVE = XNaNE|YNaNE;//less than or equal 3'b011: CmpNVE = EitherNaNE;//less than or equal
default: CmpNVE = 1'b0; default: CmpNVE = 1'b0;
endcase endcase
end end
@ -71,24 +63,22 @@ module fcmp (
// - inf = inf and -inf = -inf // - inf = inf and -inf = -inf
// - return 0 if comparison with NaN (unordered) // - return 0 if comparison with NaN (unordered)
logic [`FLEN-1:0] QNaNX, QNaNY; logic [`FLEN-1:0] QNaN;
if(`IEEE754) begin // fmin/fmax of two NaNs returns a quiet NaN of the appropriate size
assign QNaNX = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]}; // for IEEE, return the payload of X
assign QNaNY = FmtE ? {YSgnE, YExpE, 1'b1, YManE[`NF-2:0]} : {{32{1'b1}}, YSgnE, YExpE[7:0], 1'b1, YManE[50:29]}; // for RISC-V, return the canonical NaN
end else begin if(`IEEE754) assign QNaN = FmtE ? {XSgnE, XExpE, 1'b1, XManE[`NF-2:0]} : {{32{1'b1}}, XSgnE, XExpE[7:0], 1'b1, XManE[50:29]};
assign QNaNX = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0}; else assign QNaN = FmtE ? {1'b0, XExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpE[7:0], 1'b1, 22'b0};
assign QNaNY = FmtE ? {1'b0, YExpE, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpE[7:0], 1'b1, 22'b0};
end
always_comb begin always_comb begin
case (FOpCtrlE[2:0]) case (FOpCtrlE[2:0])
3'b111: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Min 3'b111: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Min
: YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE; : YNaNE ? FSrcXE : LT ? FSrcXE : FSrcYE;
3'b101: CmpResE = XNaNE ? YNaNE ? QNaNX : FSrcYE // Max 3'b101: CmpResE = XNaNE ? YNaNE ? QNaN : FSrcYE // Max
: YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE; : YNaNE ? FSrcXE : LT ? FSrcYE : FSrcXE;
3'b010: CmpResE = {63'b0, (EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Equal 3'b010: CmpResE = {63'b0, (EQ|BothZeroE) & ~EitherNaNE}; // Equal
3'b001: CmpResE = {63'b0, LT&~(XZeroE&YZeroE)&~(XNaNE|YNaNE)}; // Less than 3'b001: CmpResE = {63'b0, LT & ~BothZeroE & ~EitherNaNE}; // Less than
3'b011: CmpResE = {63'b0, (LT|EQ|(XZeroE&YZeroE))&~(XNaNE|YNaNE)}; // Less than or equal 3'b011: CmpResE = {63'b0, (LT|EQ|BothZeroE) & ~EitherNaNE}; // Less than or equal
default: CmpResE = 64'b0; default: CmpResE = 64'b0;
endcase endcase
end end

View File

@ -0,0 +1,71 @@
///////////////////////////////////////////
// block ram model should be equivalent to srsam.
//
// Written: Ross Thompson
// March 29, 2022
// Modified: Based on UG901 vivado documentation.
//
// Purpose: On-chip SIMPLERAM, external to core
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////
// This model actually works correctly with vivado.
`include "wally-config.vh"
module bram1p1rw
#(
//--------------------------------------------------------------------------
parameter NUM_COL = 8,
parameter COL_WIDTH = 8,
parameter ADDR_WIDTH = 10,
// Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth
parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits
//----------------------------------------------------------------------
) (
input logic clk,
input logic ena,
input logic [NUM_COL-1:0] we,
input logic [ADDR_WIDTH-1:0] addr,
output logic [DATA_WIDTH-1:0] dout,
input logic [DATA_WIDTH-1:0] din
);
// Core Memory
logic [DATA_WIDTH-1:0] RAM [(2**ADDR_WIDTH)-1:0];
integer i;
initial begin
$readmemh("big64.txt", RAM);
end
always @ (posedge clk) begin
dout <= RAM[addr];
if(ena) begin
for(i=0;i<NUM_COL;i=i+1) begin
if(we[i]) begin
RAM[addr][i*COL_WIDTH +: COL_WIDTH] <= din[i*COL_WIDTH +:COL_WIDTH];
end
end
end
end
endmodule // bytewrite_tdp_ram_rf

View File

@ -0,0 +1,82 @@
///////////////////////////////////////////
// block ram model should be equivalent to srsam.
//
// Written: Ross Thompson
// March 29, 2022
// Modified: Based on UG901 vivado documentation.
//
// Purpose: On-chip SIMPLERAM, external to core
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// 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.
////////////////////////////////////////////////////////////////////////////////////////////////
// This model actually works correctly with vivado.
`include "wally-config.vh"
module bram2p1r1w
#(
//--------------------------------------------------------------------------
parameter NUM_COL = 8,
parameter COL_WIDTH = 8,
parameter ADDR_WIDTH = 10,
parameter PRELOAD_ENABLED = 0,
parameter PRELOAD_FILE = "bootrom.txt",
// Addr Width in bits : 2 *ADDR_WIDTH = RAM Depth
parameter DATA_WIDTH = NUM_COL*COL_WIDTH // Data Width in bits
//----------------------------------------------------------------------
) (
input logic clk,
input logic enaA,
input logic [ADDR_WIDTH-1:0] addrA,
output logic [DATA_WIDTH-1:0] doutA,
input logic enaB,
input logic [NUM_COL-1:0] weB,
input logic [ADDR_WIDTH-1:0] addrB,
input logic [DATA_WIDTH-1:0] dinB
);
// Core Memory
logic [DATA_WIDTH-1:0] RAM [(2**ADDR_WIDTH)-1:0];
integer i;
initial begin
if(PRELOAD_ENABLED)
$readmemh(PRELOAD_FILE, RAM);
end
// Port-A Operation
always @ (posedge clk) begin
if(enaA) begin
doutA <= RAM[addrA];
end
end
// Port-B Operation:
always @ (posedge clk) begin
if(enaB) begin
for(i=0;i<NUM_COL;i=i+1) begin
if(weB[i]) begin
RAM[addrB][i*COL_WIDTH +: COL_WIDTH] <= dinB[i*COL_WIDTH +:COL_WIDTH];
end
end
end
end
endmodule // bytewrite_tdp_ram_rf

View File

@ -39,6 +39,14 @@ module simpleram #(parameter BASE=0, RANGE = 65535) (
output logic [`XLEN-1:0] rd output logic [`XLEN-1:0] rd
); );
localparam ADDR_WDITH = $clog2(RANGE/8);
localparam OFFSET = $clog2(`XLEN/8);
bram1p1rw #(`XLEN/8, 8, ADDR_WDITH)
memory(.clk, .ena(we), .we(ByteMask), .addr(a[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(rd), .din(wd));
/* -----\/----- EXCLUDED -----\/-----
logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)];
// discard bottom 2 or 3 bits of address offset within word or doubleword // discard bottom 2 or 3 bits of address offset within word or doubleword
@ -55,5 +63,6 @@ module simpleram #(parameter BASE=0, RANGE = 65535) (
if (we & ByteMask[index]) RAM[adrmsbs][8*(index+1)-1:8*index] <= #1 wd[8*(index+1)-1:8*index]; if (we & ByteMask[index]) RAM[adrmsbs][8*(index+1)-1:8*index] <= #1 wd[8*(index+1)-1:8*index];
end end
end end
-----/\----- EXCLUDED -----/\----- */
endmodule endmodule

View File

@ -102,6 +102,7 @@ module BTBPredictor
// Another optimization may be using a PC relative address. // Another optimization may be using a PC relative address.
// *** need to add forwarding. // *** need to add forwarding.
// *** optimize for byte write enables
SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk), SRAM2P1R1W #(Depth, `XLEN+5) memory(.clk(clk),
.reset(reset), .reset(reset),
.RA1(LookUpPCIndex), .RA1(LookUpPCIndex),

View File

@ -66,7 +66,7 @@ module ifu (
output logic IllegalIEUInstrFaultD, output logic IllegalIEUInstrFaultD,
output logic InstrMisalignedFaultM, output logic InstrMisalignedFaultM,
output logic [`XLEN-1:0] InstrMisalignedAdrM, output logic [`XLEN-1:0] InstrMisalignedAdrM,
input logic ExceptionM, PendingInterruptM, input logic ExceptionM,
// mmu management // mmu management
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PTE, input logic [`XLEN-1:0] PTE,
@ -142,8 +142,7 @@ module ifu (
mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1)) mmu #(.TLB_ENTRIES(`ITLB_ENTRIES), .IMMU(1))
immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .DisableTranslation(1'b0), .PrivilegeModeW, .DisableTranslation(1'b0),
.PAdr(PCFExt[`PA_BITS-1:0]), .VAdr(PCFExt),
.VAdr(PCFSpill),
.Size(2'b10), .Size(2'b10),
.PTE(PTE), .PTE(PTE),
.PageTypeWriteVal(PageType), .PageTypeWriteVal(PageType),

View File

@ -48,7 +48,7 @@ module dtim(
output logic DCacheCommittedM, output logic DCacheCommittedM,
output logic DCacheMiss, output logic DCacheMiss,
output logic DCacheAccess); output logic DCacheAccess);
simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.clk, .ByteMask(ByteMaskM), .clk, .ByteMask(ByteMaskM),
.a(CPUBusy | LSURWM[0] | reset ? IEUAdrM[31:0] : IEUAdrE[31:0]), // move mux out; this shouldn't be needed when stails are handled differently *** .a(CPUBusy | LSURWM[0] | reset ? IEUAdrM[31:0] : IEUAdrE[31:0]), // move mux out; this shouldn't be needed when stails are handled differently ***

View File

@ -91,7 +91,7 @@ module lsu (
logic [2:0] LSUFunct3M; logic [2:0] LSUFunct3M;
logic [6:0] LSUFunct7M; logic [6:0] LSUFunct7M;
logic [1:0] LSUAtomicM; logic [1:0] LSUAtomicM;
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLSUPAdrM; (* mark_debug = "true" *) logic [`XLEN+1:0] PreLSUPAdrM;
logic [11:0] PreLSUAdrE, LSUAdrE; logic [11:0] PreLSUAdrE, LSUAdrE;
logic CPUBusy; logic CPUBusy;
logic DCacheStallM; logic DCacheStallM;
@ -132,7 +132,7 @@ module lsu (
assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0; assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
assign IgnoreRequestTrapM = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM; assign IgnoreRequestTrapM = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM;
assign LSUAdrE = PreLSUAdrE; assign PreLSUAdrE = IEUAdrE[11:0]; assign LSUAdrE = PreLSUAdrE; assign PreLSUAdrE = IEUAdrE[11:0];
assign PreLSUPAdrM = IEUAdrExtM[`PA_BITS-1:0]; assign PreLSUPAdrM = IEUAdrExtM;
assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM; assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
assign LSUWriteDataM = WriteDataM; assign LSUWriteDataM = WriteDataM;
end end
@ -151,8 +151,7 @@ module lsu (
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0)) mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .DisableTranslation, .PrivilegeModeW, .DisableTranslation,
.PAdr(PreLSUPAdrM), .VAdr(PreLSUPAdrM),
.VAdr(IEUAdrM),
.Size(LSUFunct3M[1:0]), .Size(LSUFunct3M[1:0]),
.PTE, .PTE,
.PageTypeWriteVal(PageType), .PageTypeWriteVal(PageType),

View File

@ -59,7 +59,7 @@ module lsuvirtmem(
output logic [1:0] PreLSURWM, output logic [1:0] PreLSURWM,
output logic [1:0] LSUAtomicM, output logic [1:0] LSUAtomicM,
output logic [11:0] LSUAdrE, output logic [11:0] LSUAdrE,
output logic [`PA_BITS-1:0] PreLSUPAdrM, output logic [`XLEN+1:0] PreLSUPAdrM,
input logic [`XLEN+1:0] IEUAdrExtM, // *** can move internally. input logic [`XLEN+1:0] IEUAdrExtM, // *** can move internally.
output logic InterlockStall, output logic InterlockStall,
@ -71,13 +71,15 @@ module lsuvirtmem(
logic AnyCPUReqM; logic AnyCPUReqM;
logic [`PA_BITS-1:0] HPTWAdr; logic [`PA_BITS-1:0] HPTWAdr;
logic [`XLEN+1:0] HPTWAdrExt;
logic [1:0] HPTWRW; logic [1:0] HPTWRW;
logic [2:0] HPTWSize; logic [2:0] HPTWSize;
logic SelReplayMemE; logic SelReplayMemE;
logic [11:0] PreLSUAdrE; logic [11:0] PreLSUAdrE;
logic ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF; logic ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF;
logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM; logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM;
logic SelHPTWAdr;
assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF); assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF);
assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM); assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);
assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM; assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM;
@ -94,13 +96,22 @@ module lsuvirtmem(
.DCacheStallM, .HPTWAdr, .HPTWRW, .HPTWSize); .DCacheStallM, .HPTWAdr, .HPTWRW, .HPTWSize);
// *** possible future optimization of simplifying page table entry with precomputed misalignment (Ross) low priority // *** possible future optimization of simplifying page table entry with precomputed misalignment (Ross) low priority
// Once the walk is done and it is time to update the DTLB we need to switch back
// to the orignal data virtual address.
assign SelHPTWAdr = SelHPTW & ~DTLBWriteM;
// multiplex the outputs to LSU // multiplex the outputs to LSU
if(`XLEN+2-`PA_BITS > 0) begin
logic [(`XLEN+2-`PA_BITS)-1:0] zeros;
assign zeros = '0;
assign HPTWAdrExt = {zeros, HPTWAdr};
end else assign HPTWAdrExt = HPTWAdr;
mux2 #(2) rwmux(MemRWM, HPTWRW, SelHPTW, PreLSURWM); mux2 #(2) rwmux(MemRWM, HPTWRW, SelHPTW, PreLSURWM);
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M);
mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M);
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM);
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE); mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE);
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLSUPAdrM); mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, PreLSUPAdrM);
if(`HPTW_WRITES_SUPPORTED) if(`HPTW_WRITES_SUPPORTED)
mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, LSUWriteDataM); mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, LSUWriteDataM);
else assign LSUWriteDataM = WriteDataM; else assign LSUWriteDataM = WriteDataM;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// ram.sv // swbytemask.sv
// //
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu 9 January 2021
// Modified: // Modified:

View File

@ -49,16 +49,10 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
// 11 - TLB is accessed for both read and write // 11 - TLB is accessed for both read and write
input logic DisableTranslation, input logic DisableTranslation,
// VAdr goes to the TLB only. Virtual if the TLB is active. // VAdr is the virtual/physical address from IEU or physical address from HPTW.
// PAdr goes to address mux bypassing the TLB. PAdr used when there is no translation.
// Comes from either the program address (instruction address or load/store address)
// or from the hardware pagetable walker.
// PAdr is intended to used as a phsycial address. Discarded by the address mux when translation is
// performed.
// PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr) // PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr)
// when there is translation. // when there is translation.
input logic [`PA_BITS-1:0] PAdr, // *** consider renaming this. input logic [`XLEN+1:0] VAdr,
input logic [`XLEN-1:0] VAdr,
input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
// Controls for writing a new entry to the TLB // Controls for writing a new entry to the TLB
@ -106,7 +100,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
tlb(.clk, .reset, tlb(.clk, .reset,
.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]),
.SATP_ASID(SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE]), .SATP_ASID(SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE]),
.VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .VAdr(VAdr[`XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .PrivilegeModeW, .ReadAccess, .WriteAccess,
.DisableTranslation, .PTE, .PageTypeWriteVal, .DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
@ -122,8 +116,8 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
// the lower 12 bits are the page offset. These are never changed from the orginal // the lower 12 bits are the page offset. These are never changed from the orginal
// non translated address. // non translated address.
//mux2 #(`PA_BITS) addressmux(PAdr, TLBPAdr, Translate, PhysicalAddress); //mux2 #(`PA_BITS) addressmux(PAdr, TLBPAdr, Translate, PhysicalAddress);
mux2 #(`PA_BITS-12) addressmux(PAdr[`PA_BITS-1:12], TLBPAdr[`PA_BITS-1:12], Translate, PhysicalAddress[`PA_BITS-1:12]); mux2 #(`PA_BITS-12) addressmux(VAdr[`PA_BITS-1:12], TLBPAdr[`PA_BITS-1:12], Translate, PhysicalAddress[`PA_BITS-1:12]);
assign PhysicalAddress[11:0] = PAdr[11:0]; assign PhysicalAddress[11:0] = VAdr[11:0];
/////////////////////////////////////////// ///////////////////////////////////////////

View File

@ -43,7 +43,7 @@ module csr #(parameter
input logic [31:0] InstrM, input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM, input logic [`XLEN-1:0] PCM, SrcAM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, input logic TimerIntM, MExtIntM, SExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
input logic InstrValidM, FRegWriteM, LoadStallD, input logic InstrValidM, FRegWriteM, LoadStallD,
input logic BPPredDirWrongM, input logic BPPredDirWrongM,
@ -60,9 +60,9 @@ module csr #(parameter
output logic [1:0] STATUS_MPP, output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, output logic STATUS_SPP, STATUS_TSR,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, output logic [`XLEN-1:0] MEDELEG_REGW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW,
output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MIE, STATUS_SIE,
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW,
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
@ -122,9 +122,10 @@ module csr #(parameter
assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW); assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW);
assign CSRUWriteM = CSRWriteM; assign CSRUWriteM = CSRWriteM;
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM, csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM, .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM); .MExtIntM, .SExtIntM, .TimerIntM, .SwIntM,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW);
csrsr csrsr(.clk, .reset, .StallW, csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteSSTATUSM, .WriteMSTATUSM, .WriteSSTATUSM,
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW, .TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,

View File

@ -32,78 +32,62 @@
`include "wally-config.vh" `include "wally-config.vh"
module csri #(parameter module csri #(parameter
// Machine CSRs MIE = 12'h304,
MIE = 12'h304, MIP = 12'h344,
MIP = 12'h344, SIE = 12'h104,
SIE = 12'h104, SIP = 12'h144
SIP = 12'h144) ( ) (
input logic clk, reset, input logic clk, reset,
input logic InstrValidNotFlushedM, StallW, input logic InstrValidNotFlushedM, StallW,
input logic CSRMWriteM, CSRSWriteM, input logic CSRMWriteM, CSRSWriteM,
input logic [`XLEN-1:0] CSRWriteValM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic ExtIntM, ExtIntS, TimerIntM, SwIntM, input logic MExtIntM, SExtIntM, TimerIntM, SwIntM,
input logic [`XLEN-1:0] MIDELEG_REGW, input logic [11:0] MIDELEG_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW
input logic [`XLEN-1:0] CSRWriteValM
); );
logic [9:0] IP_REGW_writeable; logic [11:0] IP_REGW_writeable; // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
logic [11:0] IntInM, IP_REGW, IE_REGW; logic [11:0] IP_REGW, IE_REGW;
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK; logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;
logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM; logic WriteMIPM, WriteMIEM, WriteSIPM, WriteSIEM;
// Determine which interrupts need to be set
// assumes no N-mode user interrupts
always_comb begin
IntInM = 0;
IntInM[11] = ExtIntM; // MEIP
IntInM[9] = (ExtIntM & MIDELEG_REGW[9]); // SEIP
IntInM[7] = TimerIntM; // MTIP
IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP
IntInM[3] = SwIntM; // MSIP
IntInM[1] = SwIntM & MIDELEG_REGW[1]; // SSIP
end
// Interrupt Write Enables // Interrupt Write Enables
assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM; assign WriteMIPM = CSRMWriteM & (CSRAdrM == MIP) & InstrValidNotFlushedM;
assign WriteMIEM = CSRMWriteM & (CSRAdrM == MIE) & InstrValidNotFlushedM; assign WriteMIEM = CSRMWriteM & (CSRAdrM == MIE) & InstrValidNotFlushedM;
assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP) & InstrValidNotFlushedM; assign WriteSIPM = CSRSWriteM & (CSRAdrM == SIP) & InstrValidNotFlushedM;
assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE) & InstrValidNotFlushedM; assign WriteSIEM = CSRSWriteM & (CSRAdrM == SIE) & InstrValidNotFlushedM;
// Interrupt Pending and Enable Registers // Interrupt Pending and Enable Registers
// MEIP, MTIP, MSIP are read-only // MEIP, MTIP, MSIP are read-only
// SEIP, STIP, SSIP is writable in MIP if S mode exists // SEIP, STIP, SSIP is writable in MIP if S mode exists
// SSIP is writable in SIP if S mode exists // SSIP is writable in SIP if S mode exists
if (`S_SUPPORTED) begin:mask if (`S_SUPPORTED) begin:mask
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writable in MIP (20210108-draft 3.1.9) 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) assign SIP_WRITE_MASK = 12'h002; // SSIP is writable in SIP (privileged 20210108-draft 4.1.3)
assign MIE_WRITE_MASK = 12'hAAA;
end else begin:mask end else begin:mask
assign MIP_WRITE_MASK = 12'h000; assign MIP_WRITE_MASK = 12'h000;
assign SIP_WRITE_MASK = 12'h000; assign SIP_WRITE_MASK = 12'h000;
assign MIE_WRITE_MASK = 12'h888;
end end
always @(posedge clk) always @(posedge clk)
if (reset) IP_REGW_writeable <= 10'b0; if (reset) IP_REGW_writeable <= 12'b0;
else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & MIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable else if (WriteMIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & MIP_WRITE_MASK);
else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[9:0] & SIP_WRITE_MASK[9:0]) | {1'b0,IntInM[8:0]}; // MTIP unclearable else if (WriteSIPM) IP_REGW_writeable <= (CSRWriteValM[11:0] & SIP_WRITE_MASK);
else IP_REGW_writeable <= IP_REGW_writeable | {1'b0, IntInM[8:0]}; // *** check this turns off interrupts properly even when MIDELEG changes
always @(posedge clk) always @(posedge clk)
if (reset) IE_REGW <= 12'b0; if (reset) IE_REGW <= 12'b0;
else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'hAAA); // MIE controls M and S fields else if (WriteMIEM) IE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields else if (WriteSIEM) IE_REGW <= (CSRWriteValM[11:0] & 12'h222) | (IE_REGW & 12'h888); // only S fields
// restricted views of registers assign IP_REGW = {MExtIntM,1'b0,SExtIntM|IP_REGW_writeable[9],1'b0,TimerIntM,1'b0,IP_REGW_writeable[5],1'b0,SwIntM,1'b0,IP_REGW_writeable[1],1'b0};
// Add ExtIntM read-only signal
assign IP_REGW = {ExtIntM,1'b0,ExtIntS,9'b0} | {2'b0,IP_REGW_writeable};
// Machine Mode
assign MIP_REGW = IP_REGW; assign MIP_REGW = IP_REGW;
assign MIE_REGW = IE_REGW; assign MIE_REGW = IE_REGW;
// Supervisor mode
if (`S_SUPPORTED) begin if (`S_SUPPORTED) begin
assign SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible assign SIP_REGW = IP_REGW & 12'h222;
assign SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; assign SIE_REGW = IE_REGW & 12'h222;
end else begin end else begin
assign SIP_REGW = 12'b0; assign SIP_REGW = 12'b0;
assign SIE_REGW = 12'b0; assign SIE_REGW = 12'b0;

View File

@ -33,42 +33,42 @@
`include "wally-config.vh" `include "wally-config.vh"
module csrm #(parameter module csrm #(parameter
// Machine CSRs // Machine CSRs
MVENDORID = 12'hF11, MVENDORID = 12'hF11,
MARCHID = 12'hF12, MARCHID = 12'hF12,
MIMPID = 12'hF13, MIMPID = 12'hF13,
MHARTID = 12'hF14, MHARTID = 12'hF14,
MSTATUS = 12'h300, MSTATUS = 12'h300,
MISA_ADR = 12'h301, MISA_ADR = 12'h301,
MEDELEG = 12'h302, MEDELEG = 12'h302,
MIDELEG = 12'h303, MIDELEG = 12'h303,
MIE = 12'h304, MIE = 12'h304,
MTVEC = 12'h305, MTVEC = 12'h305,
MCOUNTEREN = 12'h306, MCOUNTEREN = 12'h306,
MSTATUSH = 12'h310, MSTATUSH = 12'h310,
MCOUNTINHIBIT = 12'h320, MCOUNTINHIBIT = 12'h320,
MSCRATCH = 12'h340, MSCRATCH = 12'h340,
MEPC = 12'h341, MEPC = 12'h341,
MCAUSE = 12'h342, MCAUSE = 12'h342,
MTVAL = 12'h343, MTVAL = 12'h343,
MIP = 12'h344, MIP = 12'h344,
PMPCFG0 = 12'h3A0, PMPCFG0 = 12'h3A0,
// .. up to 15 more at consecutive addresses // .. up to 15 more at consecutive addresses
PMPADDR0 = 12'h3B0, PMPADDR0 = 12'h3B0,
// ... up to 63 more at consecutive addresses // ... up to 63 more at consecutive addresses
TSELECT = 12'h7A0, TSELECT = 12'h7A0,
TDATA1 = 12'h7A1, TDATA1 = 12'h7A1,
TDATA2 = 12'h7A2, TDATA2 = 12'h7A2,
TDATA3 = 12'h7A3, TDATA3 = 12'h7A3,
DCSR = 12'h7B0, DCSR = 12'h7B0,
DPC = 12'h7B1, DPC = 12'h7B1,
DSCRATCH0 = 12'h7B2, DSCRATCH0 = 12'h7B2,
DSCRATCH1 = 12'h7B3, DSCRATCH1 = 12'h7B3,
// Constants // Constants
ZERO = {(`XLEN){1'b0}}, ZERO = {(`XLEN){1'b0}},
MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11),
MIDELEG_MASK = {{(`XLEN-12){1'b0}}, 12'h222} MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable
) ( ) (
input logic clk, reset, input logic clk, reset,
input logic InstrValidNotFlushedM, StallW, input logic InstrValidNotFlushedM, StallW,
input logic CSRMWriteM, MTrapM, input logic CSRMWriteM, MTrapM,
@ -78,7 +78,8 @@ module csrm #(parameter
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW, output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] MEPC_REGW, (* mark_debug = "true" *) output logic [`XLEN-1:0] MEPC_REGW,
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, output logic [`XLEN-1:0] MEDELEG_REGW,
output logic [11:0] MIDELEG_REGW,
// 64-bit registers in RV64, or two 32-bit registers in RV32 // 64-bit registers in RV64, or two 32-bit registers in RV32
//output var logic [63:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0], //output var logic [63:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES/8-1:0],
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
@ -148,7 +149,7 @@ module csrm #(parameter
flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW);
if (`S_SUPPORTED) begin:deleg // DELEG registers should exist if (`S_SUPPORTED) begin:deleg // DELEG registers should exist
flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW); flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW);
flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW);
end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0; end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0;
flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW); flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW);
@ -188,7 +189,7 @@ module csrm #(parameter
MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported
MTVEC: CSRMReadValM = MTVEC_REGW; MTVEC: CSRMReadValM = MTVEC_REGW;
MEDELEG: CSRMReadValM = MEDELEG_REGW; MEDELEG: CSRMReadValM = MEDELEG_REGW;
MIDELEG: CSRMReadValM = MIDELEG_REGW; MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW};
MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW}; MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW};
MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW}; MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW};
MSCRATCH: CSRMReadValM = MSCRATCH_REGW; MSCRATCH: CSRMReadValM = MSCRATCH_REGW;

View File

@ -55,7 +55,7 @@ module privileged (
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD, input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
input logic LoadMisalignedFaultM, input logic LoadMisalignedFaultM,
input logic StoreAmoMisalignedFaultM, input logic StoreAmoMisalignedFaultM,
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, input logic TimerIntM, MExtIntM, SExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM, input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
input logic [4:0] SetFflagsM, input logic [4:0] SetFflagsM,
@ -69,7 +69,6 @@ module privileged (
input logic StoreAmoAccessFaultM, input logic StoreAmoAccessFaultM,
output logic ExceptionM, output logic ExceptionM,
output logic PendingInterruptM,
output logic IllegalFPUInstrE, output logic IllegalFPUInstrE,
output logic [1:0] PrivilegeModeW, output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
@ -86,7 +85,8 @@ module privileged (
logic [`XLEN-1:0] CauseM, NextFaultMtvalM; logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW; logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW;
logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW; logic [`XLEN-1:0] MEDELEG_REGW;
logic [11:0] MIDELEG_REGW;
logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM; logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
logic IllegalCSRAccessM; logic IllegalCSRAccessM;
@ -111,7 +111,7 @@ module privileged (
/////////////////////////////////////////// ///////////////////////////////////////////
// get bits of DELEG registers based on CAUSE // get bits of DELEG registers based on CAUSE
assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
// PrivilegeMode FSM // PrivilegeMode FSM
always_comb begin always_comb begin
@ -150,7 +150,7 @@ module privileged (
.StallE, .StallM, .StallW, .StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM, .InstrM, .PCM, .SrcAM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM,
.MTIME_CLINT, .MTIME_CLINT,
.InstrValidM, .FRegWriteM, .LoadStallD, .InstrValidM, .FRegWriteM, .LoadStallD,
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
@ -159,9 +159,9 @@ module privileged (
.CauseM, .NextFaultMtvalM, .STATUS_MPP, .CauseM, .NextFaultMtvalM, .STATUS_MPP,
.STATUS_SPP, .STATUS_TSR, .STATUS_SPP, .STATUS_TSR,
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW, .MIDELEG_REGW, .MEDELEG_REGW,
.SATP_REGW, .SATP_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MIE, .STATUS_SIE,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW,
.PMPCFG_ARRAY_REGW, .PMPCFG_ARRAY_REGW,
@ -210,7 +210,7 @@ module privileged (
.mretM, .sretM, .mretM, .sretM,
.PrivilegeModeW, .NextPrivilegeModeM, .PrivilegeModeW, .NextPrivilegeModeM,
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MIE, .STATUS_SIE,
.PCM, .PCM,
.InstrMisalignedAdrM, .IEUAdrM, .InstrMisalignedAdrM, .IEUAdrM,
@ -219,7 +219,6 @@ module privileged (
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM, .TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
.InterruptM, .InterruptM,
.ExceptionM, .ExceptionM,
.PendingInterruptM,
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM); .PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
endmodule endmodule

View File

@ -41,7 +41,7 @@ module trap (
(* mark_debug = "true" *) input logic mretM, sretM, (* mark_debug = "true" *) input logic mretM, sretM,
input logic [1:0] PrivilegeModeW, NextPrivilegeModeM, input logic [1:0] PrivilegeModeW, NextPrivilegeModeM,
(* mark_debug = "true" *) input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW, (* mark_debug = "true" *) input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, MIDELEG_REGW,
input logic STATUS_MIE, STATUS_SIE, input logic STATUS_MIE, STATUS_SIE,
input logic [`XLEN-1:0] PCM, input logic [`XLEN-1:0] PCM,
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM, input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
@ -50,15 +50,13 @@ module trap (
output logic TrapM, MTrapM, STrapM, UTrapM, RetM, output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
output logic InterruptM, output logic InterruptM,
output logic ExceptionM, output logic ExceptionM,
output logic PendingInterruptM,
output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW, // output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
// input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM // input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
); );
logic MIntGlobalEnM, SIntGlobalEnM; logic MIntGlobalEnM, SIntGlobalEnM;
(* mark_debug = "true" *) logic [11:0] PendingIntsM; (* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM;
//logic InterruptM; //logic InterruptM;
logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector; logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
logic Exception1M; logic Exception1M;
@ -67,11 +65,13 @@ module trap (
// interrupt if any sources are pending // interrupt if any sources are pending
// & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage) // & with a M stage valid bit to avoid interrupts from interrupt a nonexistent flushed instruction (in the M stage)
// & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice // & with ~CommittedM to make sure MEPC isn't chosen so as to rerun the same instr twice
// MPendingIntsM[i] = ((priv == M & mstatus.MIE) | (priv < M)) & mip[i] & mie[i] & ~mideleg[i]
// Sinterrupt[i] = ((priv == S & sstatus.SIE) | (priv < S)) & sip[i] & sie[i]
assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9 assign MIntGlobalEnM = (PrivilegeModeW != `M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9
assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9 assign SIntGlobalEnM = (PrivilegeModeW == `U_MODE) | ((PrivilegeModeW == `S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9
assign PendingIntsM = ((MIP_REGW & MIE_REGW) & ({12{MIntGlobalEnM}} & 12'h888)) | ((SIP_REGW & SIE_REGW) & ({12{SIntGlobalEnM}} & 12'h222)); assign MPendingIntsM = {12{MIntGlobalEnM}} & MIP_REGW & MIE_REGW & ~MIDELEG_REGW;
assign PendingInterruptM = (|PendingIntsM) & InstrValidM; assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW;
assign InterruptM = PendingInterruptM & ~(CommittedM); // *** RT. temporary hack to prevent integer division from having an interrupt during divide. assign InterruptM = (|MPendingIntsM || |SPendingIntsM) && InstrValidM && ~(CommittedM); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
// Trigger Traps and RET // Trigger Traps and RET
// According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous. // According to RISC-V Spec Section 1.6, exceptions are caused by instructions. Interrupts are external asynchronous.
@ -102,7 +102,7 @@ module trap (
if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec if(`VECTORED_INTERRUPTS_SUPPORTED) begin:vec
always_comb always_comb
if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1) if (PrivilegedTrapVector[1:0] == 2'b01 & CauseM[`XLEN-1] == 1)
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + {CauseM[`XLEN-5:0], 2'b00}, 2'b00}; PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2] + CauseM[`XLEN-3:0], 2'b00};
else else
PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00}; PrivilegedVectoredTrapVector = {PrivilegedTrapVector[`XLEN-1:2], 2'b00};
end end
@ -119,12 +119,15 @@ module trap (
// Exceptions are of lower priority than all interrupts (3.1.9) // Exceptions are of lower priority than all interrupts (3.1.9)
always_comb always_comb
if (reset) CauseM = 0; // hard reset 3.3 if (reset) CauseM = 0; // hard reset 3.3
else if (PendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int else if (MPendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
else if (PendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int else if (MPendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
else if (PendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int else if (MPendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
else if (PendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int else if (MPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by M-mode
else if (PendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int else if (MPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by M-mode
else if (PendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int else if (MPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by M-mode
else if (SPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by S-mode
else if (SPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by S-mode
else if (SPendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int handled by S-mode
else if (InstrPageFaultM) CauseM = 12; else if (InstrPageFaultM) CauseM = 12;
else if (InstrAccessFaultM) CauseM = 1; else if (InstrAccessFaultM) CauseM = 1;
else if (InstrMisalignedFaultM) CauseM = 0; else if (InstrMisalignedFaultM) CauseM = 0;

View File

@ -57,7 +57,7 @@ module plic (
input logic UARTIntr,GPIOIntr, input logic UARTIntr,GPIOIntr,
output logic [`XLEN-1:0] HREADPLIC, output logic [`XLEN-1:0] HREADPLIC,
output logic HRESPPLIC, HREADYPLIC, output logic HRESPPLIC, HREADYPLIC,
output logic ExtIntM, ExtIntS); output logic MExtIntM, SExtIntM);
logic memwrite, memread, initTrans; logic memwrite, memread, initTrans;
logic [23:0] entry, entryd; logic [23:0] entry, entryd;
@ -253,10 +253,10 @@ module plic (
threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3]; threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2]; threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2];
end end
// is the max priority > threshold? end
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold? // is the max priority > threshold?
end // *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]); assign MExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]); assign SExtIntM = |(threshMask[1] & priorities_with_irqs[1]);
endmodule endmodule

View File

@ -43,78 +43,22 @@ module ram #(parameter BASE=0, RANGE = 65535) (
output logic HRESPRam, HREADYRam output logic HRESPRam, HREADYRam
); );
localparam MemStartAddr = BASE>>(1+`XLEN/32); logic [`XLEN/8-1:0] ByteMaskM;
localparam MemEndAddr = (RANGE+BASE)>>1+(`XLEN/32); logic [31:0] HWADDR, A;
logic prevHREADYRam, risingHREADYRam;
logic initTrans;
logic memwrite;
logic [3:0] busycount;
logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; swbytemask swbytemask(.HSIZED, .HADDRD(HWADDR[2:0]), .ByteMask(ByteMaskM));
logic [31:0] HWADDR, A;
logic prevHREADYRam, risingHREADYRam;
logic initTrans;
logic memwrite;
logic [3:0] busycount;
logic [`XLEN/8-1:0] ByteMaskM;
if(`FPGA) begin:ram
initial begin
// *** need to address this preload for fpga. It should work as a preload file
// but for some reason vivado is not synthesizing the preload.
//$readmemh(PRELOAD, RAM);
RAM[BASE+0] = 64'h94e1819300002197;
RAM[BASE+1] = 64'h4281420141014081;
RAM[BASE+2] = 64'h4481440143814301;
RAM[BASE+3] = 64'h4681460145814501;
RAM[BASE+4] = 64'h4881480147814701;
RAM[BASE+5] = 64'h4a814a0149814901;
RAM[BASE+6] = 64'h4c814c014b814b01;
RAM[BASE+7] = 64'h4e814e014d814d01;
RAM[BASE+8] = 64'h0110011b4f814f01;
RAM[BASE+9] = 64'h059b45011161016e;
RAM[BASE+10] = 64'h0004063705fe0010;
RAM[BASE+11] = 64'h05a000ef8006061b;
RAM[BASE+12] = 64'h0ff003930000100f;
RAM[BASE+13] = 64'h4e952e3110060e37;
RAM[BASE+14] = 64'hc602829b0053f2b7;
RAM[BASE+15] = 64'h2023fe02dfe312fd;
RAM[BASE+16] = 64'h829b0053f2b7007e;
RAM[BASE+17] = 64'hfe02dfe312fdc602;
RAM[BASE+18] = 64'h4de31efd000e2023;
RAM[BASE+19] = 64'h059bf1402573fdd0;
RAM[BASE+20] = 64'h0000061705e20870;
RAM[BASE+21] = 64'h0010029b01260613;
RAM[BASE+22] = 64'h11010002806702fe;
RAM[BASE+23] = 64'h84b2842ae426e822;
RAM[BASE+24] = 64'h892ee04aec064505;
RAM[BASE+25] = 64'h06e000ef07e000ef;
RAM[BASE+26] = 64'h979334fd02905563;
RAM[BASE+27] = 64'h07930177d4930204;
RAM[BASE+28] = 64'h4089093394be2004;
RAM[BASE+29] = 64'h04138522008905b3;
RAM[BASE+30] = 64'h19e3014000ef2004;
RAM[BASE+31] = 64'h64a2644260e2fe94;
RAM[BASE+32] = 64'h6749808261056902;
RAM[BASE+33] = 64'hdfed8b8510472783;
RAM[BASE+34] = 64'h2423479110a73823;
RAM[BASE+35] = 64'h10472783674910f7;
RAM[BASE+36] = 64'h20058693ffed8b89;
RAM[BASE+37] = 64'h05a1118737836749;
RAM[BASE+38] = 64'hfed59be3fef5bc23;
RAM[BASE+39] = 64'h1047278367498082;
RAM[BASE+40] = 64'h67c98082dfed8b85;
RAM[BASE+41] = 64'h0000808210a7a023;
end // initial begin
end // if (FPGA)
swbytemask swbytemask(.HSIZED, .HADDRD(A[2:0]), .ByteMask(ByteMaskM));
assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00); assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00);
// *** this seems like a weird way to use reset // *** this seems like a weird way to use reset
flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam & HWRITE, memwrite); flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam & HWRITE, memwrite);
flopenr #(32) haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A); flopenr #(32) haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A);
// busy FSM to extend READY signal // busy FSM to extend READY signal
always_ff @(posedge HCLK, negedge HRESETn) always @(posedge HCLK, negedge HRESETn)
if (~HRESETn) begin if (~HRESETn) begin
busycount <= 0; busycount <= 0;
HREADYRam <= #1 0; HREADYRam <= #1 0;
@ -131,47 +75,26 @@ module ram #(parameter BASE=0, RANGE = 65535) (
end end
end end
assign HRESPRam = 0; // OK assign HRESPRam = 0; // OK
localparam ADDR_WDITH = $clog2(RANGE/8);
localparam OFFSET = $clog2(`XLEN/8);
// Rising HREADY edge detector // Rising HREADY edge detector
// Indicates when ram is finishing up // Indicates when ram is finishing up
// Needed because HREADY may go high for other reasons, // Needed because HREADY may go high for other reasons,
// and we only want to write data when finishing up. // and we only want to write data when finishing up.
flopr #(1) prevhreadyRamreg(HCLK,~HRESETn,HREADYRam,prevHREADYRam); flopenr #(1) prevhreadyRamreg(HCLK,~HRESETn, 1'b1, HREADYRam,prevHREADYRam);
assign risingHREADYRam = HREADYRam & ~prevHREADYRam; assign risingHREADYRam = HREADYRam & ~prevHREADYRam;
// Model memory read and write always @(posedge HCLK)
/* -----\/----- EXCLUDED -----\/-----
integer index;
initial begin
for(index = MemStartAddr; index < MemEndAddr; index = index + 1) begin
RAM[index] <= {`XLEN{1'b0}};
end
end
-----/\----- EXCLUDED -----/\----- */
/* verilator lint_off WIDTH */
genvar index;
always_ff @(posedge HCLK)
HWADDR <= #1 A; HWADDR <= #1 A;
if (`XLEN == 64) begin:ramrw
always_ff @(posedge HCLK)
HREADRam <= #1 RAM[A[31:3]];
for(index = 0; index < `XLEN/8; index++) begin
always_ff @(posedge HCLK) begin
if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:3]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index];
end
end
end else begin
always_ff @(posedge HCLK)
HREADRam <= #1 RAM[A[31:2]];
for(index = 0; index < `XLEN/8; index++) begin
always_ff @(posedge HCLK) begin:ramrw
if (memwrite & risingHREADYRam & ByteMaskM[index]) RAM[HWADDR[31:2]][8*(index+1)-1:8*index] <= #1 HWDATA[8*(index+1)-1:8*index];
end
end
end
/* verilator lint_on WIDTH */
bram2p1r1w #(`XLEN/8, 8, ADDR_WDITH, `FPGA)
memory(.clk(HCLK), .enaA(1'b1),
.addrA(A[ADDR_WDITH+OFFSET-1:OFFSET]), .doutA(HREADRam),
.enaB(memwrite & risingHREADYRam), .weB(ByteMaskM),
.addrB(HWADDR[ADDR_WDITH+OFFSET-1:OFFSET]), .dinB(HWDATA));
endmodule endmodule

View File

@ -55,7 +55,7 @@ module uncore (
input logic [3:0] HSIZED, input logic [3:0] HSIZED,
input logic HWRITED, input logic HWRITED,
// peripheral pins // peripheral pins
output logic TimerIntM, SwIntM, ExtIntM, ExtIntS, output logic TimerIntM, SwIntM, MExtIntM, SExtIntM,
input logic [31:0] GPIOPinsIn, input logic [31:0] GPIOPinsIn,
output logic [31:0] GPIOPinsOut, GPIOPinsEn, output logic [31:0] GPIOPinsOut, GPIOPinsEn,
input logic UARTSin, input logic UARTSin,
@ -133,10 +133,10 @@ module uncore (
.HWRITE, .HREADY, .HTRANS, .HWDATA, .HWRITE, .HREADY, .HTRANS, .HWDATA,
.UARTIntr, .GPIOIntr, .UARTIntr, .GPIOIntr,
.HREADPLIC, .HRESPPLIC, .HREADYPLIC, .HREADPLIC, .HRESPPLIC, .HREADYPLIC,
.ExtIntM, .ExtIntS); .MExtIntM, .SExtIntM);
end else begin : plic end else begin : plic
assign ExtIntM = 0; assign MExtIntM = 0;
assign ExtIntS = 0; assign SExtIntM = 0;
end end
if (`GPIO_SUPPORTED == 1) begin : gpio if (`GPIO_SUPPORTED == 1) begin : gpio
gpio gpio( gpio gpio(

View File

@ -34,7 +34,7 @@
module wallypipelinedcore ( module wallypipelinedcore (
input logic clk, reset, input logic clk, reset,
// Privileged // Privileged
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM, input logic TimerIntM, MExtIntM, SExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
// Bus Interface // Bus Interface
input logic [`AHBW-1:0] HRDATA, input logic [`AHBW-1:0] HRDATA,
@ -157,7 +157,6 @@ module wallypipelinedcore (
logic [2:0] LSUBusSize; logic [2:0] LSUBusSize;
logic ExceptionM; logic ExceptionM;
logic PendingInterruptM;
logic DCacheMiss; logic DCacheMiss;
logic DCacheAccess; logic DCacheAccess;
logic ICacheMiss; logic ICacheMiss;
@ -170,7 +169,7 @@ module wallypipelinedcore (
.StallF, .StallD, .StallE, .StallM, .StallW, .StallF, .StallD, .StallE, .StallM, .StallW,
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW, .FlushF, .FlushD, .FlushE, .FlushM, .FlushW,
.ExceptionM, .PendingInterruptM, .ExceptionM,
// Fetch // Fetch
.IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr, .IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr,
.IFUBusRead, .IFUStallF, .IFUBusRead, .IFUStallF,
@ -182,7 +181,7 @@ module wallypipelinedcore (
// Mem // Mem
.RetM, .TrapM, .PrivilegedNextPCM, .InvalidateICacheM, .RetM, .TrapM, .PrivilegedNextPCM, .InvalidateICacheM,
.InstrD, .InstrM, . PCM, .InstrClassM, .BPPredDirWrongM, .InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM, .BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
// Writeback // Writeback
@ -331,7 +330,7 @@ module wallypipelinedcore (
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD, .InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM,
.MTIME_CLINT, .MTIME_CLINT,
.InstrMisalignedAdrM, .IEUAdrM, .InstrMisalignedAdrM, .IEUAdrM,
.SetFflagsM, .SetFflagsM,
@ -339,7 +338,7 @@ module wallypipelinedcore (
// *** do these need to be split up into one for dmem and one for ifu? // *** do these need to be split up into one for dmem and one for ifu?
// instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem? // instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem?
.InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM,
.ExceptionM, .PendingInterruptM, .IllegalFPUInstrE, .ExceptionM, .IllegalFPUInstrE,
.PrivilegeModeW, .SATP_REGW, .PrivilegeModeW, .SATP_REGW,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,

View File

@ -74,7 +74,7 @@ module wallypipelinedsoc (
logic HRESP; logic HRESP;
logic TimerIntM, SwIntM; // from CLINT logic TimerIntM, SwIntM; // from CLINT
logic [63:0] MTIME_CLINT; // from CLINT to CSRs logic [63:0] MTIME_CLINT; // from CLINT to CSRs
logic ExtIntM,ExtIntS; // from PLIC logic MExtIntM,SExtIntM; // from PLIC
logic [2:0] HADDRD; logic [2:0] HADDRD;
logic [3:0] HSIZED; logic [3:0] HSIZED;
logic HWRITED; logic HWRITED;
@ -84,7 +84,7 @@ module wallypipelinedsoc (
// instantiate processor and memories // instantiate processor and memories
wallypipelinedcore core(.clk, .reset, wallypipelinedcore core(.clk, .reset,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM, .TimerIntM, .MExtIntM, .SExtIntM, .SwIntM,
.MTIME_CLINT, .MTIME_CLINT,
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA,
.HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK,
@ -94,7 +94,7 @@ module wallypipelinedsoc (
uncore uncore(.HCLK, .HRESETn, .TIMECLK, uncore uncore(.HCLK, .HRESETn, .TIMECLK,
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED, .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HADDRD, .HSIZED, .HWRITED,
.TimerIntM, .SwIntM, .ExtIntM, .ExtIntS, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT, .TimerIntM, .SwIntM, .MExtIntM, .SExtIntM, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .UARTSout, .MTIME_CLINT,
.HSELEXT, .HSELEXT,
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK .SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK

View File

@ -357,7 +357,7 @@ module testbench;
initial begin initial begin
force dut.core.priv.priv.SwIntM = 0; force dut.core.priv.priv.SwIntM = 0;
force dut.core.priv.priv.TimerIntM = 0; force dut.core.priv.priv.TimerIntM = 0;
force dut.core.priv.priv.ExtIntM = 0; force dut.core.priv.priv.MExtIntM = 0;
$sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR); $sformat(testvectorDir,"%s/linux-testvectors/",RISCV_DIR);
$sformat(linuxImageDir,"%s/buildroot/output/images/",RISCV_DIR); $sformat(linuxImageDir,"%s/buildroot/output/images/",RISCV_DIR);
if (CHECKPOINT!=0) if (CHECKPOINT!=0)
@ -368,14 +368,14 @@ module testbench;
ProgramLabelMapFile = {linuxImageDir,"disassembly/vmlinux.objdump.lab"}; ProgramLabelMapFile = {linuxImageDir,"disassembly/vmlinux.objdump.lab"};
// initialize bootrom // initialize bootrom
memFile = $fopen({testvectorDir,"bootmem.bin"}, "rb"); memFile = $fopen({testvectorDir,"bootmem.bin"}, "rb");
readResult = $fread(dut.uncore.bootrom.bootrom.RAM,memFile); readResult = $fread(dut.uncore.bootrom.bootrom.memory.RAM,memFile);
$fclose(memFile); $fclose(memFile);
// initialize RAM // initialize RAM
if (CHECKPOINT==0) if (CHECKPOINT==0)
memFile = $fopen({testvectorDir,"ram.bin"}, "rb"); memFile = $fopen({testvectorDir,"ram.bin"}, "rb");
else else
memFile = $fopen({checkpointDir,"ram.bin"}, "rb"); memFile = $fopen({checkpointDir,"ram.bin"}, "rb");
readResult = $fread(dut.uncore.ram.ram.RAM,memFile); readResult = $fread(dut.uncore.ram.ram.memory.RAM,memFile);
$fclose(memFile); $fclose(memFile);
if (CHECKPOINT==0) begin // normal if (CHECKPOINT==0) begin // normal
traceFileM = $fopen({testvectorDir,"all.txt"}, "r"); traceFileM = $fopen({testvectorDir,"all.txt"}, "r");
@ -383,7 +383,7 @@ module testbench;
InstrCountW = '0; InstrCountW = '0;
AttemptedInstructionCount = '0; AttemptedInstructionCount = '0;
end else begin // checkpoint end else begin // checkpoint
//$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.RAM); //$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.memory.RAM);
traceFileE = $fopen({checkpointDir,"all.txt"}, "r"); traceFileE = $fopen({checkpointDir,"all.txt"}, "r");
traceFileM = $fopen({checkpointDir,"all.txt"}, "r"); traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
InstrCountW = CHECKPOINT; InstrCountW = CHECKPOINT;
@ -791,9 +791,9 @@ module testbench;
BaseAdr = SATP[43:0] << 12; BaseAdr = SATP[43:0] << 12;
for (i = 2; i >= 0; i--) begin for (i = 2; i >= 0; i--) begin
PAdr = BaseAdr + (VPN[i] << 3); PAdr = BaseAdr + (VPN[i] << 3);
// ram.RAM is 64-bit addressed. PAdr specifies a byte. We right shift // ram.memory.RAM is 64-bit addressed. PAdr specifies a byte. We right shift
// by 3 (the PTE size) to get the requested 64-bit PTE. // by 3 (the PTE size) to get the requested 64-bit PTE.
PTE = dut.uncore.ram.ram.RAM[PAdr >> 3]; PTE = dut.uncore.ram.ram.memory.RAM[PAdr >> 3];
PTE_R = PTE[1]; PTE_R = PTE[1];
PTE_X = PTE[3]; PTE_X = PTE[3];
if (PTE_R | PTE_X) begin if (PTE_R | PTE_X) begin

View File

@ -44,7 +44,7 @@ module testbench;
int test, i, errors, totalerrors; int test, i, errors, totalerrors;
logic [31:0] sig32[0:SIGNATURESIZE]; logic [31:0] sig32[0:SIGNATURESIZE];
logic [`XLEN-1:0] signature[0:SIGNATURESIZE]; logic [`XLEN-1:0] signature[0:SIGNATURESIZE];
logic [`XLEN-1:0] testadr; logic [`XLEN-1:0] testadr, testadrNoBase;
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName; string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
logic [31:0] InstrW; logic [31:0] InstrW;
@ -170,6 +170,7 @@ logic [3:0] dummy;
test = 1; test = 1;
totalerrors = 0; totalerrors = 0;
testadr = 0; testadr = 0;
testadrNoBase = 0;
// fill memory with defined values to reduce Xs in simulation // fill memory with defined values to reduce Xs in simulation
// Quick note the memory will need to be initialized. The C library does not // Quick note the memory will need to be initialized. The C library does not
// guarantee the initialized reads. For example a strcmp can read 6 byte // guarantee the initialized reads. For example a strcmp can read 6 byte
@ -178,7 +179,7 @@ logic [3:0] dummy;
// the design. // the design.
if (TEST == "coremark") if (TEST == "coremark")
for (i=MemStartAddr; i<MemEndAddr; i = i+1) for (i=MemStartAddr; i<MemEndAddr; i = i+1)
dut.uncore.ram.ram.RAM[i] = 64'h0; dut.uncore.ram.ram.memory.RAM[i] = 64'h0;
// read test vectors into memory // read test vectors into memory
pathname = tvpaths[tests[0].atoi()]; pathname = tvpaths[tests[0].atoi()];
@ -186,9 +187,9 @@ logic [3:0] dummy;
pathname = tvpaths[0]; pathname = tvpaths[0];
else pathname = tvpaths[1]; */ else pathname = tvpaths[1]; */
memfilename = {pathname, tests[test], ".elf.memfile"}; memfilename = {pathname, tests[test], ".elf.memfile"};
if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM);
else $readmemh(memfilename, dut.uncore.ram.ram.RAM); else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM);
if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM);
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
@ -243,14 +244,15 @@ logic [3:0] dummy;
errors = (i == SIGNATURESIZE+1); // error if file is empty errors = (i == SIGNATURESIZE+1); // error if file is empty
i = 0; i = 0;
testadr = (`RAM_BASE+tests[test+1].atohex())/(`XLEN/8); testadr = (`RAM_BASE+tests[test+1].atohex())/(`XLEN/8);
testadrNoBase = (tests[test+1].atohex())/(`XLEN/8);
/* verilator lint_off INFINITELOOP */ /* verilator lint_off INFINITELOOP */
while (signature[i] !== 'bx) begin while (signature[i] !== 'bx) begin
logic [`XLEN-1:0] sig; logic [`XLEN-1:0] sig;
if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.RAM[testadr+i]; if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.memory.RAM[testadrNoBase+i];
else sig = dut.uncore.ram.ram.RAM[testadr+i]; else sig = dut.uncore.ram.ram.memory.RAM[testadrNoBase+i];
// $display("signature[%h] = %h sig = %h", i, signature[i], sig); //$display("signature[%h] = %h sig = %h", i, signature[i], sig);
if (signature[i] !== sig & if (signature[i] !== sig &
//if (signature[i] !== dut.core.lsu.dtim.ram.RAM[testadr+i] & //if (signature[i] !== dut.core.lsu.dtim.ram.memory.RAM[testadr+i] &
(signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin // ***i+1? (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin // ***i+1?
if ((signature[i] !== '0 | signature[i+4] !== 'x)) begin if ((signature[i] !== '0 | signature[i+4] !== 'x)) begin
// if (signature[i+4] !== 'bx | (signature[i] !== 32'hFFFFFFFF & signature[i] !== 32'h00000000)) begin // if (signature[i+4] !== 'bx | (signature[i] !== 32'hFFFFFFFF & signature[i] !== 32'h00000000)) begin
@ -260,7 +262,7 @@ logic [3:0] dummy;
errors = errors+1; errors = errors+1;
$display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DMEM) = %h, signature = %h", $display(" Error on test %s result %d: adr = %h sim (D$) %h sim (DMEM) = %h, signature = %h",
tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]); tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], sig, signature[i]);
// tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.ram.RAM[testadr+i], signature[i]); // tests[test], i, (testadr+i)*(`XLEN/8), DCacheFlushFSM.ShadowRAM[testadr+i], dut.core.lsu.dtim.ram.memory.RAM[testadr+i], signature[i]);
$stop;//***debug $stop;//***debug
end end
end end
@ -283,10 +285,10 @@ logic [3:0] dummy;
else begin else begin
//pathname = tvpaths[tests[0]]; //pathname = tvpaths[tests[0]];
memfilename = {pathname, tests[test], ".elf.memfile"}; memfilename = {pathname, tests[test], ".elf.memfile"};
//$readmemh(memfilename, dut.uncore.ram.ram.RAM); //$readmemh(memfilename, dut.uncore.ram.ram.memory.RAM);
if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM); if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM);
else $readmemh(memfilename, dut.uncore.ram.ram.RAM); else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM);
if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM); if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM);
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"}; ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"}; ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};

View File

@ -959,7 +959,7 @@ string imperas32f[] = '{
"rv64i_m/I/andi-01", "6010", "rv64i_m/I/andi-01", "6010",
"rv64i_m/I/auipc-01", "2010", "rv64i_m/I/auipc-01", "2010",
"rv64i_m/I/beq-01", "47010", "rv64i_m/I/beq-01", "47010",
"rv64i_m/I/bge-01", "47010", "rv64i_m/I/bge-01", "46010",
"rv64i_m/I/bgeu-01", "56010", "rv64i_m/I/bgeu-01", "56010",
"rv64i_m/I/blt-01", "4d010", "rv64i_m/I/blt-01", "4d010",
"rv64i_m/I/bltu-01", "57010", "rv64i_m/I/bltu-01", "57010",
@ -1479,7 +1479,7 @@ string imperas32f[] = '{
string wally64periph[] = '{ string wally64periph[] = '{
`WALLYTEST, `WALLYTEST,
"rv64i_m/privilege/WALLY-PERIPH", "22f0" "rv64i_m/privilege/WALLY-PERIPH", "3310"
}; };
string wally32e[] = '{ string wally32e[] = '{

View File

@ -50,10 +50,47 @@
// Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries) // Number of 64 bit PMP Configuration Register entries (or pairs of 32 bit entries)
`define PMPCFG_ENTRIES (`PMP_ENTRIES/8) `define PMPCFG_ENTRIES (`PMP_ENTRIES/8)
// Floating-point half-precision
`define ZFH_SUPPORTED 0
// Floating point constants for Quad, Double, Single, and Half precisions
`define Q_LEN 128
`define Q_NE 15
`define Q_NF 112
`define Q_BIAS 16383
`define D_LEN 64
`define D_NE 11
`define D_NF 52
`define D_BIAS 1023
`define S_LEN 32
`define S_NE 8
`define S_NF 23
`define S_BIAS 127
`define H_LEN 16
`define H_NE 5
`define H_NF 10
`define H_BIAS 15
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
`define FLEN 64//(`Q_SUPPORTED ? 128 : `D_SUPPORTED ? 64 : 32) `define FLEN (`Q_SUPPORTED ? `Q_LEN : `D_SUPPORTED ? `D_LEN : `F_SUPPORTED ? `S_LEN : `H_LEN)
`define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8) `define NE (`Q_SUPPORTED ? `Q_NE : `D_SUPPORTED ? `D_NE : `F_SUPPORTED ? `S_NE : `H_NE)
`define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23) `define NF (`Q_SUPPORTED ? `Q_NF : `D_SUPPORTED ? `D_NF : `F_SUPPORTED ? `S_NF : `H_NF)
`define FMT (`Q_SUPPORTED ? 3 : `D_SUPPORTED ? 1 : `F_SUPPORTED ? 0 : 2)
`define BIAS (`Q_SUPPORTED ? `Q_BIAS : `D_SUPPORTED ? `D_BIAS : `F_SUPPORTED ? `S_BIAS : `H_BIAS)
// Floating point constants needed for FPU paramerterization
`define FPSIZES (`Q_SUPPORTED+`D_SUPPORTED+`F_SUPPORTED+`ZFH_SUPPORTED)
`define LEN1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_LEN : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_LEN : `H_LEN)
`define NE1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NE : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NE : `H_NE)
`define NF1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_NF : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_NF : `H_NF)
`define FMT1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? 1 : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? 0 : 2)
`define BIAS1 ((`D_SUPPORTED & (`FLEN != `D_LEN)) ? `D_BIAS : (`F_SUPPORTED & (`FLEN != `S_LEN)) ? `S_BIAS : `H_BIAS)
`define LEN2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_LEN : `H_LEN)
`define NE2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NE : `H_NE)
`define NF2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_NF : `H_NF)
`define FMT2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? 0 : 2)
`define BIAS2 ((`F_SUPPORTED & (`LEN1 != `S_LEN)) ? `S_BIAS : `H_BIAS)
// Disable spurious Verilator warnings // Disable spurious Verilator warnings