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

This commit is contained in:
Ross Thompson 2022-03-31 16:30:55 -05:00
commit 1586f893b1
30 changed files with 462 additions and 291 deletions

View File

@ -41,7 +41,7 @@ connect_debug_port u_ila_0/probe5 [get_nets [list {wallypipelinedsoc/core/ReadDa
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 64 [get_debug_ports u_ila_0/probe6] set_property port_width 64 [get_debug_ports u_ila_0/probe6]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6]
connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/WriteDataM[0]} {wallypipelinedsoc/core/WriteDataM[1]} {wallypipelinedsoc/core/WriteDataM[2]} {wallypipelinedsoc/core/WriteDataM[3]} {wallypipelinedsoc/core/WriteDataM[4]} {wallypipelinedsoc/core/WriteDataM[5]} {wallypipelinedsoc/core/WriteDataM[6]} {wallypipelinedsoc/core/WriteDataM[7]} {wallypipelinedsoc/core/WriteDataM[8]} {wallypipelinedsoc/core/WriteDataM[9]} {wallypipelinedsoc/core/WriteDataM[10]} {wallypipelinedsoc/core/WriteDataM[11]} {wallypipelinedsoc/core/WriteDataM[12]} {wallypipelinedsoc/core/WriteDataM[13]} {wallypipelinedsoc/core/WriteDataM[14]} {wallypipelinedsoc/core/WriteDataM[15]} {wallypipelinedsoc/core/WriteDataM[16]} {wallypipelinedsoc/core/WriteDataM[17]} {wallypipelinedsoc/core/WriteDataM[18]} {wallypipelinedsoc/core/WriteDataM[19]} {wallypipelinedsoc/core/WriteDataM[20]} {wallypipelinedsoc/core/WriteDataM[21]} {wallypipelinedsoc/core/WriteDataM[22]} {wallypipelinedsoc/core/WriteDataM[23]} {wallypipelinedsoc/core/WriteDataM[24]} {wallypipelinedsoc/core/WriteDataM[25]} {wallypipelinedsoc/core/WriteDataM[26]} {wallypipelinedsoc/core/WriteDataM[27]} {wallypipelinedsoc/core/WriteDataM[28]} {wallypipelinedsoc/core/WriteDataM[29]} {wallypipelinedsoc/core/WriteDataM[30]} {wallypipelinedsoc/core/WriteDataM[31]} {wallypipelinedsoc/core/WriteDataM[32]} {wallypipelinedsoc/core/WriteDataM[33]} {wallypipelinedsoc/core/WriteDataM[34]} {wallypipelinedsoc/core/WriteDataM[35]} {wallypipelinedsoc/core/WriteDataM[36]} {wallypipelinedsoc/core/WriteDataM[37]} {wallypipelinedsoc/core/WriteDataM[38]} {wallypipelinedsoc/core/WriteDataM[39]} {wallypipelinedsoc/core/WriteDataM[40]} {wallypipelinedsoc/core/WriteDataM[41]} {wallypipelinedsoc/core/WriteDataM[42]} {wallypipelinedsoc/core/WriteDataM[43]} {wallypipelinedsoc/core/WriteDataM[44]} {wallypipelinedsoc/core/WriteDataM[45]} {wallypipelinedsoc/core/WriteDataM[46]} {wallypipelinedsoc/core/WriteDataM[47]} {wallypipelinedsoc/core/WriteDataM[48]} {wallypipelinedsoc/core/WriteDataM[49]} {wallypipelinedsoc/core/WriteDataM[50]} {wallypipelinedsoc/core/WriteDataM[51]} {wallypipelinedsoc/core/WriteDataM[52]} {wallypipelinedsoc/core/WriteDataM[53]} {wallypipelinedsoc/core/WriteDataM[54]} {wallypipelinedsoc/core/WriteDataM[55]} {wallypipelinedsoc/core/WriteDataM[56]} {wallypipelinedsoc/core/WriteDataM[57]} {wallypipelinedsoc/core/WriteDataM[58]} {wallypipelinedsoc/core/WriteDataM[59]} {wallypipelinedsoc/core/WriteDataM[60]} {wallypipelinedsoc/core/WriteDataM[61]} {wallypipelinedsoc/core/WriteDataM[62]} {wallypipelinedsoc/core/WriteDataM[63]} ]] connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/lsu/WriteDataM[0]} {wallypipelinedsoc/core/lsu/WriteDataM[1]} {wallypipelinedsoc/core/lsu/WriteDataM[2]} {wallypipelinedsoc/core/lsu/WriteDataM[3]} {wallypipelinedsoc/core/lsu/WriteDataM[4]} {wallypipelinedsoc/core/lsu/WriteDataM[5]} {wallypipelinedsoc/core/lsu/WriteDataM[6]} {wallypipelinedsoc/core/lsu/WriteDataM[7]} {wallypipelinedsoc/core/lsu/WriteDataM[8]} {wallypipelinedsoc/core/lsu/WriteDataM[9]} {wallypipelinedsoc/core/lsu/WriteDataM[10]} {wallypipelinedsoc/core/lsu/WriteDataM[11]} {wallypipelinedsoc/core/lsu/WriteDataM[12]} {wallypipelinedsoc/core/lsu/WriteDataM[13]} {wallypipelinedsoc/core/lsu/WriteDataM[14]} {wallypipelinedsoc/core/lsu/WriteDataM[15]} {wallypipelinedsoc/core/lsu/WriteDataM[16]} {wallypipelinedsoc/core/lsu/WriteDataM[17]} {wallypipelinedsoc/core/lsu/WriteDataM[18]} {wallypipelinedsoc/core/lsu/WriteDataM[19]} {wallypipelinedsoc/core/lsu/WriteDataM[20]} {wallypipelinedsoc/core/lsu/WriteDataM[21]} {wallypipelinedsoc/core/lsu/WriteDataM[22]} {wallypipelinedsoc/core/lsu/WriteDataM[23]} {wallypipelinedsoc/core/lsu/WriteDataM[24]} {wallypipelinedsoc/core/lsu/WriteDataM[25]} {wallypipelinedsoc/core/lsu/WriteDataM[26]} {wallypipelinedsoc/core/lsu/WriteDataM[27]} {wallypipelinedsoc/core/lsu/WriteDataM[28]} {wallypipelinedsoc/core/lsu/WriteDataM[29]} {wallypipelinedsoc/core/lsu/WriteDataM[30]} {wallypipelinedsoc/core/lsu/WriteDataM[31]} {wallypipelinedsoc/core/lsu/WriteDataM[32]} {wallypipelinedsoc/core/lsu/WriteDataM[33]} {wallypipelinedsoc/core/lsu/WriteDataM[34]} {wallypipelinedsoc/core/lsu/WriteDataM[35]} {wallypipelinedsoc/core/lsu/WriteDataM[36]} {wallypipelinedsoc/core/lsu/WriteDataM[37]} {wallypipelinedsoc/core/lsu/WriteDataM[38]} {wallypipelinedsoc/core/lsu/WriteDataM[39]} {wallypipelinedsoc/core/lsu/WriteDataM[40]} {wallypipelinedsoc/core/lsu/WriteDataM[41]} {wallypipelinedsoc/core/lsu/WriteDataM[42]} {wallypipelinedsoc/core/lsu/WriteDataM[43]} {wallypipelinedsoc/core/lsu/WriteDataM[44]} {wallypipelinedsoc/core/lsu/WriteDataM[45]} {wallypipelinedsoc/core/lsu/WriteDataM[46]} {wallypipelinedsoc/core/lsu/WriteDataM[47]} {wallypipelinedsoc/core/lsu/WriteDataM[48]} {wallypipelinedsoc/core/lsu/WriteDataM[49]} {wallypipelinedsoc/core/lsu/WriteDataM[50]} {wallypipelinedsoc/core/lsu/WriteDataM[51]} {wallypipelinedsoc/core/lsu/WriteDataM[52]} {wallypipelinedsoc/core/lsu/WriteDataM[53]} {wallypipelinedsoc/core/lsu/WriteDataM[54]} {wallypipelinedsoc/core/lsu/WriteDataM[55]} {wallypipelinedsoc/core/lsu/WriteDataM[56]} {wallypipelinedsoc/core/lsu/WriteDataM[57]} {wallypipelinedsoc/core/lsu/WriteDataM[58]} {wallypipelinedsoc/core/lsu/WriteDataM[59]} {wallypipelinedsoc/core/lsu/WriteDataM[60]} {wallypipelinedsoc/core/lsu/WriteDataM[61]} {wallypipelinedsoc/core/lsu/WriteDataM[62]} {wallypipelinedsoc/core/lsu/WriteDataM[63]} ]]
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 64 [get_debug_ports u_ila_0/probe7] set_property port_width 64 [get_debug_ports u_ila_0/probe7]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7]
@ -122,7 +122,7 @@ connect_debug_port u_ila_0/probe25 [get_nets [list {wallypipelinedsoc/uncore/sdc
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 12 [get_debug_ports u_ila_0/probe26] set_property port_width 12 [get_debug_ports u_ila_0/probe26]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe26] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe26]
connect_debug_port u_ila_0/probe26 [get_nets [list {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[0]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[1]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[2]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[3]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[4]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[5]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[6]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[7]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[8]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[9]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[10]} {wallypipelinedsoc/core/priv.priv/trap/PendingIntsM[11]} ]] connect_debug_port u_ila_0/probe26 [get_nets [list {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[0]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[1]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[2]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[3]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[4]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[5]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[6]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[7]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[8]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[9]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[10]} {wallypipelinedsoc/core/priv.priv/trap/MPendingIntsM[11]} ]]
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 64 [get_debug_ports u_ila_0/probe27] set_property port_width 64 [get_debug_ports u_ila_0/probe27]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe27] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe27]
@ -155,6 +155,7 @@ create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe34] set_property port_width 1 [get_debug_ports u_ila_0/probe34]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe34] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe34]
connect_debug_port u_ila_0/probe34 [get_nets [list wallypipelinedsoc/core/lsu/LSUBusWrite ]] connect_debug_port u_ila_0/probe34 [get_nets [list wallypipelinedsoc/core/lsu/LSUBusWrite ]]
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe35] set_property port_width 1 [get_debug_ports u_ila_0/probe35]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe35] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe35]
@ -195,10 +196,12 @@ create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe44] set_property port_width 1 [get_debug_ports u_ila_0/probe44]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe44] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe44]
connect_debug_port u_ila_0/probe44 [get_nets [list wallypipelinedsoc/core/priv.priv/trap/InstrPageFaultM ]] connect_debug_port u_ila_0/probe44 [get_nets [list wallypipelinedsoc/core/priv.priv/trap/InstrPageFaultM ]]
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe45] set_property port_width 1 [get_debug_ports u_ila_0/probe45]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe45] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe45]
connect_debug_port u_ila_0/probe45 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] connect_debug_port u_ila_0/probe45 [get_nets [list wallypipelinedsoc/core/InstrValidM ]]
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe46] set_property port_width 1 [get_debug_ports u_ila_0/probe46]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe46] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe46]
@ -553,9 +556,9 @@ set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe119]
connect_debug_port u_ila_0/probe119 [get_nets [list wallypipelinedsoc/core/lsu/DTLBWriteM]] connect_debug_port u_ila_0/probe119 [get_nets [list wallypipelinedsoc/core/lsu/DTLBWriteM]]
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe
set_property port_width 11 [get_debug_ports u_ila_0/probe120] set_property port_width 4 [get_debug_ports u_ila_0/probe120]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe120] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe120]
connect_debug_port u_ila_0/probe120 [get_nets [list {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[0]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[1]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[2]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[3]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[4]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[5]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[6]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[7]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[8]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[9]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[10]}]] connect_debug_port u_ila_0/probe120 [get_nets [list {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[0]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[1]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[2]} {wallypipelinedsoc/core/lsu/VIRTMEM_SUPPORTED.lsuvirtmem/hptw/WalkerState[3]}]]
create_debug_port u_ila_0 probe create_debug_port u_ila_0 probe

