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 da93d14050
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
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]
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
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]
@ -122,7 +122,7 @@ connect_debug_port u_ila_0/probe25 [get_nets [list {wallypipelinedsoc/uncore/sdc
create_debug_port u_ila_0 probe
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]
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
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]
@ -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 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 ]]
create_debug_port u_ila_0 probe
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]
@ -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 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 ]]
create_debug_port u_ila_0 probe
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]
connect_debug_port u_ila_0/probe45 [get_nets [list wallypipelinedsoc/core/InstrValidM ]]
create_debug_port u_ila_0 probe
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]
@ -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]]
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]
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

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_clock_interaction -file reports/clock_interaction.rpt
write_verilog -force -mode funcsim sim/syn-funcsim.v
source ../constraints/debug2.xdc

View File

@ -47,7 +47,8 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) (
always_ff @(posedge clk) AdrD <= Adr;
genvar index;
integer index;
/* -----\/----- EXCLUDED -----\/-----
for(index = 0; index < WIDTH/8; index++) begin
always_ff @(posedge clk) begin
if (WriteEnable & ByteMask[index]) begin
@ -55,6 +56,18 @@ module sram1p1rw #(parameter DEPTH=128, WIDTH=256) (
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(WIDTH%8 != 0) begin
always_ff @(posedge clk) begin

View File

@ -8,7 +8,7 @@ onbreak {resume}
# create library
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
vsim -lib worklib testbenchopt

View File

@ -5,4 +5,4 @@ export PATH=$PATH:/usr/local/bin/
verilator=`which verilator`
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
);
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)];
// 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];
end
end
-----/\----- EXCLUDED -----/\----- */
endmodule

View File

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

View File

@ -48,7 +48,7 @@ module dtim(
output logic DCacheCommittedM,
output logic DCacheMiss,
output logic DCacheAccess);
simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.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 ***

View File

@ -91,7 +91,7 @@ module lsu (
logic [2:0] LSUFunct3M;
logic [6:0] LSUFunct7M;
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 CPUBusy;
logic DCacheStallM;
@ -132,7 +132,7 @@ module lsu (
assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF, IgnoreRequestTLB} = '0;
assign IgnoreRequestTrapM = TrapM; assign CPUBusy = StallW; assign PreLSURWM = MemRWM;
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 LSUWriteDataM = WriteDataM;
end
@ -151,8 +151,7 @@ module lsu (
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .DisableTranslation,
.PAdr(PreLSUPAdrM),
.VAdr(IEUAdrM),
.VAdr(PreLSUPAdrM),
.Size(LSUFunct3M[1:0]),
.PTE,
.PageTypeWriteVal(PageType),

View File

@ -59,7 +59,7 @@ module lsuvirtmem(
output logic [1:0] PreLSURWM,
output logic [1:0] LSUAtomicM,
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.
output logic InterlockStall,
@ -71,13 +71,15 @@ module lsuvirtmem(
logic AnyCPUReqM;
logic [`PA_BITS-1:0] HPTWAdr;
logic [`XLEN+1:0] HPTWAdrExt;
logic [1:0] HPTWRW;
logic [2:0] HPTWSize;
logic SelReplayMemE;
logic [11:0] PreLSUAdrE;
logic ITLBMissOrDAFaultF, ITLBMissOrDAFaultNoTrapF;
logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM;
logic DTLBMissOrDAFaultM, DTLBMissOrDAFaultNoTrapM;
logic SelHPTWAdr;
assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF);
assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);
assign ITLBMissOrDAFaultNoTrapF = ITLBMissOrDAFaultF & ~TrapM;
@ -94,13 +96,22 @@ module lsuvirtmem(
.DCacheStallM, .HPTWAdr, .HPTWRW, .HPTWSize);
// *** 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
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 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M);
mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M);
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM);
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)
mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, LSUWriteDataM);
else assign LSUWriteDataM = WriteDataM;

View File

