mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
07eba7df45
Binary file not shown.
@ -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
|
@ -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
|
||||||
|
@ -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(
|
||||||
|
15
pipelined/src/cache/sram1p1rw.sv
vendored
15
pipelined/src/cache/sram1p1rw.sv
vendored
@ -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
|
||||||
|
@ -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
|
||||||
|
71
pipelined/src/generic/flop/bram1p1rw.sv
Normal file
71
pipelined/src/generic/flop/bram1p1rw.sv
Normal 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
|
82
pipelined/src/generic/flop/bram2p1r1w.sv
Normal file
82
pipelined/src/generic/flop/bram2p1r1w.sv
Normal 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
|
@ -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
|
||||||
|
|
||||||
|
@ -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),
|
||||||
|
@ -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),
|
||||||
|
@ -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 ***
|
||||||
|
@ -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),
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
@ -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];
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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"};
|
||||||
|
@ -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[] = '{
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user