View File

@ -0,0 +1,42 @@
94e1819300002197
4281420141014081
4481440143814301
4681460145814501
4881480147814701
4a814a0149814901
4c814c014b814b01
4e814e014d814d01
0110011b4f814f01
059b45011161016e
0004063705fe0010
05a000ef8006061b
0ff003930000100f
4e952e3110060e37
c602829b0053f2b7
2023fe02dfe312fd
829b0053f2b7007e
fe02dfe312fdc602
4de31efd000e2023
059bf1402573fdd0
0000061705e20870
0010029b01260613
11010002806702fe
84b2842ae426e822
892ee04aec064505
06e000ef07e000ef
979334fd02905563
07930177d4930204
4089093394be2004
04138522008905b3
19e3014000ef2004
64a2644260e2fe94
6749808261056902
dfed8b8510472783
2423479110a73823
10472783674910f7
20058693ffed8b89
05a1118737836749
fed59be3fef5bc23
1047278367498082
67c98082dfed8b85
0000808210a7a023

View File

@ -52,6 +52,9 @@ report_utilization -hierarchical -file re
report_cdc -file reports/cdc.rpt report_cdc -file reports/cdc.rpt
report_clock_interaction -file reports/clock_interaction.rpt report_clock_interaction -file reports/clock_interaction.rpt
write_verilog -force -mode funcsim sim/syn-funcsim.v
source ../constraints/debug2.xdc source ../constraints/debug2.xdc

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