@ -37,7 +37,6 @@ module adrdecs (
input logic [1:0] Size,
output logic [8:0] SelRegions
);
logic [3:0] clintaccesssize;
// Determine which region of physical memory (if any) is being accessed
// *** 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 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, clintaccesssize, SelRegions[4]);
adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[4]);
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 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
input logic DisableTranslation,
// VAdr goes to the TLB only. Virtual if the TLB is active.
// 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.
// VAdr is the virtual/physical address from IEU or physical address from HPTW.
// PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr)
// 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
// 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,
.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]),
.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,
.DisableTranslation, .PTE, .PageTypeWriteVal,
.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
// non translated address.
//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]);
assign PhysicalAddress[11:0] = PAdr[11:0];
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] = VAdr[11:0];
///////////////////////////////////////////

View File

@ -43,7 +43,7 @@ module csr #(parameter
input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM,
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 InstrValidM, FRegWriteM, LoadStallD,
input logic BPPredDirWrongM,
@ -60,9 +60,9 @@ module csr #(parameter
output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR,
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 [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_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW,
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
@ -122,9 +122,10 @@ module csr #(parameter
assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW);
assign CSRUWriteM = CSRWriteM;
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW, .CSRMWriteM, .CSRSWriteM,
.CSRAdrM, .ExtIntM, .ExtIntS, .TimerIntM, .SwIntM,
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
csri csri(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MExtIntM, .SExtIntM, .TimerIntM, .SwIntM,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIDELEG_REGW);
csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteSSTATUSM,
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,

View File

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

View File

@ -33,42 +33,42 @@
`include "wally-config.vh"
module csrm #(parameter
// Machine CSRs
MVENDORID = 12'hF11,
MARCHID = 12'hF12,
MIMPID = 12'hF13,
MHARTID = 12'hF14,
MSTATUS = 12'h300,
MISA_ADR = 12'h301,
MEDELEG = 12'h302,
MIDELEG = 12'h303,
MIE = 12'h304,
MTVEC = 12'h305,
MCOUNTEREN = 12'h306,
MSTATUSH = 12'h310,
MCOUNTINHIBIT = 12'h320,
MSCRATCH = 12'h340,
MEPC = 12'h341,
MCAUSE = 12'h342,
MTVAL = 12'h343,
MIP = 12'h344,
PMPCFG0 = 12'h3A0,
// .. up to 15 more at consecutive addresses
PMPADDR0 = 12'h3B0,
// ... up to 63 more at consecutive addresses
TSELECT = 12'h7A0,
TDATA1 = 12'h7A1,
TDATA2 = 12'h7A2,
TDATA3 = 12'h7A3,
DCSR = 12'h7B0,
DPC = 12'h7B1,
DSCRATCH0 = 12'h7B2,
DSCRATCH1 = 12'h7B3,
// Constants
ZERO = {(`XLEN){1'b0}},
MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11),
MIDELEG_MASK = {{(`XLEN-12){1'b0}}, 12'h222}
) (
// Machine CSRs
MVENDORID = 12'hF11,
MARCHID = 12'hF12,
MIMPID = 12'hF13,
MHARTID = 12'hF14,
MSTATUS = 12'h300,
MISA_ADR = 12'h301,
MEDELEG = 12'h302,
MIDELEG = 12'h303,
MIE = 12'h304,
MTVEC = 12'h305,
MCOUNTEREN = 12'h306,
MSTATUSH = 12'h310,
MCOUNTINHIBIT = 12'h320,
MSCRATCH = 12'h340,
MEPC = 12'h341,
MCAUSE = 12'h342,
MTVAL = 12'h343,
MIP = 12'h344,
PMPCFG0 = 12'h3A0,
// .. up to 15 more at consecutive addresses
PMPADDR0 = 12'h3B0,
// ... up to 63 more at consecutive addresses
TSELECT = 12'h7A0,
TDATA1 = 12'h7A1,
TDATA2 = 12'h7A2,
TDATA3 = 12'h7A3,
DCSR = 12'h7B0,
DPC = 12'h7B1,
DSCRATCH0 = 12'h7B2,
DSCRATCH1 = 12'h7B3,
// Constants
ZERO = {(`XLEN){1'b0}},
MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11),
MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable
) (
input logic clk, reset,
input logic InstrValidNotFlushedM, StallW,
input logic CSRMWriteM, MTrapM,
@ -78,7 +78,8 @@ module csrm #(parameter
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] MEPC_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
//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],
@ -148,7 +149,7 @@ module csrm #(parameter
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
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;
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
MTVEC: CSRMReadValM = MTVEC_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};
MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW};
MSCRATCH: CSRMReadValM = MSCRATCH_REGW;

View File

@ -55,7 +55,7 @@ module privileged (
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
input logic LoadMisalignedFaultM,
input logic StoreAmoMisalignedFaultM,
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
input logic TimerIntM, MExtIntM, SExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT,
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
input logic [4:0] SetFflagsM,
@ -69,7 +69,6 @@ module privileged (
input logic StoreAmoAccessFaultM,
output logic ExceptionM,
output logic PendingInterruptM,
output logic IllegalFPUInstrE,
output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW,
@ -86,7 +85,8 @@ module privileged (
logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
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 IllegalCSRAccessM;
@ -111,7 +111,7 @@ module privileged (
///////////////////////////////////////////
// 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
always_comb begin
@ -150,7 +150,7 @@ module privileged (
.StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
.TimerIntM, .MExtIntM, .SExtIntM, .SwIntM,
.MTIME_CLINT,
.InstrValidM, .FRegWriteM, .LoadStallD,
.BPPredDirWrongM, .BTBPredPCWrongM, .RASPredPCWrongM,
@ -159,9 +159,9 @@ module privileged (
.CauseM, .NextFaultMtvalM, .STATUS_MPP,
.STATUS_SPP, .STATUS_TSR,
.MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW, .MIDELEG_REGW,
.MEDELEG_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_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TW,
.PMPCFG_ARRAY_REGW,
@ -210,7 +210,7 @@ module privileged (
.mretM, .sretM,
.PrivilegeModeW, .NextPrivilegeModeM,
.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,
.PCM,
.InstrMisalignedAdrM, .IEUAdrM,
@ -219,7 +219,6 @@ module privileged (
.TrapM, .MTrapM, .STrapM, .UTrapM, .RetM,
.InterruptM,
.ExceptionM,
.PendingInterruptM,
.PrivilegedNextPCM, .CauseM, .NextFaultMtvalM);
endmodule

View File

@ -41,7 +41,7 @@ module trap (
(* mark_debug = "true" *) input logic mretM, sretM,
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 [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 [`XLEN-1:0] PCM,
input logic [`XLEN-1:0] InstrMisalignedAdrM, IEUAdrM,
@ -50,15 +50,13 @@ module trap (
output logic TrapM, MTrapM, STrapM, UTrapM, RetM,
output logic InterruptM,
output logic ExceptionM,
output logic PendingInterruptM,
output logic [`XLEN-1:0] PrivilegedNextPCM, CauseM, NextFaultMtvalM
// output logic [11:0] MIP_REGW, SIP_REGW, UIP_REGW, MIE_REGW, SIE_REGW, UIE_REGW,
// input logic WriteMIPM, WriteSIPM, WriteUIPM, WriteMIEM, WriteSIEM, WriteUIEM
);
logic MIntGlobalEnM, SIntGlobalEnM;
(* mark_debug = "true" *) logic [11:0] PendingIntsM;
(* mark_debug = "true" *) logic [11:0] MPendingIntsM, SPendingIntsM;
//logic InterruptM;
logic [`XLEN-1:0] PrivilegedTrapVector, PrivilegedVectoredTrapVector;
logic Exception1M;
@ -67,11 +65,13 @@ module trap (
// 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 ~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 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 PendingInterruptM = (|PendingIntsM) & InstrValidM;
assign InterruptM = PendingInterruptM & ~(CommittedM); // *** RT. temporary hack to prevent integer division from having an interrupt during divide.
assign MPendingIntsM = {12{MIntGlobalEnM}} & MIP_REGW & MIE_REGW & ~MIDELEG_REGW;
assign SPendingIntsM = {12{SIntGlobalEnM}} & SIP_REGW & SIE_REGW;
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
// 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)
always_comb
if (reset) CauseM = 0; // hard reset 3.3
else if (PendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
else if (PendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
else if (PendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
else if (PendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int
else if (PendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int
else if (PendingIntsM[5]) CauseM = (1 << (`XLEN-1)) + 5; // Supervisor Timer Int
else if (MPendingIntsM[11]) CauseM = (1 << (`XLEN-1)) + 11; // Machine External Int
else if (MPendingIntsM[3]) CauseM = (1 << (`XLEN-1)) + 3; // Machine Sw Int
else if (MPendingIntsM[7]) CauseM = (1 << (`XLEN-1)) + 7; // Machine Timer Int
else if (MPendingIntsM[9]) CauseM = (1 << (`XLEN-1)) + 9; // Supervisor External Int handled by M-mode
else if (MPendingIntsM[1]) CauseM = (1 << (`XLEN-1)) + 1; // Supervisor Sw Int handled by M-mode
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 (InstrAccessFaultM) CauseM = 1;
else if (InstrMisalignedFaultM) CauseM = 0;

View File

@ -35,6 +35,7 @@ module clint (
input logic HCLK, HRESETn, TIMECLK,
input logic HSELCLINT,
input logic [15:0] HADDR,
input logic [3:0] HSIZED,
input logic HWRITE,
input logic [`XLEN-1:0] HWDATA,
input logic HREADY,
@ -50,6 +51,8 @@ module clint (
logic memwrite;
logic initTrans;
logic [63:0] MTIMECMP;
logic [`XLEN/8-1:0] ByteMaskM;
integer i;
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
@ -63,6 +66,9 @@ module clint (
if (`XLEN==64) assign #2 entry = {HADDR[15:3], 3'b000};
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
// This will require synchronizing MTIME to the system clock
// before it is read or compared to MTIMECMP.
@ -86,7 +92,11 @@ module clint (
// MTIMECMP is not reset
end else if (memwrite) begin
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
// eventually replace MTIME logic below with timereg
@ -98,7 +108,9 @@ module clint (
// MTIMECMP is not reset
end else if (memwrite & entryd == 16'hBFF8) begin
// 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 begin:clint // 32-bit
always @(posedge HCLK) begin
@ -118,8 +130,14 @@ module clint (
// MTIMECMP is not reset ***?
end else if (memwrite) begin
if (entryd == 16'h0000) MSIP <= HWDATA[0];
if (entryd == 16'h4000) MTIMECMP[31:0] <= HWDATA;
if (entryd == 16'h4004) MTIMECMP[63:32] <= HWDATA;
if (entryd == 16'h4000)
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
end
@ -130,10 +148,14 @@ module clint (
MTIME <= 0;
// MTIMECMP is not reset
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
// 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

View File

@ -57,7 +57,7 @@ module plic (
input logic UARTIntr,GPIOIntr,
output logic [`XLEN-1:0] HREADPLIC,
output logic HRESPPLIC, HREADYPLIC,
output logic ExtIntM, ExtIntS);
output logic MExtIntM, SExtIntM);
logic memwrite, memread, initTrans;
logic [23:0] entry, entryd;
@ -176,11 +176,7 @@ module plic (
end
// pending interrupt requests
assign nextIntPending =
(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));
assign nextIntPending = (intPending | requests) & ~intInProgress;
flopr #(`N) intPendingFlop(HCLK,~HRESETn,nextIntPending,intPending);
// context-dependent signals
@ -253,10 +249,10 @@ module plic (
threshMask[ctx][2] = (intThreshold[ctx] != 2) & threshMask[ctx][3];
threshMask[ctx][1] = (intThreshold[ctx] != 1) & threshMask[ctx][2];
end
// is the max priority > threshold?
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
end
assign ExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
assign ExtIntS = |(threshMask[1] & priorities_with_irqs[1]);
end
// is the max priority > threshold?
// *** would it be any better to first priority encode maxPriority into binary and then ">" with threshold?
assign MExtIntM = |(threshMask[0] & priorities_with_irqs[0]);
assign SExtIntM = |(threshMask[1] & priorities_with_irqs[1]);
endmodule

View File

@ -43,85 +43,28 @@ module ram #(parameter BASE=0, RANGE = 65535) (
output logic HRESPRam, HREADYRam
);
// Desired changes.
// 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.)
// 3. implement burst.
// 4. remove the configurable latency.
localparam MemStartAddr = BASE>>(1+`XLEN/32);
localparam MemEndAddr = (RANGE+BASE)>>1+(`XLEN/32);
logic [`XLEN/8-1:0] ByteMaskM;
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)];
logic [31:0] HWADDR, A;
swbytemask swbytemask(.HSIZED, .HADDRD(HWADDR[2:0]), .ByteMask(ByteMaskM));
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);
// *** this seems like a weird way to use reset
flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam & HWRITE, memwrite);
flopenr #(32) haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A);
// busy FSM to extend READY signal
always_ff @(posedge HCLK, negedge HRESETn)
always @(posedge HCLK, negedge HRESETn)
if (~HRESETn) begin
busycount <= 0;
HREADYRam <= #1 0;
@ -138,47 +81,26 @@ module ram #(parameter BASE=0, RANGE = 65535) (
end
end
assign HRESPRam = 0; // OK
localparam ADDR_WDITH = $clog2(RANGE/8);
localparam OFFSET = $clog2(`XLEN/8);
// Rising HREADY edge detector
// Indicates when ram is finishing up
// Needed because HREADY may go high for other reasons,
// 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;
// Model memory read and write
/* -----\/----- 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)
always @(posedge HCLK)
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

View File

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

View File

@ -34,7 +34,7 @@
module wallypipelinedcore (
input logic clk, reset,
// Privileged
input logic TimerIntM, ExtIntM, ExtIntS, SwIntM,
input logic TimerIntM, MExtIntM, SExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT,
// Bus Interface
input logic [`AHBW-1:0] HRDATA,
@ -157,7 +157,6 @@ module wallypipelinedcore (
logic [2:0] LSUBusSize;
logic ExceptionM;
logic PendingInterruptM;
logic DCacheMiss;
logic DCacheAccess;
logic ICacheMiss;
@ -170,7 +169,7 @@ module wallypipelinedcore (
.StallF, .StallD, .StallE, .StallM, .StallW,
.FlushF, .FlushD, .FlushE, .FlushM, .FlushW,
.ExceptionM, .PendingInterruptM,
.ExceptionM,
// Fetch
.IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr,
.IFUBusRead, .IFUStallF,
@ -331,7 +330,7 @@ module wallypipelinedcore (
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.TimerIntM, .ExtIntM, .ExtIntS, .SwIntM,
.TimerIntM, .MExtIntM, .SExtIntM, .SwIntM,
.MTIME_CLINT,
.InstrMisalignedAdrM, .IEUAdrM,
.SetFflagsM,
@ -339,7 +338,7 @@ module wallypipelinedcore (
// *** 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?
.InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM,
.ExceptionM, .PendingInterruptM, .IllegalFPUInstrE,
.ExceptionM, .IllegalFPUInstrE,
.PrivilegeModeW, .SATP_REGW,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,

View File

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

View File

@ -357,7 +357,7 @@ module testbench;
initial begin
force dut.core.priv.priv.SwIntM = 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(linuxImageDir,"%s/buildroot/output/images/",RISCV_DIR);
if (CHECKPOINT!=0)
@ -368,14 +368,14 @@ module testbench;
ProgramLabelMapFile = {linuxImageDir,"disassembly/vmlinux.objdump.lab"};
// initialize bootrom
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);
// initialize RAM
if (CHECKPOINT==0)
memFile = $fopen({testvectorDir,"ram.bin"}, "rb");
else
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);
if (CHECKPOINT==0) begin // normal
traceFileM = $fopen({testvectorDir,"all.txt"}, "r");
@ -383,7 +383,7 @@ module testbench;
InstrCountW = '0;
AttemptedInstructionCount = '0;
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");
traceFileM = $fopen({checkpointDir,"all.txt"}, "r");
InstrCountW = CHECKPOINT;
@ -791,9 +791,9 @@ module testbench;
BaseAdr = SATP[43:0] << 12;
for (i = 2; i >= 0; i--) begin
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.
PTE = dut.uncore.ram.ram.RAM[PAdr >> 3];
PTE = dut.uncore.ram.ram.memory.RAM[PAdr >> 3];
PTE_R = PTE[1];
PTE_X = PTE[3];
if (PTE_R | PTE_X) begin

View File

@ -44,7 +44,7 @@ module testbench;
int test, i, errors, totalerrors;
logic [31:0] sig32[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;
logic [31:0] InstrW;
@ -170,6 +170,7 @@ logic [3:0] dummy;
test = 1;
totalerrors = 0;
testadr = 0;
testadrNoBase = 0;
// fill memory with defined values to reduce Xs in simulation
// 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
@ -178,7 +179,7 @@ logic [3:0] dummy;
// the design.
if (TEST == "coremark")
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
pathname = tvpaths[tests[0].atoi()];
@ -186,9 +187,9 @@ logic [3:0] dummy;
pathname = tvpaths[0];
else pathname = tvpaths[1]; */
memfilename = {pathname, tests[test], ".elf.memfile"};
if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM);
else $readmemh(memfilename, dut.uncore.ram.ram.RAM);
if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM);
if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM);
else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM);
if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM);
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
ProgramLabelMapFile = {pathname, tests[test], ".elf.objdump.lab"};
@ -243,14 +244,15 @@ logic [3:0] dummy;
errors = (i == SIGNATURESIZE+1); // error if file is empty
i = 0;
testadr = (`RAM_BASE+tests[test+1].atohex())/(`XLEN/8);
testadrNoBase = (tests[test+1].atohex())/(`XLEN/8);
/* verilator lint_off INFINITELOOP */
while (signature[i] !== 'bx) begin
logic [`XLEN-1:0] sig;
if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.RAM[testadr+i];
else sig = dut.uncore.ram.ram.RAM[testadr+i];
// $display("signature[%h] = %h sig = %h", i, signature[i], sig);
if (`DMEM == `MEM_TIM) sig = dut.core.lsu.dtim.dtim.ram.memory.RAM[testadrNoBase+i];
else sig = dut.uncore.ram.ram.memory.RAM[testadrNoBase+i];
//$display("signature[%h] = %h sig = %h", i, 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?
if ((signature[i] !== '0 | signature[i+4] !== 'x)) 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;
$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], 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
end
end
@ -283,10 +285,10 @@ logic [3:0] dummy;
else begin
//pathname = tvpaths[tests[0]];
memfilename = {pathname, tests[test], ".elf.memfile"};
//$readmemh(memfilename, dut.uncore.ram.ram.RAM);
if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.RAM);
else $readmemh(memfilename, dut.uncore.ram.ram.RAM);
if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.RAM);
//$readmemh(memfilename, dut.uncore.ram.ram.memory.RAM);
if (`IMEM == `MEM_TIM) $readmemh(memfilename, dut.core.ifu.irom.irom.ram.memory.RAM);
else $readmemh(memfilename, dut.uncore.ram.ram.memory.RAM);
if (`DMEM == `MEM_TIM) $readmemh(memfilename, dut.core.lsu.dtim.dtim.ram.memory.RAM);
ProgramAddrMapFile = {pathname, tests[test], ".elf.objdump.addr"};
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}/*/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
if { $saifpower == 1 } {
saif_map -start