@ -8,7 +8,7 @@ onbreak {resume}
# create library # create library
vlib worklib vlib worklib
vlog -lint -work worklib fma16.sv testbench.v vlog -lint -sv -work worklib fma16.v testbench.v
vopt +acc worklib.testbench_fma16 -work worklib -o testbenchopt vopt +acc worklib.testbench_fma16 -work worklib -o testbenchopt
vsim -lib worklib testbenchopt vsim -lib worklib testbenchopt

View File

@ -5,4 +5,4 @@ export PATH=$PATH:/usr/local/bin/
verilator=`which verilator` verilator=`which verilator`
basepath=$(dirname $0)/.. basepath=$(dirname $0)/..
$verilator --lint-only --top-module fma16 fma16.sv $verilator --lint-only --top-module fma16 fma16.v

1
pipelined/src/fma/synth Executable file
View File

@ -0,0 +1 @@
make -C ../../../synthDC synth DESIGN=fma16

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,96 @@
///////////////////////////////////////////
// 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
);
// *** TODO.
/* -----\/----- EXCLUDED -----\/-----
if(`SRAM) begin
// instanciate SRAM model
// need multiple SRAM instances to map into correct dimentions.
// also map the byte write enables onto bit write enables.
end else begin // FPGA or infered flip flop memory
// Core Memory
end
-----/\----- EXCLUDED -----/\----- */
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

@ -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

@ -37,7 +37,6 @@ module adrdecs (
input logic [1:0] Size, input logic [1:0] Size,
output logic [8:0] SelRegions output logic [8:0] SelRegions
); );
logic [3:0] clintaccesssize;
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
// *** eventually uncomment Access signals // *** eventually uncomment Access signals
@ -45,8 +44,7 @@ module adrdecs (
adrdec boottimdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[6]); adrdec boottimdec(PhysicalAddress, `BOOTROM_BASE, `BOOTROM_RANGE, `BOOTROM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[6]);
adrdec timdec(PhysicalAddress, `RAM_BASE, `RAM_RANGE, `RAM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[5]); adrdec timdec(PhysicalAddress, `RAM_BASE, `RAM_RANGE, `RAM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[5]);
assign clintaccesssize = (`XLEN==64) ? 4'b1000 : 4'b0100; adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[4]);
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, clintaccesssize, SelRegions[4]);
adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]); adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]);
adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]); adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]);
adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]); adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]);

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,1'b0, IntInM[7], 7'b0} | {2'b0, IP_REGW_writeable[9], 3'b0, IP_REGW_writeable[5], 3'b0, IP_REGW_writeable[1], 1'b0}; // *** This is just to force the Machine level bits of IP to be unwriteable and to only come from intInM. PLEASE CHANGE ME!!!
// 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.
@ -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

@ -35,6 +35,7 @@ module clint (
input logic HCLK, HRESETn, TIMECLK, input logic HCLK, HRESETn, TIMECLK,
input logic HSELCLINT, input logic HSELCLINT,
input logic [15:0] HADDR, input logic [15:0] HADDR,
input logic [3:0] HSIZED,
input logic HWRITE, input logic HWRITE,
input logic [`XLEN-1:0] HWDATA, input logic [`XLEN-1:0] HWDATA,
input logic HREADY, input logic HREADY,
@ -50,6 +51,8 @@ module clint (
logic memwrite; logic memwrite;
logic initTrans; logic initTrans;
logic [63:0] MTIMECMP; logic [63:0] MTIMECMP;
logic [`XLEN/8-1:0] ByteMaskM;
integer i;
assign initTrans = HREADY & HSELCLINT & (HTRANS != 2'b00); assign initTrans = HREADY & HSELCLINT & (HTRANS != 2'b00);
// entryd and memwrite are delayed by a cycle because AHB controller waits a cycle before outputting write data // entryd and memwrite are delayed by a cycle because AHB controller waits a cycle before outputting write data
@ -63,6 +66,9 @@ module clint (
if (`XLEN==64) assign #2 entry = {HADDR[15:3], 3'b000}; if (`XLEN==64) assign #2 entry = {HADDR[15:3], 3'b000};
else assign #2 entry = {HADDR[15:2], 2'b00}; else assign #2 entry = {HADDR[15:2], 2'b00};
swbytemask swbytemask(.HSIZED, .HADDRD(entryd[2:0]), .ByteMask(ByteMaskM));
// DH 2/20/21: Eventually allow MTIME to run off a separate clock // DH 2/20/21: Eventually allow MTIME to run off a separate clock
// This will require synchronizing MTIME to the system clock // This will require synchronizing MTIME to the system clock
// before it is read or compared to MTIMECMP. // before it is read or compared to MTIMECMP.
@ -86,7 +92,11 @@ module clint (
// MTIMECMP is not reset // MTIMECMP is not reset
end else if (memwrite) begin end else if (memwrite) begin
if (entryd == 16'h0000) MSIP <= HWDATA[0]; if (entryd == 16'h0000) MSIP <= HWDATA[0];
if (entryd == 16'h4000) MTIMECMP <= HWDATA; if (entryd == 16'h4000) begin
for(i=0;i<`XLEN/8;i++)
if(ByteMaskM[i])
MTIMECMP[i*8 +: 8] <= HWDATA[i*8 +: 8];
end
end end
// eventually replace MTIME logic below with timereg // eventually replace MTIME logic below with timereg
@ -98,7 +108,9 @@ module clint (
// MTIMECMP is not reset // MTIMECMP is not reset
end else if (memwrite & entryd == 16'hBFF8) begin end else if (memwrite & entryd == 16'hBFF8) begin
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
MTIME <= HWDATA; for(i=0;i<`XLEN/8;i++)
if(ByteMaskM[i])
MTIME[i*8 +: 8] <= HWDATA[i*8 +: 8];
end else MTIME <= MTIME + 1; end else MTIME <= MTIME + 1;
end else begin:clint // 32-bit end else begin:clint // 32-bit
always @(posedge HCLK) begin always @(posedge HCLK) begin
@ -118,8 +130,14 @@ module clint (
// MTIMECMP is not reset ***? // MTIMECMP is not reset ***?
end else if (memwrite) begin end else if (memwrite) begin
if (entryd == 16'h0000) MSIP <= HWDATA[0]; if (entryd == 16'h0000) MSIP <= HWDATA[0];
if (entryd == 16'h4000) MTIMECMP[31:0] <= HWDATA; if (entryd == 16'h4000)
if (entryd == 16'h4004) MTIMECMP[63:32] <= HWDATA; for(i=0;i<`XLEN/8;i++)
if(ByteMaskM[i])
MTIMECMP[i*8 +: 8] <= HWDATA[i*8 +: 8];
if (entryd == 16'h4004)
for(i=0;i<`XLEN/8;i++)
if(ByteMaskM[i])
MTIMECMP[32 + i*8 +: 8] <= HWDATA[i*8 +: 8];
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
end end
@ -130,10 +148,14 @@ module clint (
MTIME <= 0; MTIME <= 0;
// MTIMECMP is not reset // MTIMECMP is not reset
end else if (memwrite & (entryd == 16'hBFF8)) begin end else if (memwrite & (entryd == 16'hBFF8)) begin
MTIME[31:0] <= HWDATA; for(i=0;i<`XLEN/8;i++)
if(ByteMaskM[i])
MTIME[i*8 +: 8] <= HWDATA[i*8 +: 8];
end else if (memwrite & (entryd == 16'hBFFC)) begin end else if (memwrite & (entryd == 16'hBFFC)) begin
// MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed // MTIME Counter. Eventually change this to run off separate clock. Synchronization then needed
MTIME[63:32]<= HWDATA; for(i=0;i<`XLEN/8;i++)
if(ByteMaskM[i])
MTIME[32 + i*8 +: 8]<= HWDATA[i*8 +: 8];
end else MTIME <= MTIME + 1; end else MTIME <= MTIME + 1;
end end

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;
@ -176,11 +176,7 @@ module plic (
end end
// pending interrupt requests // pending interrupt requests
assign nextIntPending = assign nextIntPending = (intPending | requests) & ~intInProgress;
(intPending | // existing pending requests
(requests & ~intInProgress)) & // assert new requests (if they aren't already being serviced)
~({`N{((entry == 24'h200004) & memread)}} << (intClaim[0]-1)) & // deassert requests that just completed
~({`N{((entry == 24'h201004) & memread)}} << (intClaim[1]-1));
flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending); flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
// context-dependent signals // context-dependent signals
@ -253,10 +249,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,85 +43,28 @@ module ram #(parameter BASE=0, RANGE = 65535) (
output logic HRESPRam, HREADYRam output logic HRESPRam, HREADYRam
); );
// Desired changes. // Desired changes.
// 1. find a way to merge read and write address into 1 port. // 1. find a way to merge read and write address into 1 port.
// 2. remove all unnecessary latencies. (HREADY needs to be able to constant high.) // 2. remove all unnecessary latencies. (HREADY needs to be able to constant high.)
// 3. implement burst. // 3. implement burst.
// 4. remove the configurable latency. // 4. remove the configurable latency.
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[0] = 64'h94e1819300002197;
RAM[1] = 64'h4281420141014081;
RAM[2] = 64'h4481440143814301;
RAM[3] = 64'h4681460145814501;
RAM[4] = 64'h4881480147814701;
RAM[5] = 64'h4a814a0149814901;
RAM[6] = 64'h4c814c014b814b01;
RAM[7] = 64'h4e814e014d814d01;
RAM[8] = 64'h0110011b4f814f01;
RAM[9] = 64'h059b45011161016e;
RAM[10] = 64'h0004063705fe0010;
RAM[11] = 64'h05a000ef8006061b;
RAM[12] = 64'h0ff003930000100f;
RAM[13] = 64'h4e952e3110060e37;
RAM[14] = 64'hc602829b0053f2b7;
RAM[15] = 64'h2023fe02dfe312fd;
RAM[16] = 64'h829b0053f2b7007e;
RAM[17] = 64'hfe02dfe312fdc602;
RAM[18] = 64'h4de31efd000e2023;
RAM[19] = 64'h059bf1402573fdd0;
RAM[20] = 64'h0000061705e20870;
RAM[21] = 64'h0010029b01260613;
RAM[22] = 64'h11010002806702fe;
RAM[23] = 64'h84b2842ae426e822;
RAM[24] = 64'h892ee04aec064505;
RAM[25] = 64'h06e000ef07e000ef;
RAM[26] = 64'h979334fd02905563;
RAM[27] = 64'h07930177d4930204;
RAM[28] = 64'h4089093394be2004;
RAM[29] = 64'h04138522008905b3;
RAM[30] = 64'h19e3014000ef2004;
RAM[31] = 64'h64a2644260e2fe94;
RAM[32] = 64'h6749808261056902;
RAM[33] = 64'hdfed8b8510472783;
RAM[34] = 64'h2423479110a73823;
RAM[35] = 64'h10472783674910f7;
RAM[36] = 64'h20058693ffed8b89;
RAM[37] = 64'h05a1118737836749;
RAM[38] = 64'hfed59be3fef5bc23;
RAM[39] = 64'h1047278367498082;
RAM[40] = 64'h67c98082dfed8b85;
RAM[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;
@ -138,47 +81,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,
@ -116,7 +116,7 @@ module uncore (
clint clint( clint clint(
.HCLK, .HRESETn, .TIMECLK, .HCLK, .HRESETn, .TIMECLK,
.HSELCLINT, .HADDR(HADDR[15:0]), .HWRITE, .HSELCLINT, .HADDR(HADDR[15:0]), .HWRITE,
.HWDATA, .HREADY, .HTRANS, .HWDATA, .HREADY, .HTRANS, .HSIZED,
.HREADCLINT, .HREADCLINT,
.HRESPCLINT, .HREADYCLINT, .HRESPCLINT, .HREADYCLINT,
.MTIME(MTIME_CLINT), .MTIME(MTIME_CLINT),
@ -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,
@ -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

@ -28,6 +28,9 @@ eval file copy -force [glob ${hdl_src}/../config/shared/*.vh] {hdl/}
eval file copy -force [glob ${hdl_src}/*/*.sv] {hdl/} eval file copy -force [glob ${hdl_src}/*/*.sv] {hdl/}
eval file copy -force [glob ${hdl_src}/*/flop/*.sv] {hdl/} eval file copy -force [glob ${hdl_src}/*/flop/*.sv] {hdl/}
# Only for FMA class project; comment out when done
eval file copy -force [glob ${hdl_src}/fma/fma16.v] {hdl/}
# Enables name mapping # Enables name mapping
if { $saifpower == 1 } { if { $saifpower == 1 } {
saif_map -start saif_map -start