Merge branch 'openhwgroup:main' into bitmanip_cleanup

This commit is contained in:
Kevin Kim 2023-03-28 11:31:18 -07:00 committed by GitHub
commit 4c9670a082
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
119 changed files with 3682 additions and 1969 deletions

View File

@ -34,8 +34,8 @@ Clone your fork of the repo and run the setup script.
$ cd $ cd
$ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw $ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw
$ git remote add upstream https://github.com/openhwgroup/cvw
$ cd cvw $ cd cvw
$ git remote add upstream https://github.com/openhwgroup/cvw
$ source ./setup.sh $ source ./setup.sh
Add the following lines to your .bashrc or .bash_profile to run the setup script each time you log in. Add the following lines to your .bashrc or .bash_profile to run the setup script each time you log in.

View File

@ -29,7 +29,7 @@
`include "wally-shared.vh" `include "wally-shared.vh"
`define FPGA 1 `define FPGA 1
`define QEMU 1 `define QEMU 0
// RV32 or RV64: XLEN = 32 or 64 // RV32 or RV64: XLEN = 32 or 64
`define XLEN 64 `define XLEN 64

41
docs/README-linux.md Normal file
View File

@ -0,0 +1,41 @@
### Cross-Compile Buildroot Linux
Building Linux is only necessary for exploring the boot process in Chapter 17. Building and generating a trace is a time-consuming operation that could be skipped for now; you can return to this section later if you are interested in the Linux details.
Buildroot depends on configuration files in riscv-wally, so the cad user must install Wally first according to the instructions in Section 2.2.2. However, dont source ~/wally-riscv/setup.sh because it will set LD_LIBRARY_PATH in a way to cause make to fail on buildroot.
To configure and build Buildroot:
$ cd $RISCV
$ export WALLY=~/riscv-wally # make sure you havent sourced ~/riscv-wally/setup.sh by now
$ git clone https://github.com/buildroot/buildroot.git
$ cd buildroot
$ git checkout 2021.05 # last tested working version
$ cp -r $WALLY/linux/buildroot-config-src/wally ./board
$ cp ./board/wally/main.config .config
$ make --jobs
To generate disassembly files and the device tree, run another make script. Note that you can expect some warnings about phandle references while running dtc on wally-virt.dtb.
Depending on your system configuration this makefile may need a bit of tweaking. It places the output buildroot images in $RISCV/linux-testvectors and the buildroot object dumps in $RISCV/buildroot/output/images/disassembly. If these directories are owned by root then the makefile will likely fail. You can either change the makefile's target directories or change temporarily change the owner of the two directories.
$ source ~/riscv-wally/setup.sh
$ cd $WALLY/linux/buildroot-scripts
$ make all
Note: When the make tasks complete, youll find source code in $RISCV/buildroot/output/build and the executables in $RISCV/buildroot/output/images.
### Generate load images for linux boot
The Questa linux boot uses preloaded bootram and ram memory. We use QEMU to generate these preloaded memory files. Files output in $RISCV/linux-testvectors
cd cvw/linux/testvector-generation
./genInitMem.sh
This may require changing file permissions to the linux-testvectors directory.
### Generate QEMU linux trace
The linux testbench can instruction by instruction compare Wally's committed instructions against QEMU. To do this QEMU outputs a log file consisting of all instructions executed. Interrupts are handled by forcing the testbench to generate an interrupt at the same cycle as in QEMU. Generating this trace will take more than 24 hours.
cd cvw/linux/testvector-generation
./genTrace.sh

View File

@ -0,0 +1,251 @@
# The main clocks are all autogenerated by the Xilinx IP
# mmcm_clkout1 is the 22Mhz clock from the DDR4 IP used to drive wally and the AHBLite Bus.
# mmcm_clkout0 is the clock output of the DDR4 memory interface / 4.
# This clock is not used by wally or the AHBLite Bus. However it is used by the AXI BUS on the DD4 IP.
create_generated_clock -name CLKDiv64_Gen -source [get_pins wallypipelinedsoc/uncore.uncore/sdc.SDC/sd_top/slow_clk_divider/clkMux/I0] -multiply_by 1 -divide_by 2 [get_pins wallypipelinedsoc/uncore.uncore/sdc.SDC/sd_top/slow_clk_divider/clkMux/O]
##### GPI ####
set_property PACKAGE_PIN D9 [get_ports {GPI[0]}]
set_property PACKAGE_PIN C9 [get_ports {GPI[1]}]
set_property PACKAGE_PIN B9 [get_ports {GPI[2]}]
set_property PACKAGE_PIN B8 [get_ports {GPI[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPI[0]}]
set_input_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 2.000 [get_ports {GPI[*]}]
set_input_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 2.000 [get_ports {GPI[*]}]
set_max_delay -from [get_ports {GPI[*]}] 10.000
##### GPO ####
set_property PACKAGE_PIN G6 [get_ports {GPO[0]}]
set_property PACKAGE_PIN F6 [get_ports {GPO[1]}]
set_property PACKAGE_PIN E1 [get_ports {GPO[2]}]
set_property PACKAGE_PIN G3 [get_ports {GPO[4]}]
set_property PACKAGE_PIN J4 [get_ports {GPO[3]}]
set_property IOSTANDARD LVCMOS12 [get_ports {GPO[4]}]
set_property IOSTANDARD LVCMOS12 [get_ports {GPO[3]}]
set_property IOSTANDARD LVCMOS12 [get_ports {GPO[2]}]
set_property IOSTANDARD LVCMOS12 [get_ports {GPO[1]}]
set_property IOSTANDARD LVCMOS12 [get_ports {GPO[0]}]
set_max_delay -to [get_ports {GPO[*]}] 10.000
set_output_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 0.000 [get_ports {GPO[*]}]
set_output_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 0.000 [get_ports {GPO[*]}]
##### UART #####
# *** IOSTANDARD is probably wrong
set_property PACKAGE_PIN A9 [get_ports UARTSin]
set_property PACKAGE_PIN D0 [get_ports UARTSout]
set_max_delay -from [get_ports UARTSin] 10.000
set_max_delay -to [get_ports UARTSout] 10.000
set_property IOSTANDARD LVCMOS33 [get_ports UARTSin]
set_property IOSTANDARD LVCMOS3 [get_ports UARTSout]
set_property DRIVE 6 [get_ports UARTSout]
set_input_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 2.000 [get_ports UARTSin]
set_input_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 2.000 [get_ports UARTSin]
set_output_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 0.000 [get_ports UARTSout]
set_output_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 0.000 [get_ports UARTSout]
##### reset #####
#************** reset is inverted
set_input_delay -clock [get_clocks default_250mhz_clk1_0_p] -min -add_delay 2.000 [get_ports reset]
set_input_delay -clock [get_clocks default_250mhz_clk1_0_p] -max -add_delay 2.000 [get_ports reset]
set_input_delay -clock [get_clocks mmcm_clkout0] -min -add_delay 0.000 [get_ports reset]
set_input_delay -clock [get_clocks mmcm_clkout0] -max -add_delay 0.000 [get_ports reset]
set_input_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 0.000 [get_ports reset]
set_input_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 0.000 [get_ports reset]
set_max_delay -from [get_ports reset] 15.000
set_false_path -from [get_ports reset]
set_property PACKAGE_PIN C2 [get_ports {reset}]
set_property IOSTANDARD LVCMOS33 [get_ports {reset}]
##### cpu_reset #####
# ***********
set_property PACKAGE_PIN AV36 [get_ports {cpu_reset}]
set_property IOSTANDARD LVCMOS12 [get_ports {cpu_reset}]
set_output_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 0.000 [get_ports {cpu_reset}]
set_output_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 0.000 [get_ports {cpu_reset}]
##### calib #####
# **********
set_property PACKAGE_PIN BA37 [get_ports calib]
set_property IOSTANDARD LVCMOS12 [get_ports calib]
set_output_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 0.000 [get_ports calib]
set_output_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 20.000 [get_ports calib]
set_max_delay -from [get_pins xlnx_ddr4_c0/inst/u_ddr4_mem_intfc/u_ddr_cal_top/calDone_gated_reg/C] -to [get_ports calib] 50.000
##### ahblite_resetn #####
# ***************
set_property PACKAGE_PIN AU37 [get_ports {ahblite_resetn}]
set_property IOSTANDARD LVCMOS12 [get_ports {ahblite_resetn}]
set_output_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 0.000 [get_ports {ahblite_resetn}]
set_output_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 0.000 [get_ports {ahblite_resetn}]
##### south_rst #####
# ***********************
set_property PACKAGE_PIN BE22 [get_ports south_rst]
set_property IOSTANDARD LVCMOS18 [get_ports south_rst]
set_input_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 2.000 [get_ports south_rst]
set_input_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 2.000 [get_ports south_rst]
##### SD Card I/O #####
#***** may have to switch to Pmod JB or JC.
set_property PACKAGE_PIN D4 [get_ports {SDCDat[3]}]
set_property PACKAGE_PIN D2 [get_ports {SDCDat[2]}]
set_property PACKAGE_PIN E2 [get_ports {SDCDat[1]}]
set_property PACKAGE_PIN F4 [get_ports {SDCDat[0]}]
set_property PACKAGE_PIN F2 [get_ports SDCCLK]
set_property PACKAGE_PIN D3 [get_ports {SDCCmd}]
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {SDCDat[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports SDCCLK]
set_property IOSTANDARD LVCMOS33 [get_ports {SDCCmd}]
set_property PULLUP true [get_ports {SDCDat[3]}]
set_property PULLUP true [get_ports {SDCDat[2]}]
set_property PULLUP true [get_ports {SDCDat[1]}]
set_property PULLUP true [get_ports {SDCDat[0]}]
set_property PULLUP true [get_ports {SDCCmd}]
set_input_delay -clock [get_clocks CLKDiv64_Gen] -min -add_delay 2.500 [get_ports {SDCDat[*]}]
set_input_delay -clock [get_clocks CLKDiv64_Gen] -max -add_delay 21.000 [get_ports {SDCDat[*]}]
set_input_delay -clock [get_clocks CLKDiv64_Gen] -min -add_delay 2.500 [get_ports {SDCCmd}]
set_input_delay -clock [get_clocks CLKDiv64_Gen] -max -add_delay 14.000 [get_ports {SDCCmd}]
set_output_delay -clock [get_clocks CLKDiv64_Gen] -min -add_delay 2.000 [get_ports {SDCCmd}]
set_output_delay -clock [get_clocks CLKDiv64_Gen] -max -add_delay 6.000 [get_ports {SDCCmd}]
set_output_delay -clock [get_clocks CLKDiv64_Gen] 0.000 [get_ports SDCCLK]
# *********************************
set_property DCI_CASCADE {64} [get_iobanks 65]
set_property INTERNAL_VREF 0.9 [get_iobanks 65]
# ddr3
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[0]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[1]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[2]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[3]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[4]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[5]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[6]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[7]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[8]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[9]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[10]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[11]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[12]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[13]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[14]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[15]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dm[0]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dm[1]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_p[0]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_n[0]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_p[1]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_n[1]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[13]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[12]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[11]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[10]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[9]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[8]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[7]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[6]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[5]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[4]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[3]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[2]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[1]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[0]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[2]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[1]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[0]
set_property IOSTANDARD DIFF [get_ports ddr3_ck_p[0]
set_property IOSTANDARD DIFF [get_ports ddr3_ck_n[0]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ras_n
set_property IOSTANDARD SSTL135 [get_ports ddr3_cas_n
set_property IOSTANDARD SSTL135 [get_ports ddr3_we_n
set_property IOSTANDARD SSTL135 [get_ports ddr3_reset_n
set_property IOSTANDARD SSTL135 [get_ports ddr3_cke[0]
set_property IOSTANDARD SSTL135 [get_ports ddr3_odt[0]
set_property IOSTANDARD SSTL135 [get_ports ddr3_cs_n[0]
set_properity PACKAGE_PIN K5 [get_ports ddr3_dq[0]]
set_properity PACKAGE_PIN L3 [get_ports ddr3_dq[1]]
set_properity PACKAGE_PIN K3 [get_ports ddr3_dq[2]]
set_properity PACKAGE_PIN L6 [get_ports ddr3_dq[3]]
set_properity PACKAGE_PIN M3 [get_ports ddr3_dq[4]]
set_properity PACKAGE_PIN M1 [get_ports ddr3_dq[5]]
set_properity PACKAGE_PIN L4 [get_ports ddr3_dq[6]]
set_properity PACKAGE_PIN M2 [get_ports ddr3_dq[7]]
set_properity PACKAGE_PIN V4 [get_ports ddr3_dq[8]]
set_properity PACKAGE_PIN T5 [get_ports ddr3_dq[9]]
set_properity PACKAGE_PIN U4 [get_ports ddr3_dq[10]]
set_properity PACKAGE_PIN V5 [get_ports ddr3_dq[11]]
set_properity PACKAGE_PIN V1 [get_ports ddr3_dq[12]]
set_properity PACKAGE_PIN T3 [get_ports ddr3_dq[13]]
set_properity PACKAGE_PIN U3 [get_ports ddr3_dq[14]]
set_properity PACKAGE_PIN R3 [get_ports ddr3_dq[15]]
set_properity PACKAGE_PIN L1 [get_ports ddr3_dm[0]]
set_properity PACKAGE_PIN U1 [get_ports ddr3_dm[1]]
set_properity PACKAGE_PIN N2 [get_ports ddr3_dqs_p[0]]
set_properity PACKAGE_PIN N1 [get_ports ddr3_dqs_n[0]]
set_properity PACKAGE_PIN U2 [get_ports ddr3_dqs_p[1]]
set_properity PACKAGE_PIN V2 [get_ports ddr3_dqs_n[1]]
set_properity PACKAGE_PIN T8 [get_ports ddr3_addr[13]]
set_properity PACKAGE_PIN T6 [get_ports ddr3_addr[12]]
set_properity PACKAGE_PIN U6 [get_ports ddr3_addr[11]]
set_properity PACKAGE_PIN R6 [get_ports ddr3_addr[10]]
set_properity PACKAGE_PIN V7 [get_ports ddr3_addr[9]]
set_properity PACKAGE_PIN R8 [get_ports ddr3_addr[8]]
set_properity PACKAGE_PIN U7 [get_ports ddr3_addr[7]]
set_properity PACKAGE_PIN V6 [get_ports ddr3_addr[6]]
set_properity PACKAGE_PIN R7 [get_ports ddr3_addr[5]]
set_properity PACKAGE_PIN N6 [get_ports ddr3_addr[4]]
set_properity PACKAGE_PIN T1 [get_ports ddr3_addr[3]]
set_properity PACKAGE_PIN N4 [get_ports ddr3_addr[2]]
set_properity PACKAGE_PIN M6 [get_ports ddr3_addr[1]]
set_properity PACKAGE_PIN R2 [get_ports ddr3_addr[0]]
set_properity PACKAGE_PIN P2 [get_ports ddr3_ba[2]]
set_properity PACKAGE_PIN P4 [get_ports ddr3_ba[1]]
set_properity PACKAGE_PIN R1 [get_ports ddr3_ba[0]]
set_properity PACKAGE_PIN U9 [get_ports ddr3_ck_p[0]]
set_properity PACKAGE_PIN V9 [get_ports ddr3_ck_n[0]]
set_properity PACKAGE_PIN P3 [get_ports ddr3_ras_n]
set_properity PACKAGE_PIN M4 [get_ports ddr3_cas_n]
set_properity PACKAGE_PIN P5 [get_ports ddr3_we_n]
set_properity PACKAGE_PIN K6 [get_ports ddr3_reset_n]
set_properity PACKAGE_PIN N5 [get_ports ddr3_cke[0]]
set_properity PACKAGE_PIN R5 [get_ports ddr3_odt[0]]
set_properity PACKAGE_PIN U8 [get_ports ddr3_cs_n[0]]
set_max_delay -datapath_only -from [get_pins xlnx_ddr4_c0/inst/u_ddr4_mem_intfc/u_ddr_cal_top/calDone_gated_reg/C] -to [get_pins xlnx_proc_sys_reset_0/U0/EXT_LPF/lpf_int_reg/D] 10.000
set_output_delay -clock [get_clocks mmcm_clkout1] -min -add_delay 0.000 [get_ports c0_ddr4_reset_n]
set_output_delay -clock [get_clocks mmcm_clkout1] -max -add_delay 20.000 [get_ports c0_ddr4_reset_n]
set_max_delay -from [get_pins {xlnx_ddr4_c0/inst/u_ddr4_mem_intfc/u_ddr_cal_top/cal_RESET_n_reg[0]/C}] -to [get_ports c0_ddr4_reset_n] 50.000

View File

@ -120,8 +120,6 @@ ebu/ebu.sv: logic HCLK
ebu/ebu.sv: logic HREADY ebu/ebu.sv: logic HREADY
ebu/ebu.sv: logic HRESP ebu/ebu.sv: logic HRESP
ebu/ebu.sv: logic HADDR ebu/ebu.sv: logic HADDR
ebu/ebu.sv: logic HWDATA
ebu/ebu.sv: logic HWSTRB
ebu/ebu.sv: logic HWRITE ebu/ebu.sv: logic HWRITE
ebu/ebu.sv: logic HSIZE ebu/ebu.sv: logic HSIZE
ebu/ebu.sv: logic HBURST ebu/ebu.sv: logic HBURST

View File

@ -88,7 +88,7 @@ module fpgaTop
wire [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; wire [31:0] GPIOIN, GPIOOUT, GPIOEN;
wire SDCCmdIn; wire SDCCmdIn;
wire SDCCmdOE; wire SDCCmdOE;
@ -183,8 +183,8 @@ module fpgaTop
assign GPIOPinsIn = {28'b0, GPI}; assign GPIOIN = {28'b0, GPI};
assign GPO = GPIOPinsOut[4:0]; assign GPO = GPIOOUT[4:0];
assign ahblite_resetn = peripheral_aresetn; assign ahblite_resetn = peripheral_aresetn;
assign cpu_reset = bus_struct_reset; assign cpu_reset = bus_struct_reset;
assign calib = c0_init_calib_complete; assign calib = c0_init_calib_complete;
@ -231,9 +231,9 @@ module fpgaTop
.HMASTLOCK(HMASTLOCK), .HMASTLOCK(HMASTLOCK),
.HREADY(HREADY), .HREADY(HREADY),
// GPIO // GPIO
.GPIOPinsIn(GPIOPinsIn), .GPIOIN(GPIOIN),
.GPIOPinsOut(GPIOPinsOut), .GPIOOUT(GPIOOUT),
.GPIOPinsEn(GPIOPinsEn), .GPIOEN(GPIOEN),
// UART // UART
.UARTSin(UARTSin), .UARTSin(UARTSin),
.UARTSout(UARTSout), .UARTSout(UARTSout),

View File

@ -1,5 +1,5 @@
all: riscoftests memfiles all: riscoftests memfiles coveragetests
# *** Build old tests/imperas-riscv-tests for now; # *** Build old tests/imperas-riscv-tests for now;
# Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test # Delete this part when the privileged tests transition over to tests/wally-riscv-arch-test
# DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired # DH: 2/27/22 temporarily commented out imperas-riscv-tests because license expired
@ -50,3 +50,6 @@ riscoftests:
make -C ../tests/riscof/ make -C ../tests/riscof/
memfiles: memfiles:
make -f makefile-memfile wally-sim-files --jobs make -f makefile-memfile wally-sim-files --jobs
coveragetests:
make -C ../tests/coverage/

View File

@ -1,5 +1,7 @@
#--showoverrides #--mpdconsole
#--showcommands #--gdbconsole
--showoverrides
--showcommands
# Core settings # Core settings
--override cpu/unaligned=F --override cpu/unaligned=F
@ -9,7 +11,12 @@
--override cpu/misa_Extensions_mask=0x0 --override cpu/misa_Extensions_mask=0x0
# THIS NEEDS FIXING to 16 # THIS NEEDS FIXING to 16
--override cpu/PMP_registers=0 --override cpu/PMP_registers=16
--override cpu/PMP_undefined=T
# Illegal instruction should not contain the bit pattern
# illegal pmp read contained this
# --override cpu/tval_ii_code=F
# PMA Settings # PMA Settings
# 'r': read access allowed # 'r': read access allowed
@ -24,16 +31,16 @@
# '8': 8-byte accesses allowed # '8': 8-byte accesses allowed
# '-', space: ignored (use for input string formatting). # '-', space: ignored (use for input string formatting).
# #
# SV39 Memory 0x0000000000 0x7FFFFFFFFF # SVxx Memory 0x0000000000 0x7FFFFFFFFF
# #
--callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ------ ---- "; # INITIAL --callcommand refRoot/cpu/setPMA -lo 0x0000000000 -hi 0x7FFFFFFFFF -attributes " ------ ---- " # INITIAL
--callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 "; # BOOTROM --callcommand refRoot/cpu/setPMA -lo 0x0000001000 -hi 0x0000001FFF -attributes " r-x-A- 1248 " # BOOTROM
--callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw--A- --48 "; # SDC --callcommand refRoot/cpu/setPMA -lo 0x0000012100 -hi 0x000001211F -attributes " rw--A- --48 " # SDC
--callcommand refRoot/cpu/setPMA -lo 0x0002000000 -hi 0x000200FFFF -attributes " rw--A- 1248 "; # CLINT --callcommand refRoot/cpu/setPMA -lo 0x0002000000 -hi 0x000200FFFF -attributes " rw--A- 1248 " # CLINT
--callcommand refRoot/cpu/setPMA -lo 0x000C000000 -hi 0x000FFFFFFF -attributes " rw--A- --4- "; # PLIC --callcommand refRoot/cpu/setPMA -lo 0x000C000000 -hi 0x000FFFFFFF -attributes " rw--A- --4- " # PLIC
--callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw--A- 1--- "; # UART0 error - 0x10000000 - 0x100000FF --callcommand refRoot/cpu/setPMA -lo 0x0010000000 -hi 0x0010000007 -attributes " rw--A- 1--- " # UART0 error - 0x10000000 - 0x100000FF
--callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw--A- --4- "; # GPIO error - 0x10006000 - 0x100060FF --callcommand refRoot/cpu/setPMA -lo 0x0010060000 -hi 0x00100600FF -attributes " rw--A- --4- " # GPIO error - 0x10006000 - 0x100060FF
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 "; # UNCORE_RAM --callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM
# Enable the Imperas instruction coverage # Enable the Imperas instruction coverage
#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0 #-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
@ -42,7 +49,7 @@
# Add Imperas simulator application instruction tracing # Add Imperas simulator application instruction tracing
--override cpu/show_c_prefix=T --override cpu/show_c_prefix=T
--trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --trace --tracechange --traceshowicount --tracemode -tracemem ASX --monitornetschange --traceafter 10500000
# Exceptions and pagetables debug # Exceptions and pagetables debug
--override cpu/debugflags=6 --override cpu/debugflags=6

9
sim/run-imperas-linux.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
#export RISCV=/scratch/moore/RISCV
export IMPERAS_TOOLS=$(pwd)/imperas.ic
export OTHERFLAGS="+TRACE2LOG_ENABLE=1"
export OTHERFLAGS="+TRACE2LOG_ENABLE=1 +TRACE2LOG_AFTER=10500000"
vsim -c -do "do wally-linux-imperas.do buildroot buildroot-no-trace $::env(RISCV) 0 0 0"

View File

@ -51,7 +51,7 @@ vlog +incdir+../config/$1 \
-suppress 7063 \ -suppress 7063 \
+acc +acc
vopt +acc work.testbench -G DEBUG=1 -o workopt vopt +acc work.testbench -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7 \ eval vsim workopt +nowarn3829 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \ -sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
+testDir=$env(TESTDIR) $env(OTHERFLAGS) +TRACE2COV_ENABLE=1 \ +testDir=$env(TESTDIR) $env(OTHERFLAGS) +TRACE2COV_ENABLE=1 \
-do "coverage save -onexit ./riscv.ucdb" -do "coverage save -onexit ./riscv.ucdb"

View File

@ -34,7 +34,7 @@ vlog +incdir+../config/$1 \
-suppress 2583 \ -suppress 2583 \
-suppress 7063 -suppress 7063
vopt +acc work.testbench -G DEBUG=1 -o workopt vopt +acc work.testbench -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7 \ eval vsim workopt +nowarn3829 -fatal 7 \
+testDir=$env(TESTDIR) $env(OTHERFLAGS) +testDir=$env(TESTDIR) $env(OTHERFLAGS)
view wave view wave
#-- display input and output signals as hexidecimal values #-- display input and output signals as hexidecimal values

View File

@ -45,7 +45,7 @@ vlog +incdir+../config/$1 \
-suppress 7063 -suppress 7063
vopt +acc work.testbench -G DEBUG=1 -o workopt vopt +acc work.testbench -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7 \ eval vsim workopt +nowarn3829 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \ -sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
+testDir=$env(TESTDIR) $env(OTHERFLAGS) +testDir=$env(TESTDIR) $env(OTHERFLAGS)
view wave view wave

150
sim/wally-linux-imperas.do Normal file
View File

@ -0,0 +1,150 @@
# wally.do
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
#
# Modification by Oklahoma State University & Harvey Mudd College
# Use with Testbench
# James Stine, 2008; David Harris 2021
# Go Cowboys!!!!!!
#
# Takes 1:10 to run RV64IC tests using gui
# run with vsim -do "do wally-pipelined.do rv64ic riscvarchtest-64m"
# Use this wally-pipelined.do file to run this example.
# Either bring up ModelSim and type the following at the "ModelSim>" prompt:
# do wally.do
# or, to run from a shell, type the following at the shell prompt:
# vsim -do wally.do -c
# (omit the "-c" to see the GUI while running from the shell)
onbreak {resume}
# create library
if [file exists work] {
vdel -all
}
vlib work
# compile source files
# suppress spurious warnngs about
# "Extra checking for conflicts with always_comb done at vopt time"
# because vsim will run vopt
# start and run simulation
# remove +acc flag for faster sim during regressions if there is no need to access internal signals
if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=$4 -G INSTR_WAVEON=$5 -G CHECKPOINT=$6 -G NO_SPOOFING=0 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7
#-- Run the Simulation
#run -all
add log -recursive /*
do linux-wave.do
run -all
exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "buildroot-no-trace"} {
vlog -lint -work work_${1}_${2} \
+define+USE_IMPERAS_DV \
+incdir+../config/$1 \
+incdir+../config/shared \
+incdir+$env(IMPERAS_HOME)/ImpPublic/include/host \
+incdir+$env(IMPERAS_HOME)/ImpProprietary/include/host \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-api-pkg.sv \
$env(IMPERAS_HOME)/ImpPublic/source/host/rvvi/rvvi-trace.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/rvvi-pkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/imperasDV-api-pkg.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2api.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2log.sv \
$env(IMPERAS_HOME)/ImpProprietary/source/host/rvvi/trace2cov.sv \
../testbench/testbench-linux-imperas.sv \
../testbench/common/*.sv ../src/*/*.sv \
../src/*/*/*.sv -suppress 2583
#
# start and run simulation
# for profiling add
# vopt -fprofile
# vsim -fprofile+perf
# visualizer -fprofile+perf+dir=fprofile
#
eval vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 \
-G INSTR_LIMIT=0 -G INSTR_WAVEON=0 -G CHECKPOINT=0 -G NO_SPOOFING=1 -o testbenchopt
eval vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829,13286 -fatal 7 \
-sv_lib $env(IMPERAS_HOME)/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model \
$env(OTHERFLAGS)
#-- Run the Simulation
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "Don't forget to change DEBUG_LEVEL = 0."
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
#run 100 ns
#force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa
#force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000
run 14000 ms
#add log -recursive /*
#do linux-wave.do
#run -all
exec ./slack-notifier/slack-notifier.py
} elseif {$2 eq "fpga"} {
echo "hello"
vlog -work work +incdir+../config/fpga +incdir+../config/shared ../testbench/testbench.sv ../testbench/sdc/*.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv ../../fpga/sim/*.sv -suppress 8852,12070,3084,3829,2583,7063,13286
vopt +acc work.testbench -G TEST=$2 -G DEBUG=0 -o workopt
vsim workopt +nowarn3829 -fatal 7
do fpga-wave.do
add log -r /*
run 20 ms
} else {
if {$2 eq "ahb"} {
vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063 +define+RAM_LATENCY=$3 +define+BURST_EN=$4
} else {
# *** modelsim won't take `PA_BITS, but will take other defines for the lengths of DTIM_RANGE and IROM_LEN. For now just live with the warnings.
vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583,13286 -suppress 7063
}
vopt +acc work.testbench -G TEST=$2 -G DEBUG=1 -o workopt
vsim workopt +nowarn3829 -fatal 7
view wave
#-- display input and output signals as hexidecimal values
#do ./wave-dos/peripheral-waves.do
add log -recursive /*
do wave.do
#do wave-bus.do
# power add generates the logging necessary for saif generation.
#power add -r /dut/core/*
#-- Run the Simulation
run -all
#power off -r /dut/core/*
#power report -all -bsaif power.saif
noview ../testbench/testbench.sv
view wave
}
#elseif {$2 eq "buildroot-no-trace""} {
# vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation
# vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G RISCV_DIR=$3 -G INSTR_LIMIT=470350800 -G INSTR_WAVEON=470350800 -G CHECKPOINT=470350800 -G DEBUG_TRACE=0 -o testbenchopt
# vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084,3829
#-- Run the Simulation
# run 100 ns
# force -deposit testbench/dut/core/priv/priv/csr/csri/IE_REGW 16'h2aa
# force -deposit testbench/dut/uncore/uncore/clint/clint/MTIMECMP 64'h1000
# add log -recursive /*
# do linux-wave.do
# run -all
# exec ./slack-notifier/slack-notifier.py
#}

22
src/cache/cache.sv vendored
View File

@ -98,9 +98,9 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
logic CacheEn; logic CacheEn;
logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded; logic [CACHEWORDSPERLINE-1:0] MemPAdrDecoded;
logic [LINELEN/8-1:0] LineByteMask, DemuxedByteMask, FetchBufferByteSel; logic [LINELEN/8-1:0] LineByteMask, DemuxedByteMask, FetchBufferByteSel;
logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr; logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1:0] WordOffsetAddr;
genvar index; genvar index;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Read Path // Read Path
@ -154,9 +154,9 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
// Bus address for fetch, writeback, or flush writeback // Bus address for fetch, writeback, or flush writeback
mux3 #(`PA_BITS) CacheBusAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}), mux3 #(`PA_BITS) CacheBusAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
.d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}), .d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
.d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}), .d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}),
.s({SelFlush, SelWriteback}), .y(CacheBusAdr)); .s({SelFlush, SelWriteback}), .y(CacheBusAdr));
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Path // Write Path
@ -198,11 +198,11 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
cachefsm #(READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, cachefsm #(READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck,
.FlushStage, .CacheRW, .CacheAtomic, .Stall, .FlushStage, .CacheRW, .CacheAtomic, .Stall,
.CacheHit, .LineDirty, .CacheStall, .CacheCommitted, .CacheHit, .LineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .CacheMiss, .CacheAccess, .SelAdr,
.ClearValid, .ClearDirty, .SetDirty, .SetValid, .SelWriteback, .SelFlush, .ClearValid, .ClearDirty, .SetDirty, .SetValid, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CacheEn, .LRUWriteEn); .InvalidateCache, .CacheEn, .LRUWriteEn);
endmodule endmodule

76
src/cache/cachefsm.sv vendored
View File

@ -47,7 +47,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback) output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
// performance counter outputs // performance counter outputs
output logic CacheMiss, // Cache miss output logic CacheMiss, // Cache miss
output logic CacheAccess, // Cache access output logic CacheAccess, // Cache access
// cache internals // cache internals
input logic CacheHit, // Exactly 1 way hits input logic CacheHit, // Exactly 1 way hits
@ -69,21 +69,21 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
output logic CacheEn // Enable the cache memory arrays. Disable hold read data constant output logic CacheEn // Enable the cache memory arrays. Disable hold read data constant
); );
logic resetDelay; logic resetDelay;
logic AMO, StoreAMO; logic AMO, StoreAMO;
logic AnyUpdateHit, AnyHit; logic AnyUpdateHit, AnyHit;
logic AnyMiss; logic AnyMiss;
logic FlushFlag; logic FlushFlag;
typedef enum logic [3:0]{STATE_READY, // hit states typedef enum logic [3:0]{STATE_READY, // hit states
// miss states // miss states
STATE_FETCH, STATE_FETCH,
STATE_WRITEBACK, STATE_WRITEBACK,
STATE_WRITE_LINE, STATE_WRITE_LINE,
STATE_READ_HOLD, // required for back to back reads. structural hazard on writting SRAM STATE_READ_HOLD, // required for back to back reads. structural hazard on writting SRAM
// flush cache // flush cache
STATE_FLUSH, STATE_FLUSH,
STATE_FLUSH_WRITEBACK} statetype; STATE_FLUSH_WRITEBACK} statetype;
statetype CurrState, NextState; statetype CurrState, NextState;
@ -111,26 +111,26 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
always_comb begin always_comb begin
NextState = STATE_READY; NextState = STATE_READY;
case (CurrState) case (CurrState)
STATE_READY: if(InvalidateCache) NextState = STATE_READY; STATE_READY: if(InvalidateCache) NextState = STATE_READY;
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH;
else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK; else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK;
else NextState = STATE_READY; else NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
else NextState = STATE_FETCH; else NextState = STATE_FETCH;
STATE_WRITE_LINE: NextState = STATE_READ_HOLD; STATE_WRITE_LINE: NextState = STATE_READ_HOLD;
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY; else NextState = STATE_READY;
STATE_WRITEBACK: if(CacheBusAck) NextState = STATE_FETCH; STATE_WRITEBACK: if(CacheBusAck) NextState = STATE_FETCH;
else NextState = STATE_WRITEBACK; else NextState = STATE_WRITEBACK;
// eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack. // eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack.
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK; STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
else if (FlushFlag) NextState = STATE_READ_HOLD; else if (FlushFlag) NextState = STATE_READ_HOLD;
else NextState = STATE_FLUSH; else NextState = STATE_FLUSH;
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH; STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; else if(CacheBusAck) NextState = STATE_READ_HOLD;
else NextState = STATE_FLUSH_WRITEBACK; else NextState = STATE_FLUSH_WRITEBACK;
default: NextState = STATE_READY; default: NextState = STATE_READY;
endcase endcase
end end
@ -156,14 +156,14 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
(CurrState == STATE_READY & AnyMiss & LineDirty); (CurrState == STATE_READY & AnyMiss & LineDirty);
assign SelFlush = (CurrState == STATE_READY & FlushCache) | assign SelFlush = (CurrState == STATE_READY & FlushCache) |
(CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH) |
(CurrState == STATE_FLUSH_WRITEBACK); (CurrState == STATE_FLUSH_WRITEBACK);
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) | assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) |
(CurrState == STATE_FLUSH & FlushWayFlag & ~LineDirty); (CurrState == STATE_FLUSH & FlushWayFlag & ~LineDirty);
assign FlushWayCntEn = (CurrState == STATE_FLUSH & ~LineDirty) | assign FlushWayCntEn = (CurrState == STATE_FLUSH & ~LineDirty) |
(CurrState == STATE_FLUSH_WRITEBACK & CacheBusAck); (CurrState == STATE_FLUSH_WRITEBACK & CacheBusAck);
assign FlushCntRst = (CurrState == STATE_FLUSH & FlushFlag & ~LineDirty) | assign FlushCntRst = (CurrState == STATE_FLUSH & FlushFlag & ~LineDirty) |
(CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck); (CurrState == STATE_FLUSH_WRITEBACK & FlushFlag & CacheBusAck);
// Bus interface controls // Bus interface controls
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) |
(CurrState == STATE_FETCH & ~CacheBusAck) | (CurrState == STATE_FETCH & ~CacheBusAck) |

14
src/cache/cacheway.sv vendored
View File

@ -30,7 +30,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26, module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) ( OFFSETLEN = 5, INDEXLEN = 9, READ_ONLY_CACHE = 0) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations) input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
@ -86,8 +86,6 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
assign SelNonHit = FlushWayEn | SetValid | SelWriteback; assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag); mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
//assign SelTag = VictimWay | FlushWay;
//assign SelData = HitWay | FlushWayEn | VictimWayEn;
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData); mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);
@ -95,10 +93,6 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
// Write Enable demux // Write Enable demux
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// RT: Can we merge these two muxes? This is also shared in cacheLRU.
//mux3 #(1) selectwaymux(HitWay, VictimWay, FlushWay, {SelFlush, SetValid}, SelData);
//mux3 #(1) selecteddatamux(HitWay, VictimWay, FlushWay, {SelFlush, SelNonHit}, SelData);
assign SetValidWay = SetValid & SelData; assign SetValidWay = SetValid & SelData;
assign ClearValidWay = ClearValid & SelData; assign ClearValidWay = ClearValid & SelData;
assign SetDirtyWay = SetDirty & SelData; assign SetDirtyWay = SetDirty & SelData;
@ -117,8 +111,6 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
.addr(CacheSet), .dout(ReadTag), .bwe('1), .addr(CacheSet), .dout(ReadTag), .bwe('1),
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN)); .din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
// AND portion of distributed tag multiplexer // AND portion of distributed tag multiplexer
assign TagWay = SelTag ? ReadTag : '0; // AND part of AOMux assign TagWay = SelTag ? ReadTag : '0; // AND part of AOMux
assign DirtyWay = SelTag & Dirty & ValidWay; assign DirtyWay = SelTag & Dirty & ValidWay;
@ -152,8 +144,8 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
always_ff @(posedge clk) begin // Valid bit array, always_ff @(posedge clk) begin // Valid bit array,
if (reset) ValidBits <= #1 '0; if (reset) ValidBits <= #1 '0;
if(CacheEn) begin if(CacheEn) begin
ValidWay <= #1 ValidBits[CacheSet]; ValidWay <= #1 ValidBits[CacheSet];
if(InvalidateCache) ValidBits <= #1 '0; if(InvalidateCache) ValidBits <= #1 '0;
else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CacheSet] <= #1 SetValidWay; else if (SetValidEN | (ClearValidWay & ~FlushStage)) ValidBits[CacheSet] <= #1 SetValidWay;
end end
end end

View File

@ -33,8 +33,8 @@ module subcachelineread #(parameter LINELEN, WORDLEN,
parameter MUXINTERVAL )( // The number of bits between mux. Set to 16 for I$ to support compressed. Set to `LLEN for D$ parameter MUXINTERVAL )( // The number of bits between mux. Set to 16 for I$ to support compressed. Set to `LLEN for D$
input logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1 : 0] PAdr, // Physical address input logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1 : 0] PAdr, // Physical address
input logic [LINELEN-1:0] ReadDataLine,// Read data of the whole cacheline input logic [LINELEN-1:0] ReadDataLine,// Read data of the whole cacheline
output logic [WORDLEN-1:0] ReadDataWord // read data of selected word. output logic [WORDLEN-1:0] ReadDataWord // read data of selected word.
); );
localparam WORDSPERLINE = LINELEN/MUXINTERVAL; localparam WORDSPERLINE = LINELEN/MUXINTERVAL;
@ -50,7 +50,7 @@ module subcachelineread #(parameter LINELEN, WORDLEN,
genvar index; genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux
assign ReadDataLineSets[index] = ReadDataLinePad[(index*MUXINTERVAL)+WORDLEN-1 : (index*MUXINTERVAL)]; assign ReadDataLineSets[index] = ReadDataLinePad[(index*MUXINTERVAL)+WORDLEN-1 : (index*MUXINTERVAL)];
end end
// variable input mux // variable input mux

View File

@ -35,7 +35,7 @@ module ahbcacheinterface #(
parameter LINELEN, // Number of bits in cacheline parameter LINELEN, // Number of bits in cacheline
parameter LLENPOVERAHBW // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) parameter LLENPOVERAHBW // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
)( )(
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
// bus interface controls // bus interface controls
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
@ -56,7 +56,7 @@ module ahbcacheinterface #(
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
output logic CacheBusAck, // Handshack to $ indicating bus transaction completed output logic CacheBusAck, // Handshack to $ indicating bus transaction completed
output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus output logic [LINELEN-1:0] FetchBuffer, // Register to hold beats of cache line as the arrive from bus
output logic [AHBWLOGBWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase output logic [AHBWLOGBWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
// uncached interface // uncached interface
@ -76,10 +76,10 @@ module ahbcacheinterface #(
logic [`PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation logic [`PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation
logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage
logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA
logic [`AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s logic [`AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
logic [`AHBW-1:0] PreHWDATA; // AHB Address phase write data logic [`AHBW-1:0] PreHWDATA; // AHB Address phase write data
genvar index; genvar index;
// fetch buffer is made of BEATSPERLINE flip-flops // fetch buffer is made of BEATSPERLINE flip-flops
for (index = 0; index < BEATSPERLINE; index++) begin:fetchbuffer for (index = 0; index < BEATSPERLINE; index++) begin:fetchbuffer
@ -100,7 +100,7 @@ module ahbcacheinterface #(
logic [`AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0]; logic [`AHBW-1:0] AHBWordSets [(LLENPOVERAHBW)-1:0];
genvar index; genvar index;
for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux for (index = 0; index < LLENPOVERAHBW; index++) begin:readdatalinesetsmux
assign AHBWordSets[index] = CacheReadDataWordM[(index*`AHBW)+`AHBW-1: (index*`AHBW)]; assign AHBWordSets[index] = CacheReadDataWordM[(index*`AHBW)+`AHBW-1: (index*`AHBW)];
end end
assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]]; assign CacheReadDataWordAHB = AHBWordSets[BeatCount[$clog2(LLENPOVERAHBW)-1:0]];
end else assign CacheReadDataWordAHB = CacheReadDataWordM[`AHBW-1:0]; end else assign CacheReadDataWordAHB = CacheReadDataWordM[`AHBW-1:0];
@ -118,5 +118,5 @@ module ahbcacheinterface #(
buscachefsm #(BeatCountThreshold, AHBWLOGBWPL) AHBBuscachefsm( buscachefsm #(BeatCountThreshold, AHBWLOGBWPL) AHBBuscachefsm(
.HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat, .HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
.CacheBusRW, .CacheBusAck, .BeatCount, .BeatCountDelayed, .CacheBusRW, .CacheBusAck, .BeatCount, .BeatCountDelayed,
.HREADY, .HTRANS, .HWRITE, .HBURST); .HREADY, .HTRANS, .HWRITE, .HBURST);
endmodule endmodule

View File

@ -32,29 +32,28 @@
module ahbinterface #( module ahbinterface #(
parameter LSU = 0 // 1: LSU bus width is `XLEN, 0: IFU bus width is 32 bits parameter LSU = 0 // 1: LSU bus width is `XLEN, 0: IFU bus width is 32 bits
)( )(
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
// bus interface // bus interface
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic HWRITE, // AHB 0: Read operation 1: Write operation output logic HWRITE, // AHB 0: Read operation 1: Write operation
input logic [`XLEN-1:0] HRDATA, // AHB read data input logic [`XLEN-1:0] HRDATA, // AHB read data
output logic [`XLEN-1:0] HWDATA, // AHB write data output logic [`XLEN-1:0] HWDATA, // AHB write data
output logic [`XLEN/8-1:0] HWSTRB, // AHB byte mask output logic [`XLEN/8-1:0] HWSTRB, // AHB byte mask
// lsu/ifu interface // lsu/ifu interface
input logic Stall, // Core pipeline is stalled input logic Stall, // Core pipeline is stalled
input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting
input logic [1:0] BusRW, // Memory operation read/write control: 10: read, 01: write input logic [1:0] BusRW, // Memory operation read/write control: 10: read, 01: write
input logic [`XLEN/8-1:0] ByteMask, // Bytes enables within a word input logic [`XLEN/8-1:0] ByteMask, // Bytes enables within a word
input logic [`XLEN-1:0] WriteData, // IEU write data for a store input logic [`XLEN-1:0] WriteData, // IEU write data for a store
output logic BusStall, // Bus is busy with an in flight memory operation output logic BusStall, // Bus is busy with an in flight memory operation
output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt
output logic [(LSU ? `XLEN : 32)-1:0] FetchBuffer // Register to hold HRDATA after arriving from the bus output logic [(LSU ? `XLEN : 32)-1:0] FetchBuffer // Register to hold HRDATA after arriving from the bus
); );
logic CaptureEn; logic CaptureEn;
localparam LEN = (LSU ? `XLEN : 32); // 32 bits for IFU, XLEN for LSU
localparam LEN = (LSU ? `XLEN : 32); // 32 bits for IFU, XLEN for LSU
flopen #(LEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA[LEN-1:0]), .q(FetchBuffer)); flopen #(LEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA[LEN-1:0]), .q(FetchBuffer));
@ -70,4 +69,5 @@ module ahbinterface #(
busfsm busfsm(.HCLK, .HRESETn, .Flush, .BusRW, busfsm busfsm(.HCLK, .HRESETn, .Flush, .BusRW,
.BusCommitted, .Stall, .BusStall, .CaptureEn, .HREADY, .BusCommitted, .Stall, .BusStall, .CaptureEn, .HREADY,
.HTRANS, .HWRITE); .HTRANS, .HWRITE);
endmodule endmodule

View File

@ -35,33 +35,33 @@ module buscachefsm #(
parameter BeatCountThreshold, // Largest beat index parameter BeatCountThreshold, // Largest beat index
parameter AHBWLOGBWPL // Log2 of BEATSPERLINE parameter AHBWLOGBWPL // Log2 of BEATSPERLINE
)( )(
input logic HCLK, input logic HCLK,
input logic HRESETn, input logic HRESETn,
// IEU interface // IEU interface
input logic Stall, // Core pipeline is stalled input logic Stall, // Core pipeline is stalled
input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting
input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write
output logic BusStall, // Bus is busy with an in flight memory operation output logic BusStall, // Bus is busy with an in flight memory operation
output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt
// ahb cache interface locals. // ahb cache interface locals.
output logic CaptureEn, // Enable updating the Fetch buffer with valid data from HRDATA output logic CaptureEn, // Enable updating the Fetch buffer with valid data from HRDATA
// cache interface // cache interface
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
output logic CacheBusAck, // Handshack to $ indicating bus transaction completed output logic CacheBusAck, // Handshack to $ indicating bus transaction completed
// lsu interface // lsu interface
output logic [AHBWLOGBWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase output logic [AHBWLOGBWPL-1:0] BeatCount, // Beat position within the cache line in the Address Phase
output logic [AHBWLOGBWPL-1:0] BeatCountDelayed, // Beat within the cache line in the second (Data) cache stage output logic [AHBWLOGBWPL-1:0] BeatCountDelayed, // Beat within the cache line in the second (Data) cache stage
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
// BUS interface // BUS interface
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic HWRITE, // AHB 0: Read operation 1: Write operation output logic HWRITE, // AHB 0: Read operation 1: Write operation
output logic [2:0] HBURST // AHB burst length output logic [2:0] HBURST // AHB burst length
); );
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype; typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype;
@ -70,26 +70,26 @@ module buscachefsm #(
busstatetype CurrState, NextState; busstatetype CurrState, NextState;
logic [AHBWLOGBWPL-1:0] NextBeatCount; logic [AHBWLOGBWPL-1:0] NextBeatCount;
logic FinalBeatCount; logic FinalBeatCount;
logic [2:0] LocalBurstType; logic [2:0] LocalBurstType;
logic BeatCntEn; logic BeatCntEn;
logic BeatCntReset; logic BeatCntReset;
logic CacheAccess; logic CacheAccess;
always_ff @(posedge HCLK) always_ff @(posedge HCLK)
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE; if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
always_comb begin always_comb begin
case(CurrState) case(CurrState)
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
else if (HREADY & CacheBusRW[0]) NextState = CACHE_WRITEBACK; else if (HREADY & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
else NextState = ADR_PHASE; else NextState = ADR_PHASE;
DATA_PHASE: if(HREADY) NextState = MEM3; DATA_PHASE: if(HREADY) NextState = MEM3;
else NextState = DATA_PHASE; else NextState = DATA_PHASE;
MEM3: if(Stall) NextState = MEM3; MEM3: if(Stall) NextState = MEM3;
else NextState = ADR_PHASE; else NextState = ADR_PHASE;
CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK; CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
@ -98,8 +98,8 @@ module buscachefsm #(
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
else NextState = CACHE_WRITEBACK; else NextState = CACHE_WRITEBACK;
default: NextState = ADR_PHASE; default: NextState = ADR_PHASE;
endcase endcase
end end
// IEU, LSU, and IFU controls // IEU, LSU, and IFU controls
@ -117,8 +117,8 @@ module buscachefsm #(
assign CacheAccess = CurrState == CACHE_FETCH | CurrState == CACHE_WRITEBACK; assign CacheAccess = CurrState == CACHE_FETCH | CurrState == CACHE_WRITEBACK;
assign BusStall = (CurrState == ADR_PHASE & ((|BusRW) | (|CacheBusRW))) | assign BusStall = (CurrState == ADR_PHASE & ((|BusRW) | (|CacheBusRW))) |
//(CurrState == DATA_PHASE & ~BusRW[0]) | // *** replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem. //(CurrState == DATA_PHASE & ~BusRW[0]) | // *** replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem.
(CurrState == DATA_PHASE) | (CurrState == DATA_PHASE) |
(CurrState == CACHE_FETCH & ~HREADY) | (CurrState == CACHE_FETCH & ~HREADY) |
(CurrState == CACHE_WRITEBACK & ~HREADY); (CurrState == CACHE_WRITEBACK & ~HREADY);
assign BusCommitted = CurrState != ADR_PHASE; assign BusCommitted = CurrState != ADR_PHASE;
@ -144,7 +144,7 @@ module buscachefsm #(
// communication to cache // communication to cache
assign CacheBusAck = (CacheAccess & HREADY & FinalBeatCount); assign CacheBusAck = (CacheAccess & HREADY & FinalBeatCount);
assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | CacheBusRW[0])) | assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | CacheBusRW[0])) |
(CurrState == DATA_PHASE & BusRW[0]) | (CurrState == DATA_PHASE & BusRW[0]) |
(CurrState == CACHE_WRITEBACK) | (CurrState == CACHE_WRITEBACK) |
(CurrState == CACHE_FETCH); (CurrState == CACHE_FETCH);

View File

@ -57,20 +57,20 @@ module busfsm (
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
always_comb begin always_comb begin
case(CurrState) case(CurrState)
ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE; ADR_PHASE: if(HREADY & |BusRW) NextState = DATA_PHASE;
else NextState = ADR_PHASE; else NextState = ADR_PHASE;
DATA_PHASE: if(HREADY) NextState = MEM3; DATA_PHASE: if(HREADY) NextState = MEM3;
else NextState = DATA_PHASE; else NextState = DATA_PHASE;
MEM3: if(Stall) NextState = MEM3; MEM3: if(Stall) NextState = MEM3;
else NextState = ADR_PHASE; else NextState = ADR_PHASE;
default: NextState = ADR_PHASE; default: NextState = ADR_PHASE;
endcase endcase
end end
assign BusStall = (CurrState == ADR_PHASE & |BusRW) | assign BusStall = (CurrState == ADR_PHASE & |BusRW) |
// (CurrState == DATA_PHASE & ~BusRW[0]); // possible optimization here. fails uart test, but i'm not sure the failure is valid. // (CurrState == DATA_PHASE & ~BusRW[0]); // possible optimization here. fails uart test, but i'm not sure the failure is valid.
(CurrState == DATA_PHASE); (CurrState == DATA_PHASE);
assign BusCommitted = CurrState != ADR_PHASE; assign BusCommitted = CurrState != ADR_PHASE;

View File

@ -33,29 +33,29 @@
`include "wally-config.vh" `include "wally-config.vh"
module controllerinputstage #( module controllerinput #(
parameter SAVE_ENABLED = 1 // 1: Save manager inputs if Save = 1, 0: Don't save inputs parameter SAVE_ENABLED = 1 // 1: Save manager inputs if Save = 1, 0: Don't save inputs
)( )(
input logic HCLK, input logic HCLK,
input logic HRESETn, input logic HRESETn,
input logic Save, // Two or more managers requesting (HTRANS != 00) at the same time. Save the non-granted manager inputs input logic Save, // Two or more managers requesting (HTRANS != 00) at the same time. Save the non-granted manager inputs
input logic Restore, // Restore a saved manager inputs when it is finally granted input logic Restore, // Restore a saved manager inputs when it is finally granted
input logic Disable, // Supress HREADY to the non-granted manager input logic Disable, // Supress HREADY to the non-granted manager
output logic Request, // This manager is making a request output logic Request, // This manager is making a request
// controller input // controller input
input logic [1:0] HTRANSIn, // Manager input. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ input logic [1:0] HTRANSIn, // Manager input. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
input logic HWRITEIn, // Manager input. AHB 0: Read operation 1: Write operation input logic HWRITEIn, // Manager input. AHB 0: Read operation 1: Write operation
input logic [2:0] HSIZEIn, // Manager input. AHB transaction width input logic [2:0] HSIZEIn, // Manager input. AHB transaction width
input logic [2:0] HBURSTIn, // Manager input. AHB burst length input logic [2:0] HBURSTIn, // Manager input. AHB burst length
input logic [`PA_BITS-1:0] HADDRIn, // Manager input. AHB address input logic [`PA_BITS-1:0] HADDRIn, // Manager input. AHB address
output logic HREADYOut, // Indicate to manager the peripherial is not busy and another manager does not have priority output logic HREADYOut, // Indicate to manager the peripherial is not busy and another manager does not have priority
// controller output // controller output
output logic [1:0] HTRANSOut, // Aribrated manager transaction. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ output logic [1:0] HTRANSOut, // Aribrated manager transaction. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic HWRITEOut, // Aribrated manager transaction. AHB 0: Read operation 1: Write operation output logic HWRITEOut, // Aribrated manager transaction. AHB 0: Read operation 1: Write operation
output logic [2:0] HSIZEOut, // Aribrated manager transaction. AHB transaction width output logic [2:0] HSIZEOut, // Aribrated manager transaction. AHB transaction width
output logic [2:0] HBURSTOut, // Aribrated manager transaction. AHB burst length output logic [2:0] HBURSTOut, // Aribrated manager transaction. AHB burst length
output logic [`PA_BITS-1:0] HADDROut, // Aribrated manager transaction. AHB address output logic [`PA_BITS-1:0] HADDROut, // Aribrated manager transaction. AHB address
input logic HREADYIn // Peripherial ready input logic HREADYIn // Peripherial ready
); );
logic HWRITESave; logic HWRITESave;

View File

@ -52,27 +52,26 @@ module ebu (
output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority
// AHB-Lite external signals // AHB-Lite external signals
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
input logic HRESP, // AHB peripheral response. 0: OK 1: Error input logic HRESP, // AHB peripheral response. 0: OK 1: Error
output logic [`PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration output logic [`PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration
output logic [`AHBW-1:0] HWDATA, // AHB Write data after arbitration output logic [`AHBW-1:0] HWDATA, // AHB Write data after arbitration
output logic [`XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration output logic [`XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration
output logic HWRITE, // AHB transaction direction after arbitration output logic HWRITE, // AHB transaction direction after arbitration
output logic [2:0] HSIZE, // AHB transaction size after arbitration output logic [2:0] HSIZE, // AHB transaction size after arbitration
output logic [2:0] HBURST, // AHB burst length after arbitration output logic [2:0] HBURST, // AHB burst length after arbitration
output logic [3:0] HPROT, // AHB protection. Wally does not use output logic [3:0] HPROT, // AHB protection. Wally does not use
output logic [1:0] HTRANS, // AHB transaction request after arbitration output logic [1:0] HTRANS, // AHB transaction request after arbitration
output logic HMASTLOCK // AHB master lock. Wally does not use output logic HMASTLOCK // AHB master lock. Wally does not use
); );
logic LSUDisable; logic LSUDisable;
logic LSUSelect; logic LSUSelect;
logic IFUSave; logic IFUSave;
logic IFURestore; logic IFURestore;
logic IFUDisable; logic IFUDisable;
logic IFUSelect; logic IFUSelect;
logic [`PA_BITS-1:0] IFUHADDROut; logic [`PA_BITS-1:0] IFUHADDROut;
logic [1:0] IFUHTRANSOut; logic [1:0] IFUHTRANSOut;
@ -87,9 +86,7 @@ module ebu (
logic LSUHWRITEOut; logic LSUHWRITEOut;
logic IFUReq; logic IFUReq;
logic LSUReq; logic LSUReq;
assign HCLK = clk; assign HCLK = clk;
assign HRESETn = ~reset; assign HRESETn = ~reset;
@ -101,14 +98,14 @@ module ebu (
// input stages and muxing for IFU and LSU // input stages and muxing for IFU and LSU
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
controllerinputstage IFUInput(.HCLK, .HRESETn, .Save(IFUSave), .Restore(IFURestore), .Disable(IFUDisable), controllerinput IFUInput(.HCLK, .HRESETn, .Save(IFUSave), .Restore(IFURestore), .Disable(IFUDisable),
.Request(IFUReq), .Request(IFUReq),
.HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR), .HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR),
.HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY), .HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY),
.HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYIn(HREADY)); .HTRANSOut(IFUHTRANSOut), .HADDROut(IFUHADDROut), .HREADYIn(HREADY));
// LSU always has priority so there should never be a need to save and restore the address phase inputs. // LSU always has priority so there should never be a need to save and restore the address phase inputs.
controllerinputstage #(0) LSUInput(.HCLK, .HRESETn, .Save(1'b0), .Restore(1'b0), .Disable(LSUDisable), controllerinput #(0) LSUInput(.HCLK, .HRESETn, .Save(1'b0), .Restore(1'b0), .Disable(LSUDisable),
.Request(LSUReq), .Request(LSUReq),
.HWRITEIn(LSUHWRITE), .HSIZEIn(LSUHSIZE), .HBURSTIn(LSUHBURST), .HTRANSIn(LSUHTRANS), .HADDRIn(LSUHADDR), .HREADYOut(LSUHREADY), .HWRITEIn(LSUHWRITE), .HSIZEIn(LSUHSIZE), .HBURSTIn(LSUHBURST), .HTRANSIn(LSUHTRANS), .HADDRIn(LSUHADDR), .HREADYOut(LSUHREADY),
.HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut), .HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut),
@ -129,7 +126,7 @@ module ebu (
// HRDATA is sent to all controllers at the core level. // HRDATA is sent to all controllers at the core level.
ebufsmarb ebufsmarb(.HCLK, .HRESETn, .HBURST, .HREADY, .LSUReq, .IFUReq, .IFUSave, ebufsmarb ebufsmarb(.HCLK, .HRESETn, .HBURST, .HREADY, .LSUReq, .IFUReq, .IFUSave,
.IFURestore, .IFUDisable, .IFUSelect, .LSUDisable, .LSUSelect); .IFURestore, .IFUDisable, .IFUSelect, .LSUDisable, .LSUSelect);
endmodule endmodule

View File

@ -31,34 +31,33 @@
`include "wally-config.vh" `include "wally-config.vh"
module ebufsmarb ( module ebufsmarb (
input logic HCLK, input logic HCLK,
input logic HRESETn, input logic HRESETn,
input logic [2:0] HBURST, input logic [2:0] HBURST,
// AHB burst length // AHB burst length
input logic HREADY, input logic HREADY,
input logic LSUReq, input logic LSUReq,
input logic IFUReq, input logic IFUReq,
output logic IFUSave,
output logic IFURestore,
output logic IFUDisable,
output logic IFUSelect,
output logic LSUDisable,
output logic LSUSelect);
output logic IFUSave, typedef enum logic [1:0] {IDLE, ARBITRATE} statetype;
output logic IFURestore,
output logic IFUDisable,
output logic IFUSelect,
output logic LSUDisable,
output logic LSUSelect);
typedef enum logic [1:0] {IDLE, ARBITRATE} statetype;
statetype CurrState, NextState; statetype CurrState, NextState;
logic both; // Both the LSU and IFU request at the same time logic both; // Both the LSU and IFU request at the same time
logic IFUReqD; // 1 cycle delayed IFU request. Part of arbitration logic IFUReqD; // 1 cycle delayed IFU request. Part of arbitration
logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst
logic BeatCntEn; logic BeatCntEn;
logic [3:0] BeatCount; // Position within a burst transfer logic [3:0] BeatCount; // Position within a burst transfer
logic CntReset; logic BeatCntReset;
logic [3:0] Threshold; // Number of beats derived from HBURST logic [3:0] Threshold; // Number of beats derived from HBURST
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Aribtration scheme // Aribtration scheme
@ -70,8 +69,8 @@ module ebufsmarb (
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextState, IDLE, CurrState); flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextState, IDLE, CurrState);
always_comb always_comb
case (CurrState) case (CurrState)
IDLE: if (both) NextState = ARBITRATE; IDLE: if (both) NextState = ARBITRATE;
else NextState = IDLE; else NextState = IDLE;
ARBITRATE: if (HREADY & FinalBeatD & ~(LSUReq & IFUReq)) NextState = IDLE; ARBITRATE: if (HREADY & FinalBeatD & ~(LSUReq & IFUReq)) NextState = IDLE;
else NextState = ARBITRATE; else NextState = ARBITRATE;
default: NextState = IDLE; default: NextState = IDLE;
@ -98,29 +97,26 @@ module ebufsmarb (
// Burst mode logic // Burst mode logic
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
assign CntReset = NextState == IDLE; assign BeatCntReset = NextState == IDLE;
assign FinalBeat = (BeatCount == Threshold); // Detect when we are waiting on the final access. assign FinalBeat = (BeatCount == Threshold); // Detect when we are waiting on the final access.
// Counting the beats in the EBU is only necessary when both the LSU and IFU request concurrently.
// LSU has priority. HREADY serves double duty during a burst transaction. It indicates when the
// beat completes and when the transaction finishes. However there is nothing external to
// differentiate them. The EBU counts the HREADY beats so it knows when to switch to the IFU's
// request.
assign BeatCntEn = (NextState == ARBITRATE) & HREADY; assign BeatCntEn = (NextState == ARBITRATE) & HREADY;
counter #(4) BeatCounter(HCLK, ~HRESETn | CntReset | FinalBeat, BeatCntEn, BeatCount); counter #(4) BeatCounter(HCLK, ~HRESETn | BeatCntReset | FinalBeat, BeatCntEn, BeatCount);
// Used to store data from data phase of AHB. // Used to store data from data phase of AHB.
flopenr #(1) FinalBeatReg(HCLK, ~HRESETn | CntReset, BeatCntEn, FinalBeat, FinalBeatD); flopenr #(1) FinalBeatReg(HCLK, ~HRESETn | BeatCntReset, BeatCntEn, FinalBeat, FinalBeatD);
// unlike the bus fsm in lsu/ifu, we need to derive the number of beats from HBURST. // unlike the bus fsm in lsu/ifu, we need to derive the number of beats from HBURST, Threshold = num beats - 1.
// HBURST[2:1] Beats // HBURST[2:1] Beats threshold
// 00 1 // 00 1 0
// 01 4 // 01 4 3
// 10 8 // 10 8 7
// 11 16 // 11 16 15
always_comb always_comb
if (HBURST[2:1] == 2'b00) Threshold = 4'b0000; if (HBURST[2:1] == 2'b00) Threshold = 4'b0000;
else Threshold = (2 << HBURST[2:1]) - 1; else Threshold = (2 << HBURST[2:1]) - 1;
/* case(HBURST)
0: Threshold = 4'b0000;
3: Threshold = 4'b0011; // INCR4
5: Threshold = 4'b0111; // INCR8
7: Threshold = 4'b1111; // INCR16
default: Threshold = 4'b0000; // INCR without end.
endcase
end */
endmodule endmodule

View File

@ -31,53 +31,53 @@ module fctrl (
input logic clk, input logic clk,
input logic reset, input logic reset,
// input control signals // input control signals
input logic StallE, StallM, StallW, // stall signals input logic StallE, StallM, StallW, // stall signals
input logic FlushE, FlushM, FlushW, // flush signals input logic FlushE, FlushM, FlushW, // flush signals
input logic IntDivE, // is inteteger division input logic IntDivE, // is inteteger division
input logic [2:0] FRM_REGW, // rounding mode from CSR input logic [2:0] FRM_REGW, // rounding mode from CSR
input logic [1:0] STATUS_FS, // is FPU enabled? input logic [1:0] STATUS_FS, // is FPU enabled?
input logic FDivBusyE, // is the divider busy input logic FDivBusyE, // is the divider busy
// intruction // intruction
input logic [31:0] InstrD, // the full instruction input logic [31:0] InstrD, // the full instruction
input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision
input logic [6:0] OpD, // bits 6:0 of instruction input logic [6:0] OpD, // bits 6:0 of instruction
input logic [4:0] Rs2D, // bits 24:20 of instruction input logic [4:0] Rs2D, // bits 24:20 of instruction
input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode
// input mux selections // input mux selections
output logic XEnD, YEnD, ZEnD, // enable inputs output logic XEnD, YEnD, ZEnD, // enable inputs
output logic XEnE, YEnE, ZEnE, // enable inputs output logic XEnE, YEnE, ZEnE, // enable inputs
// opperation mux selections // opperation mux selections
output logic FCvtIntE, FCvtIntW, // convert to integer opperation output logic FCvtIntE, FCvtIntW, // convert to integer opperation
output logic [2:0] FrmM, // FP rounding mode output logic [2:0] FrmM, // FP rounding mode
output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format
output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component
output logic FpLoadStoreM, // FP load or store instruction output logic FpLoadStoreM, // FP load or store instruction
output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
// register control signals // register control signals
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
output logic FWriteIntE, FWriteIntM, // Write to integer register output logic FWriteIntE, FWriteIntM, // Write to integer register
output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input
output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input
// other control signals // other control signals
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
output logic FDivStartE, IDivStartE // Start division or squareroot output logic FDivStartE, IDivStartE // Start division or squareroot
); );
`define FCTRLW 12 `define FCTRLW 12
logic [`FCTRLW-1:0] ControlsD; // control signals logic [`FCTRLW-1:0] ControlsD; // control signals
logic FRegWriteD; // FP register write enable logic FRegWriteD; // FP register write enable
logic FDivStartD; // start division/sqrt logic FDivStartD; // start division/sqrt
logic FWriteIntD; // integer register write enable logic FWriteIntD; // integer register write enable
logic [2:0] OpCtrlD; // Select which opperation to do in each component logic [2:0] OpCtrlD; // Select which opperation to do in each component
logic [1:0] PostProcSelD; // select result in the post processing unit logic [1:0] PostProcSelD; // select result in the post processing unit
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
logic [2:0] FrmD, FrmE; // FP rounding mode logic [2:0] FrmD, FrmE; // FP rounding mode
logic [`FMTBITS-1:0] FmtD; // FP format logic [`FMTBITS-1:0] FmtD; // FP format
logic [1:0] Fmt; // format - before possible reduction logic [1:0] Fmt; // format - before possible reduction
logic SupportedFmt; // is the format supported logic SupportedFmt; // is the format supported
logic FCvtIntD, FCvtIntM; // convert to integer opperation logic FCvtIntD, FCvtIntM; // convert to integer opperation
// FPU Instruction Decoder // FPU Instruction Decoder
assign Fmt = Funct7D[1:0]; assign Fmt = Funct7D[1:0];

View File

@ -30,20 +30,20 @@
`include "wally-config.vh" `include "wally-config.vh"
module fcvt ( module fcvt (
input logic Xs, // input's sign input logic Xs, // input's sign
input logic [`NE-1:0] Xe, // input's exponent input logic [`NE-1:0] Xe, // input's exponent
input logic [`NF:0] Xm, // input's fraction input logic [`NF:0] Xm, // input's fraction
input logic [`XLEN-1:0] Int, // integer input - from IEU input logic [`XLEN-1:0] Int, // integer input - from IEU
input logic [2:0] OpCtrl, // choose which opperation (look below for values) input logic [2:0] OpCtrl, // choose which opperation (look below for values)
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic XZero, // is the input zero input logic XZero, // is the input zero
input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half) input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
output logic [`NE:0] Ce, // the calculated expoent output logic [`NE:0] Ce, // the calculated expoent
output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
output logic ResSubnormUf,// does the result underflow or is subnormal output logic ResSubnormUf,// does the result underflow or is subnormal
output logic Cs, // the result's sign output logic Cs, // the result's sign
output logic IntZero, // is the integer zero? output logic IntZero, // is the integer zero?
output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder) output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder)
); );
// OpCtrls: // OpCtrls:
@ -60,7 +60,7 @@ module fcvt (
logic [`XLEN-1:0] PosInt; // the positive integer input logic [`XLEN-1:0] PosInt; // the positive integer input
logic [`XLEN-1:0] TrimInt; // integer trimmed to the correct size logic [`XLEN-1:0] TrimInt; // integer trimmed to the correct size
logic [`NE-2:0] NewBias; // the bias of the final result logic [`NE-2:0] NewBias; // the bias of the final result
logic [`NE-1:0] OldExp; // the old exponent logic [`NE-1:0] OldExp; // the old exponent
logic Signed; // is the opperation with a signed integer? logic Signed; // is the opperation with a signed integer?
logic Int64; // is the integer 64 bits? logic Int64; // is the integer 64 bits?
logic IntToFp; // is the opperation an int->fp conversion? logic IntToFp; // is the opperation an int->fp conversion?

View File

@ -29,49 +29,49 @@
`include "wally-config.vh" `include "wally-config.vh"
module fdivsqrt( module fdivsqrt(
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic [`FMTBITS-1:0] FmtE, input logic [`FMTBITS-1:0] FmtE,
input logic XsE, input logic XsE,
input logic [`NF:0] XmE, YmE, input logic [`NF:0] XmE, YmE,
input logic [`NE-1:0] XeE, YeE, input logic [`NE-1:0] XeE, YeE,
input logic XInfE, YInfE, input logic XInfE, YInfE,
input logic XZeroE, YZeroE, input logic XZeroE, YZeroE,
input logic XNaNE, YNaNE, input logic XNaNE, YNaNE,
input logic FDivStartE, IDivStartE, input logic FDivStartE, IDivStartE,
input logic StallM, input logic StallM,
input logic FlushE, input logic FlushE,
input logic SqrtE, SqrtM, input logic SqrtE, SqrtM,
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B
input logic [2:0] Funct3E, Funct3M, input logic [2:0] Funct3E, Funct3M,
input logic IntDivE, W64E, input logic IntDivE, W64E,
output logic DivStickyM, output logic DivStickyM,
output logic FDivBusyE, IFDivStartE, FDivDoneE, output logic FDivBusyE, IFDivStartE, FDivDoneE,
output logic [`NE+1:0] QeM, output logic [`NE+1:0] QeM,
output logic [`DIVb:0] QmM, output logic [`DIVb:0] QmM,
output logic [`XLEN-1:0] FIntDivResultM output logic [`XLEN-1:0] FIntDivResultM
); );
// Floating-point division and square root module, with optional integer division and remainder // Floating-point division and square root module, with optional integer division and remainder
// Computes X/Y, sqrt(X), A/B, or A%B // Computes X/Y, sqrt(X), A/B, or A%B
logic [`DIVb+3:0] WS, WC; // Partial remainder components logic [`DIVb+3:0] WS, WC; // Partial remainder components
logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend) logic [`DIVb+3:0] X; // Iterator Initial Value (from dividend)
logic [`DIVb-1:0] DPreproc, D; // Iterator Divisor logic [`DIVb-1:0] DPreproc, D; // Iterator Divisor
logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values logic [`DIVb:0] FirstU, FirstUM; // Intermediate result values
logic [`DIVb+1:0] FirstC; // Step tracker logic [`DIVb+1:0] FirstC; // Step tracker
logic Firstun; // Quotient selection logic Firstun; // Quotient selection
logic WZeroE; // Early termination flag logic WZeroE; // Early termination flag
logic SpecialCaseM; // Divide by zero, square root of negative, etc. logic SpecialCaseM; // Divide by zero, square root of negative, etc.
logic DivStartE; // Enable signal for flops during stall logic DivStartE; // Enable signal for flops during stall
// Integer div/rem signals // Integer div/rem signals
logic BZeroM; // Denominator is zero logic BZeroM; // Denominator is zero
logic IntDivM; // Integer operation logic IntDivM; // Integer operation
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
logic ISpecialCaseE; // Integer div/remainder special cases logic ISpecialCaseE; // Integer div/remainder special cases
fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor fdivsqrtpreproc fdivsqrtpreproc( // Preprocessor
.clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE), .clk, .IFDivStartE, .Xm(XmE), .Ym(YmE), .Xe(XeE), .Ye(YeE),

View File

@ -37,7 +37,7 @@ module fdivsqrtpostproc(
input logic [`DIVb+1:0] FirstC, input logic [`DIVb+1:0] FirstC,
input logic SqrtE, input logic SqrtE,
input logic Firstun, SqrtM, SpecialCaseM, NegQuotM, input logic Firstun, SqrtM, SpecialCaseM, NegQuotM,
input logic [`XLEN-1:0] AM, input logic [`XLEN-1:0] AM,
input logic RemOpM, ALTBM, BZeroM, AsM, W64M, input logic RemOpM, ALTBM, BZeroM, AsM, W64M,
input logic [`DIVBLEN:0] nM, mM, input logic [`DIVBLEN:0] nM, mM,
output logic [`DIVb:0] QmM, output logic [`DIVb:0] QmM,
@ -46,11 +46,11 @@ module fdivsqrtpostproc(
output logic [`XLEN-1:0] FIntDivResultM output logic [`XLEN-1:0] FIntDivResultM
); );
logic [`DIVb+3:0] W, Sum, DM; logic [`DIVb+3:0] W, Sum, DM;
logic [`DIVb:0] PreQmM; logic [`DIVb:0] PreQmM;
logic NegStickyM; logic NegStickyM;
logic weq0E, WZeroM; logic weq0E, WZeroM;
logic [`XLEN-1:0] IntDivResultM; logic [`XLEN-1:0] IntDivResultM;
////////////////////////// //////////////////////////
// Execute Stage: Detect early termination for an exact result // Execute Stage: Detect early termination for an exact result

View File

@ -29,35 +29,35 @@
`include "wally-config.vh" `include "wally-config.vh"
module fdivsqrtpreproc ( module fdivsqrtpreproc (
input logic clk, input logic clk,
input logic IFDivStartE, input logic IFDivStartE,
input logic [`NF:0] Xm, Ym, input logic [`NF:0] Xm, Ym,
input logic [`NE-1:0] Xe, Ye, input logic [`NE-1:0] Xe, Ye,
input logic [`FMTBITS-1:0] Fmt, input logic [`FMTBITS-1:0] Fmt,
input logic Sqrt, input logic Sqrt,
input logic XZeroE, input logic XZeroE,
input logic [2:0] Funct3E, input logic [2:0] Funct3E,
output logic [`NE+1:0] QeM, output logic [`NE+1:0] QeM,
output logic [`DIVb+3:0] X, output logic [`DIVb+3:0] X,
output logic [`DIVb-1:0] DPreproc, output logic [`DIVb-1:0] DPreproc,
// Int-specific // Int-specific
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
input logic IntDivE, W64E, input logic IntDivE, W64E,
output logic ISpecialCaseE, output logic ISpecialCaseE,
output logic [`DIVBLEN:0] nE, nM, mM, output logic [`DIVBLEN:0] nE, nM, mM,
output logic NegQuotM, ALTBM, IntDivM, W64M, output logic NegQuotM, ALTBM, IntDivM, W64M,
output logic AsM, BZeroM, output logic AsM, BZeroM,
output logic [`XLEN-1:0] AM output logic [`XLEN-1:0] AM
); );
logic [`DIVb-1:0] XPreproc; logic [`DIVb-1:0] XPreproc;
logic [`DIVb:0] PreSqrtX; logic [`DIVb:0] PreSqrtX;
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
logic [`NE+1:0] QeE; // Quotient Exponent (FP only) logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
logic [`DIVb-1:0] IFNormLenX, IFNormLenD; // Correctly-sized inputs for iterator logic [`DIVb-1:0] IFNormLenX, IFNormLenD; // Correctly-sized inputs for iterator
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
logic NumerZeroE; // Numerator is zero (X or A) logic NumerZeroE; // Numerator is zero (X or A)
logic AZeroE, BZeroE; // A or B is Zero for integer division logic AZeroE, BZeroE; // A or B is Zero for integer division
if (`IDIV_ON_FPU) begin:intpreproc // Int Supported if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
logic signedDiv, NegQuotE; logic signedDiv, NegQuotE;

View File

@ -45,11 +45,11 @@ module fdivsqrtqsel2 (
assign g = ps & pc; assign g = ps & pc;
assign magnitude = ~((ps[2]^pc[2]) & (ps[1]^pc[1]) & assign magnitude = ~((ps[2]^pc[2]) & (ps[1]^pc[1]) &
(ps[0]^pc[0])); (ps[0]^pc[0]));
assign sign = (ps[3]^pc[3])^ assign sign = (ps[3]^pc[3])^
(ps[2] & pc[2] | ((ps[2]^pc[2]) & (ps[2] & pc[2] | ((ps[2]^pc[2]) &
(ps[1]&pc[1] | ((ps[1]^pc[1]) & (ps[1]&pc[1] | ((ps[1]^pc[1]) &
(ps[0]&pc[0]))))); (ps[0]&pc[0])))));
// Produce digit = +1, 0, or -1 // Produce digit = +1, 0, or -1
assign up = magnitude & ~sign; assign up = magnitude & ~sign;

View File

@ -32,21 +32,21 @@ module fdivsqrtqsel4 (
input logic [2:0] Dmsbs, input logic [2:0] Dmsbs,
input logic [4:0] Smsbs, input logic [4:0] Smsbs,
input logic [7:0] WSmsbs, WCmsbs, input logic [7:0] WSmsbs, WCmsbs,
input logic Sqrt, j1, input logic Sqrt, j1,
output logic [3:0] udigit output logic [3:0] udigit
); );
logic [6:0] Wmsbs; logic [6:0] Wmsbs;
logic [7:0] PreWmsbs; logic [7:0] PreWmsbs;
logic [2:0] A; logic [2:0] A;
assign PreWmsbs = WCmsbs + WSmsbs; assign PreWmsbs = WCmsbs + WSmsbs;
assign Wmsbs = PreWmsbs[7:1]; assign Wmsbs = PreWmsbs[7:1];
// D = 0001.xxx... // D = 0001.xxx...
// Dmsbs = | | // Dmsbs = | |
// W = xxxx.xxx... // W = xxxx.xxx...
// Wmsbs = | | // Wmsbs = | |
logic [3:0] USel4[1023:0]; logic [3:0] USel4[1023:0];
// Prepopulate selection table; this is constant at compile time // Prepopulate selection table; this is constant at compile time
always_comb begin always_comb begin
@ -109,5 +109,5 @@ module fdivsqrtqsel4 (
end else A = Dmsbs; end else A = Dmsbs;
// Select quotient digit from lookup table based on A and W // Select quotient digit from lookup table based on A and W
assign udigit = USel4[{A,Wmsbs}]; assign udigit = USel4[{A,Wmsbs}];
endmodule endmodule

View File

@ -32,19 +32,19 @@ module fdivsqrtqsel4cmp (
input logic [2:0] Dmsbs, input logic [2:0] Dmsbs,
input logic [4:0] Smsbs, input logic [4:0] Smsbs,
input logic [7:0] WSmsbs, WCmsbs, input logic [7:0] WSmsbs, WCmsbs,
input logic SqrtE, j1, input logic SqrtE, j1,
output logic [3:0] udigit output logic [3:0] udigit
); );
logic [6:0] Wmsbs; logic [6:0] Wmsbs;
logic [7:0] PreWmsbs; logic [7:0] PreWmsbs;
logic [2:0] A; logic [2:0] A;
assign PreWmsbs = WCmsbs + WSmsbs; assign PreWmsbs = WCmsbs + WSmsbs;
assign Wmsbs = PreWmsbs[7:1]; assign Wmsbs = PreWmsbs[7:1];
// D = 0001.xxx... // D = 0001.xxx...
// Dmsbs = | | // Dmsbs = | |
// W = xxxx.xxx... // W = xxxx.xxx...
// Wmsbs = | | // Wmsbs = | |
logic [6:0] mk2, mk1, mk0, mkm1; logic [6:0] mk2, mk1, mk0, mkm1;
logic [6:0] mks2[7:0], mks1[7:0]; logic [6:0] mks2[7:0], mks1[7:0];

View File

@ -31,32 +31,32 @@
/* verilator lint_off UNOPTFLAT */ /* verilator lint_off UNOPTFLAT */
module fdivsqrtstage2 ( module fdivsqrtstage2 (
input logic [`DIVb-1:0] D, input logic [`DIVb-1:0] D,
input logic [`DIVb+3:0] DBar, input logic [`DIVb+3:0] DBar,
input logic [`DIVb:0] U, UM, input logic [`DIVb:0] U, UM,
input logic [`DIVb+3:0] WS, WC, input logic [`DIVb+3:0] WS, WC,
input logic [`DIVb+1:0] C, input logic [`DIVb+1:0] C,
input logic SqrtE, input logic SqrtE,
output logic un, output logic un,
output logic [`DIVb+1:0] CNext, output logic [`DIVb+1:0] CNext,
output logic [`DIVb:0] UNext, UMNext, output logic [`DIVb:0] UNext, UMNext,
output logic [`DIVb+3:0] WSNext, WCNext output logic [`DIVb+3:0] WSNext, WCNext
); );
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
logic [`DIVb+3:0] Dsel; logic [`DIVb+3:0] Dsel;
logic up, uz; logic up, uz;
logic [`DIVb+3:0] F; logic [`DIVb+3:0] F;
logic [`DIVb+3:0] AddIn; logic [`DIVb+3:0] AddIn;
logic [`DIVb+3:0] WSA, WCA; logic [`DIVb+3:0] WSA, WCA;
// Qmient Selection logic // Qmient Selection logic
// Given partial remainder, select digit of +1, 0, or -1 (up, uz, un) // Given partial remainder, select digit of +1, 0, or -1 (up, uz, un)
// q encoding: // q encoding:
// 1000 = +2 // 1000 = +2
// 0100 = +1 // 0100 = +1
// 0000 = 0 // 0000 = 0
// 0010 = -1 // 0010 = -1
// 0001 = -2 // 0001 = -2
fdivsqrtqsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], up, uz, un); fdivsqrtqsel2 qsel2(WS[`DIVb+3:`DIVb], WC[`DIVb+3:`DIVb], up, uz, un);
// Sqrt F generation. Extend C, U, UM to Q4.k // Sqrt F generation. Extend C, U, UM to Q4.k

View File

@ -30,34 +30,34 @@
module fdivsqrtstage4 ( module fdivsqrtstage4 (
input logic [`DIVb-1:0] D, input logic [`DIVb-1:0] D,
input logic [`DIVb+3:0] DBar, D2, DBar2, input logic [`DIVb+3:0] DBar, D2, DBar2,
input logic [`DIVb:0] U, UM, input logic [`DIVb:0] U,UM,
input logic [`DIVb+3:0] WS, WC, input logic [`DIVb+3:0] WS, WC,
input logic [`DIVb+1:0] C, input logic [`DIVb+1:0] C,
input logic SqrtE, j1, input logic SqrtE, j1,
output logic [`DIVb+1:0] CNext, output logic [`DIVb+1:0] CNext,
output logic un, output logic un,
output logic [`DIVb:0] UNext, UMNext, output logic [`DIVb:0] UNext, UMNext,
output logic [`DIVb+3:0] WSNext, WCNext output logic [`DIVb+3:0] WSNext, WCNext
); );
logic [`DIVb+3:0] Dsel; logic [`DIVb+3:0] Dsel;
logic [3:0] udigit; logic [3:0] udigit;
logic [`DIVb+3:0] F; logic [`DIVb+3:0] F;
logic [`DIVb+3:0] AddIn; logic [`DIVb+3:0] AddIn;
logic [4:0] Smsbs; logic [4:0] Smsbs;
logic [2:0] Dmsbs; logic [2:0] Dmsbs;
logic [7:0] WCmsbs, WSmsbs; logic [7:0] WCmsbs, WSmsbs;
logic CarryIn; logic CarryIn;
logic [`DIVb+3:0] WSA, WCA; logic [`DIVb+3:0] WSA, WCA;
// Digit Selection logic // Digit Selection logic
// u encoding: // u encoding:
// 1000 = +2 // 1000 = +2
// 0100 = +1 // 0100 = +1
// 0000 = 0 // 0000 = 0
// 0010 = -1 // 0010 = -1
// 0001 = -2 // 0001 = -2
assign Smsbs = U[`DIVb:`DIVb-4]; assign Smsbs = U[`DIVb:`DIVb-4];
assign Dmsbs = D[`DIVb-1:`DIVb-3]; assign Dmsbs = D[`DIVb-1:`DIVb-3];
assign WCmsbs = WC[`DIVb+3:`DIVb-4]; assign WCmsbs = WC[`DIVb+3:`DIVb-4];

View File

@ -32,12 +32,12 @@
module fmalza #(WIDTH) ( module fmalza #(WIDTH) (
input logic [WIDTH-1:0] A, // addend input logic [WIDTH-1:0] A, // addend
input logic [2*`NF+1:0] Pm, // product input logic [2*`NF+1:0] Pm, // product
input logic Cin, // carry in input logic Cin, // carry in
input logic sub, // subtraction input logic sub, // subtraction
output logic [$clog2(WIDTH+1)-1:0] SCnt // normalization shift count for the positive result output logic [$clog2(WIDTH+1)-1:0] SCnt // normalization shift count for the positive result
); );
logic [WIDTH:0] F; // most significant bit of F indicates leading digit logic [WIDTH:0] F; // most significant bit of F indicates leading digit
logic [WIDTH-1:0] B; // zero-extended product with same size as aligned A logic [WIDTH-1:0] B; // zero-extended product with same size as aligned A
logic [WIDTH-1:0] P, G, K; // propagate, generate, kill for each column logic [WIDTH-1:0] P, G, K; // propagate, generate, kill for each column
logic [WIDTH-1:0] Pp1, Gm1, Km1; // propagate shifted right by 1, generate/kill shifted left 1 logic [WIDTH-1:0] Pp1, Gm1, Km1; // propagate shifted right by 1, generate/kill shifted left 1

View File

@ -29,40 +29,40 @@
`include "wally-config.vh" `include "wally-config.vh"
module fpu ( module fpu (
input logic clk, input logic clk,
input logic reset, input logic reset,
// Hazards // Hazards
input logic StallE, StallM, StallW, // stall signals (from HZU) input logic StallE, StallM, StallW, // stall signals (from HZU)
input logic FlushE, FlushM, FlushW, // flush signals (from HZU) input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
output logic FPUStallD, // Stall the decode stage (To HZU) output logic FPUStallD, // Stall the decode stage (To HZU)
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU) output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU)
// CSRs // CSRs
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit) input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
input logic [2:0] FRM_REGW, // Rounding mode (from CSR) input logic [2:0] FRM_REGW, // Rounding mode (from CSR)
// Decode stage // Decode stage
input logic [31:0] InstrD, // instruction (from IFU) input logic [31:0] InstrD, // instruction (from IFU)
// Execute stage // Execute stage
input logic [2:0] Funct3E, // Funct fields of instruction specify type of operations input logic [2:0] Funct3E, // Funct fields of instruction specify type of operations
input logic IntDivE, W64E, // Integer division on FPU input logic IntDivE, W64E, // Integer division on FPU
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input for convert, move, and int div (from IEU) input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input for convert, move, and int div (from IEU)
input logic [4:0] RdE, // which FP register to write to (from IEU) input logic [4:0] RdE, // which FP register to write to (from IEU)
output logic FWriteIntE, // integer register write enable (to IEU) output logic FWriteIntE, // integer register write enable (to IEU)
output logic FCvtIntE, // Convert to int (to IEU) output logic FCvtIntE, // Convert to int (to IEU)
// Memory stage // Memory stage
input logic [2:0] Funct3M, // Funct fields of instruction specify type of operations input logic [2:0] Funct3M, // Funct fields of instruction specify type of operations
input logic [4:0] RdM, // which FP register to write to (from IEU) input logic [4:0] RdM, // which FP register to write to (from IEU)
output logic FRegWriteM, // FP register write enable (to privileged unit) output logic FRegWriteM, // FP register write enable (to privileged unit)
output logic FpLoadStoreM, // Fp load instruction? (to LSU) output logic FpLoadStoreM, // Fp load instruction? (to LSU)
output logic [`FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU) output logic [`FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU)
output logic [`XLEN-1:0] FIntResM, // data to be written to integer register (to IEU) output logic [`XLEN-1:0] FIntResM, // data to be written to integer register (to IEU)
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to IFU) output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to IFU)
output logic [4:0] SetFflagsM, // FPU flags (to privileged unit) output logic [4:0] SetFflagsM, // FPU flags (to privileged unit)
// Writeback stage // Writeback stage
input logic [4:0] RdW, // which FP register to write to (from IEU) input logic [4:0] RdW, // which FP register to write to (from IEU)
input logic [`FLEN-1:0] ReadDataW, // Read data (from LSU) input logic [`FLEN-1:0] ReadDataW, // Read data (from LSU)
output logic [`XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU) output logic [`XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU)
output logic FCvtIntW, // select FCvtIntRes (to IEU) output logic FCvtIntW, // select FCvtIntRes (to IEU)
output logic [`XLEN-1:0] FIntDivResultW // Result from integer division (to IEU) output logic [`XLEN-1:0] FIntDivResultW // Result from integer division (to IEU)
); );
// RISC-V FPU specifics: // RISC-V FPU specifics:
@ -70,97 +70,97 @@ module fpu (
// - RISC-V detects underflow after rounding // - RISC-V detects underflow after rounding
// control signals // control signals
logic FRegWriteW; // FP register write enable logic FRegWriteW; // FP register write enable
logic [2:0] FrmM; // FP rounding mode logic [2:0] FrmM; // FP rounding mode
logic [`FMTBITS-1:0] FmtE, FmtM; // FP precision 0-single 1-double logic [`FMTBITS-1:0] FmtE, FmtM; // FP precision 0-single 1-double
logic FDivStartE, IDivStartE; // Start division or squareroot logic FDivStartE, IDivStartE; // Start division or squareroot
logic FWriteIntM; // Write to integer register logic FWriteIntM; // Write to integer register
logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals
logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input
logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input
logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
logic FRegWriteE; // Write floating-point register logic FRegWriteE; // Write floating-point register
// regfile signals // regfile signals
logic [`FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage logic [`FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage
logic [`FLEN-1:0] FRD1E, FRD2E, FRD3E; // Read Data from FP register - execute stage logic [`FLEN-1:0] FRD1E, FRD2E, FRD3E; // Read Data from FP register - execute stage
logic [`FLEN-1:0] XE; // Input 1 to the various units (after forwarding) logic [`FLEN-1:0] XE; // Input 1 to the various units (after forwarding)
logic [`XLEN-1:0] IntSrcXE; // Input 1 to the various units (after forwarding) logic [`XLEN-1:0] IntSrcXE; // Input 1 to the various units (after forwarding)
logic [`FLEN-1:0] PreYE, YE; // Input 2 to the various units (after forwarding) logic [`FLEN-1:0] PreYE, YE; // Input 2 to the various units (after forwarding)
logic [`FLEN-1:0] PreZE, ZE; // Input 3 to the various units (after forwarding) logic [`FLEN-1:0] PreZE, ZE; // Input 3 to the various units (after forwarding)
// unpacking signals // unpacking signals
logic XsE, YsE, ZsE; // input's sign - execute stage logic XsE, YsE, ZsE; // input's sign - execute stage
logic XsM, YsM; // input's sign - memory stage logic XsM, YsM; // input's sign - memory stage
logic [`NE-1:0] XeE, YeE, ZeE; // input's exponent - execute stage logic [`NE-1:0] XeE, YeE, ZeE; // input's exponent - execute stage
logic [`NE-1:0] ZeM; // input's exponent - memory stage logic [`NE-1:0] ZeM; // input's exponent - memory stage
logic [`NF:0] XmE, YmE, ZmE; // input's significand - execute stage logic [`NF:0] XmE, YmE, ZmE; // input's significand - execute stage
logic [`NF:0] XmM, YmM, ZmM; // input's significand - memory stage logic [`NF:0] XmM, YmM, ZmM; // input's significand - memory stage
logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage
logic XNaNM, YNaNM, ZNaNM; // is the input a NaN - memory stage logic XNaNM, YNaNM, ZNaNM; // is the input a NaN - memory stage
logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage
logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage
logic XSubnormE; // is the input subnormal logic XSubnormE; // is the input subnormal
logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage
logic XZeroM, YZeroM; // is the input zero - memory stage logic XZeroM, YZeroM; // is the input zero - memory stage
logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage
logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage
logic XExpMaxE; // is the exponent all ones (max value) logic XExpMaxE; // is the exponent all ones (max value)
logic [`FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations logic [`FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations
// Fma Signals // Fma Signals
logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting
logic [1:0] FmaZSelE; // Select Z = Y when adding or subtracting, 0 when multiplying logic [1:0] FmaZSelE; // Select Z = Y when adding or subtracting, 0 when multiplying
logic [3*`NF+3:0] SmE, SmM; // Sum significand logic [3*`NF+3:0] SmE, SmM; // Sum significand
logic FmaAStickyE, FmaAStickyM; // FMA addend sticky bit output logic FmaAStickyE, FmaAStickyM; // FMA addend sticky bit output
logic [`NE+1:0] SeE,SeM; // Sum exponent logic [`NE+1:0] SeE,SeM; // Sum exponent
logic InvAE, InvAM; // Invert addend logic InvAE, InvAM; // Invert addend
logic AsE, AsM; // Addend sign logic AsE, AsM; // Addend sign
logic PsE, PsM; // Product sign logic PsE, PsM; // Product sign
logic SsE, SsM; // Sum sign logic SsE, SsM; // Sum sign
logic [$clog2(3*`NF+5)-1:0] SCntE, SCntM; // LZA sum leading zero count logic [$clog2(3*`NF+5)-1:0] SCntE, SCntM; // LZA sum leading zero count
// Cvt Signals // Cvt Signals
logic [`NE:0] CeE, CeM; // convert intermediate expoent logic [`NE:0] CeE, CeM; // convert intermediate expoent
logic [`LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by logic [`LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
logic CsE, CsM; // convert result sign logic CsE, CsM; // convert result sign
logic IntZeroE, IntZeroM; // is the integer zero? logic IntZeroE, IntZeroM; // is the integer zero?
logic [`CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder) logic [`CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder)
logic [`XLEN-1:0] FCvtIntResM; // fcvt integer result (for IEU) logic [`XLEN-1:0] FCvtIntResM; // fcvt integer result (for IEU)
// divide signals // divide signals
logic [`DIVb:0] QmM; // fdivsqrt signifcand logic [`DIVb:0] QmM; // fdivsqrt signifcand
logic [`NE+1:0] QeM; // fdivsqrt exponent logic [`NE+1:0] QeM; // fdivsqrt exponent
logic DivStickyM; // fdivsqrt sticky bit logic DivStickyM; // fdivsqrt sticky bit
logic FDivDoneE, IFDivStartE; // fdivsqrt control signals logic FDivDoneE, IFDivStartE; // fdivsqrt control signals
logic [`XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU) logic [`XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU)
// result and flag signals // result and flag signals
logic [`XLEN-1:0] ClassResE; // classify result logic [`XLEN-1:0] ClassResE; // classify result
logic [`FLEN-1:0] CmpFpResE; // compare result to FPU (min/max) logic [`FLEN-1:0] CmpFpResE; // compare result to FPU (min/max)
logic [`XLEN-1:0] CmpIntResE; // compare result to IEU (eq/lt/le) logic [`XLEN-1:0] CmpIntResE; // compare result to IEU (eq/lt/le)
logic CmpNVE; // compare invalid flag (Not Valid) logic CmpNVE; // compare invalid flag (Not Valid)
logic [`FLEN-1:0] SgnResE; // sign injection result logic [`FLEN-1:0] SgnResE; // sign injection result
logic [`XLEN-1:0] FIntResE; // FPU to IEU E-stage result (classify, compare, move) logic [`XLEN-1:0] FIntResE; // FPU to IEU E-stage result (classify, compare, move)
logic [`FLEN-1:0] PostProcResM; // Postprocessor output logic [`FLEN-1:0] PostProcResM; // Postprocessor output
logic [4:0] PostProcFlgM; // Postprocessor flags logic [4:0] PostProcFlgM; // Postprocessor flags
logic PreNVE, PreNVM; // selected flag that is ready in the memory stage logic PreNVE, PreNVM; // selected flag that is ready in the memory stage
logic [`FLEN-1:0] FpResM, FpResW; // FPU preliminary result logic [`FLEN-1:0] FpResM, FpResW; // FPU preliminary result
logic [`FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage logic [`FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage
logic [`FLEN-1:0] FResultW; // final FP result being written to the FP register logic [`FLEN-1:0] FResultW; // final FP result being written to the FP register
// other signals // other signals
logic [`FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv logic [`FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv
logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
logic [`FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed logic [`FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed
logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt
logic [`FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer logic [`FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer
logic mvsgn; // sign bit for extending move logic mvsgn; // sign bit for extending move
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Decode Stage: fctrl decoder, read register file // Decode Stage: fctrl decoder, read register file

View File

@ -29,8 +29,8 @@
`include "wally-config.vh" `include "wally-config.vh"
module fregfile ( module fregfile (
input logic clk, reset, input logic clk, reset,
input logic we4, // write enable input logic we4, // write enable
input logic [4:0] a1, a2, a3, a4, // adresses input logic [4:0] a1, a2, a3, a4, // adresses
input logic [`FLEN-1:0] wd4, // write data input logic [`FLEN-1:0] wd4, // write data
output logic [`FLEN-1:0] rd1, rd2, rd3 // read data output logic [`FLEN-1:0] rd1, rd2, rd3 // read data

View File

@ -29,43 +29,43 @@
`include "wally-config.vh" `include "wally-config.vh"
module fsgninj ( module fsgninj (
input logic Xs, Ys, // X and Y sign bits input logic Xs, Ys, // X and Y sign bits
input logic [`FLEN-1:0] X, // X input logic [`FLEN-1:0] X, // X
input logic [`FMTBITS-1:0] Fmt, // format input logic [`FMTBITS-1:0] Fmt, // format
input logic [1:0] OpCtrl, // operation control input logic [1:0] OpCtrl, // operation control
output logic [`FLEN-1:0] SgnRes // result output logic [`FLEN-1:0] SgnRes // result
); );
logic ResSgn; // result sign logic ResSgn; // result sign
// OpCtrl: // OpCtrl:
// 00 - fsgnj - directly copy over sign value of Y // 00 - fsgnj - directly copy over sign value of Y
// 01 - fsgnjn - negate sign value of Y // 01 - fsgnjn - negate sign value of Y
// 10 - fsgnjx - XOR sign values of X and Y // 10 - fsgnjx - XOR sign values of X and Y
// calculate the result's sign // calculate the result's sign
assign ResSgn = (OpCtrl[1] ? Xs : OpCtrl[0]) ^ Ys; assign ResSgn = (OpCtrl[1] ? Xs : OpCtrl[0]) ^ Ys;
// format final result based on precision // format final result based on precision
// - uses NaN-blocking format // - uses NaN-blocking format
// - if there are any unsused bits the most significant bits are filled with 1s // - if there are any unsused bits the most significant bits are filled with 1s
if (`FPSIZES == 1) if (`FPSIZES == 1)
assign SgnRes = {ResSgn, X[`FLEN-2:0]}; assign SgnRes = {ResSgn, X[`FLEN-2:0]};
else if (`FPSIZES == 2) else if (`FPSIZES == 2)
assign SgnRes = {~Fmt|ResSgn, X[`FLEN-2:`LEN1], Fmt ? X[`LEN1-1] : ResSgn, X[`LEN1-2:0]}; assign SgnRes = {~Fmt|ResSgn, X[`FLEN-2:`LEN1], Fmt ? X[`LEN1-1] : ResSgn, X[`LEN1-2:0]};
else if (`FPSIZES == 3) begin else if (`FPSIZES == 3) begin
logic [2:0] SgnBits; logic [2:0] SgnBits;
always_comb always_comb
case (Fmt) case (Fmt)
`FMT: SgnBits = {ResSgn, X[`LEN1-1], X[`LEN2-1]}; `FMT: SgnBits = {ResSgn, X[`LEN1-1], X[`LEN2-1]};
`FMT1: SgnBits = {1'b1, ResSgn, X[`LEN2-1]}; `FMT1: SgnBits = {1'b1, ResSgn, X[`LEN2-1]};
`FMT2: SgnBits = {2'b11, ResSgn}; `FMT2: SgnBits = {2'b11, ResSgn};
default: SgnBits = {3{1'bx}}; default: SgnBits = {3{1'bx}};
endcase endcase
assign SgnRes = {SgnBits[2], X[`FLEN-2:`LEN1], SgnBits[1], X[`LEN1-2:`LEN2], SgnBits[0], X[`LEN2-2:0]}; assign SgnRes = {SgnBits[2], X[`FLEN-2:`LEN1], SgnBits[1], X[`LEN1-2:`LEN2], SgnBits[0], X[`LEN2-2:0]};
end else if (`FPSIZES == 4) begin end else if (`FPSIZES == 4) begin
logic [3:0] SgnBits; logic [3:0] SgnBits;
always_comb always_comb
case (Fmt) case (Fmt)
`Q_FMT: SgnBits = {ResSgn, X[`D_LEN-1], X[`S_LEN-1], X[`H_LEN-1]}; `Q_FMT: SgnBits = {ResSgn, X[`D_LEN-1], X[`S_LEN-1], X[`H_LEN-1]};
@ -73,7 +73,7 @@ module fsgninj (
`S_FMT: SgnBits = {2'b11, ResSgn, X[`H_LEN-1]}; `S_FMT: SgnBits = {2'b11, ResSgn, X[`H_LEN-1]};
`H_FMT: SgnBits = {3'b111, ResSgn}; `H_FMT: SgnBits = {3'b111, ResSgn};
endcase endcase
assign SgnRes = {SgnBits[3], X[`Q_LEN-2:`D_LEN], SgnBits[2], X[`D_LEN-2:`S_LEN], SgnBits[1], X[`S_LEN-2:`H_LEN], SgnBits[0], X[`H_LEN-2:0]}; assign SgnRes = {SgnBits[3], X[`Q_LEN-2:`D_LEN], SgnBits[2], X[`D_LEN-2:`S_LEN], SgnBits[1], X[`S_LEN-2:`H_LEN], SgnBits[0], X[`H_LEN-2:0]};
end end
endmodule endmodule

View File

@ -30,13 +30,13 @@
`include "wally-config.vh" `include "wally-config.vh"
module arrs( module arrs(
input logic clk, input logic clk,
input logic areset, input logic areset,
output logic reset output logic reset
); );
logic metaStable; logic metaStable;
logic resetB; logic resetB;
always_ff @(posedge clk , posedge areset) begin always_ff @(posedge clk , posedge areset) begin
if (areset) begin if (areset) begin

View File

@ -27,9 +27,9 @@
`include "wally-config.vh" `include "wally-config.vh"
module clockgater ( module clockgater (
input logic E, input logic E,
input logic SE, input logic SE,
input logic CLK, input logic CLK,
output logic ECLK output logic ECLK
); );
@ -39,10 +39,10 @@ module clockgater (
// VERY IMPORTANT. // VERY IMPORTANT.
// This part functionally models a clock gater, but does not necessarily meet the timing constrains a real standard cell would. // This part functionally models a clock gater, but does not necessarily meet the timing constrains a real standard cell would.
// Do not use this in synthesis! // Do not use this in synthesis!
logic enable_q; logic enable_q;
always_latch begin always_latch begin
if(~CLK) begin if(~CLK) begin
enable_q <= E | SE; enable_q <= E | SE;
end end
end end
assign ECLK = enable_q & CLK; assign ECLK = enable_q & CLK;

View File

@ -49,39 +49,39 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) (
// *************************************************************************** // ***************************************************************************
// TRUE SRAM macro // TRUE SRAM macro
// *************************************************************************** // ***************************************************************************
if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray if ((`USE_SRAM == 1) & (WIDTH == 128) & (DEPTH == 64)) begin // Cache data subarray
genvar index; genvar index;
// 64 x 128-bit SRAM // 64 x 128-bit SRAM
logic [WIDTH-1:0] BitWriteMask; logic [WIDTH-1:0] BitWriteMask;
for (index=0; index < WIDTH; index++) for (index=0; index < WIDTH; index++)
assign BitWriteMask[index] = bwe[index/8]; assign BitWriteMask[index] = bwe[index/8];
ram1p1rwbe_64x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we), ram1p1rwbe_64x128 sram1A (.CLK(clk), .CEB(~ce), .WEB(~we),
.A(addr), .D(din), .A(addr), .D(din),
.BWEB(~BitWriteMask), .Q(dout)); .BWEB(~BitWriteMask), .Q(dout));
end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag end else if ((`USE_SRAM == 1) & (WIDTH == 44) & (DEPTH == 64)) begin // RV64 cache tag
genvar index; genvar index;
// 64 x 44-bit SRAM // 64 x 44-bit SRAM
logic [WIDTH-1:0] BitWriteMask; logic [WIDTH-1:0] BitWriteMask;
for (index=0; index < WIDTH; index++) for (index=0; index < WIDTH; index++)
assign BitWriteMask[index] = bwe[index/8]; assign BitWriteMask[index] = bwe[index/8];
ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we), ram1p1rwbe_64x44 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
.A(addr), .D(din), .A(addr), .D(din),
.BWEB(~BitWriteMask), .Q(dout)); .BWEB(~BitWriteMask), .Q(dout));
end else if ((`USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag end else if ((`USE_SRAM == 1) & (WIDTH == 22) & (DEPTH == 64)) begin // RV32 cache tag
genvar index; genvar index;
// 64 x 22-bit SRAM // 64 x 22-bit SRAM
logic [WIDTH-1:0] BitWriteMask; logic [WIDTH-1:0] BitWriteMask;
for (index=0; index < WIDTH; index++) for (index=0; index < WIDTH; index++)
assign BitWriteMask[index] = bwe[index/8]; assign BitWriteMask[index] = bwe[index/8];
ram1p1rwbe_64x22 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we), ram1p1rwbe_64x22 sram1B (.CLK(clk), .CEB(~ce), .WEB(~we),
.A(addr), .D(din), .A(addr), .D(din),
.BWEB(~BitWriteMask), .Q(dout)); .BWEB(~BitWriteMask), .Q(dout));
// *************************************************************************** // ***************************************************************************
// READ first SRAM model // READ first SRAM model
// *************************************************************************** // ***************************************************************************
end else begin: ram end else begin: ram
integer i; integer i;
@ -91,13 +91,12 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) (
assign dout = RAM[addrd]; assign dout = RAM[addrd];
/* // Read /* // Read
always_ff @(posedge clk) always_ff @(posedge clk)
if(ce) dout <= #1 mem[addr]; */ if(ce) dout <= #1 mem[addr]; */
// Write divided into part for bytes and part for extra msbs // Write divided into part for bytes and part for extra msbs
// Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff. // Questa sim version 2022.3_2 does not allow multiple drivers for RAM when using always_ff.
// Therefore these always blocks use the older always @(posedge clk) // Therefore these always blocks use the older always @(posedge clk)
if(WIDTH >= 8) if(WIDTH >= 8)
always @(posedge clk) always @(posedge clk)
if (ce & we) if (ce & we)

View File

@ -26,7 +26,7 @@
module ram1p1rwbe_64x128( module ram1p1rwbe_64x128(
input logic CLK, input logic CLK,
input logic CEB, input logic CEB,
input logic WEB, input logic WEB,
input logic [5:0] A, input logic [5:0] A,
input logic [127:0] D, input logic [127:0] D,

View File

@ -26,7 +26,7 @@
module ram1p1rwbe_64x22( module ram1p1rwbe_64x22(
input logic CLK, input logic CLK,
input logic CEB, input logic CEB,
input logic WEB, input logic WEB,
input logic [5:0] A, input logic [5:0] A,
input logic [21:0] D, input logic [21:0] D,

View File

@ -26,7 +26,7 @@
module ram1p1rwbe_64x44( module ram1p1rwbe_64x44(
input logic CLK, input logic CLK,
input logic CEB, input logic CEB,
input logic WEB, input logic WEB,
input logic [5:0] A, input logic [5:0] A,
input logic [43:0] D, input logic [43:0] D,

View File

@ -44,96 +44,94 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) (
output logic [WIDTH-1:0] rd1 output logic [WIDTH-1:0] rd1
); );
logic [WIDTH-1:0] mem[DEPTH-1:0]; logic [WIDTH-1:0] mem[DEPTH-1:0];
localparam SRAMWIDTH = 32; localparam SRAMWIDTH = 32;
localparam SRAMNUMSETS = SRAMWIDTH/WIDTH; localparam SRAMNUMSETS = SRAMWIDTH/WIDTH;
// *************************************************************************** // ***************************************************************************
// TRUE Smem macro // TRUE Smem macro
// *************************************************************************** // ***************************************************************************
if ((`USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin if ((`USE_SRAM == 1) & (WIDTH == 68) & (DEPTH == 1024)) begin
ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk), ram2p1r1wbe_1024x68 memory1(.CLKA(clk), .CLKB(clk),
.CEBA(~ce1), .CEBB(~ce2), .CEBA(~ce1), .CEBB(~ce2),
.WEBA('0), .WEBB(~we2), .WEBA('0), .WEBB(~we2),
.AA(ra1), .AB(wa2), .AA(ra1), .AB(wa2),
.DA('0), .DA('0),
.DB(wd2), .DB(wd2),
.BWEBA('0), .BWEBB('1), .BWEBA('0), .BWEBB('1),
.QA(rd1), .QA(rd1),
.QB()); .QB());
end else if ((`USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin end else if ((`USE_SRAM == 1) & (WIDTH == 36) & (DEPTH == 1024)) begin
ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk), ram2p1r1wbe_1024x36 memory1(.CLKA(clk), .CLKB(clk),
.CEBA(~ce1), .CEBB(~ce2), .CEBA(~ce1), .CEBB(~ce2),
.WEBA('0), .WEBB(~we2), .WEBA('0), .WEBB(~we2),
.AA(ra1), .AB(wa2), .AA(ra1), .AB(wa2),
.DA('0), .DA('0),
.DB(wd2), .DB(wd2),
.BWEBA('0), .BWEBB('1), .BWEBA('0), .BWEBB('1),
.QA(rd1), .QA(rd1),
.QB()); .QB());
end else if ((`USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin end else if ((`USE_SRAM == 1) & (WIDTH == 2) & (DEPTH == 1024)) begin
logic [SRAMWIDTH-1:0] SRAMReadData; logic [SRAMWIDTH-1:0] SRAMReadData;
logic [SRAMWIDTH-1:0] SRAMWriteData; logic [SRAMWIDTH-1:0] SRAMWriteData;
logic [SRAMWIDTH-1:0] RD1Sets[SRAMNUMSETS-1:0]; logic [SRAMWIDTH-1:0] RD1Sets[SRAMNUMSETS-1:0];
logic [SRAMNUMSETS-1:0] SRAMBitMaskPre; logic [SRAMNUMSETS-1:0] SRAMBitMaskPre;
logic [SRAMWIDTH-1:0] SRAMBitMask; logic [SRAMWIDTH-1:0] SRAMBitMask;
logic [$clog2(DEPTH)-1:0] RA1Q; logic [$clog2(DEPTH)-1:0] RA1Q;
onehotdecoder #($clog2(SRAMNUMSETS)) oh1(wa2[$clog2(SRAMNUMSETS)-1:0], SRAMBitMaskPre);
genvar index;
for (index = 0; index < SRAMNUMSETS; index++) begin:readdatalinesetsmux
assign RD1Sets[index] = SRAMReadData[(index*WIDTH)+WIDTH-1 : (index*WIDTH)];
assign SRAMWriteData[index*2+1:index*2] = wd2;
assign SRAMBitMask[index*2+1:index*2] = {2{SRAMBitMaskPre[index]}};
end
flopen #($clog2(DEPTH)) mem_reg1 (clk, ce1, ra1, RA1Q);
assign rd1 = RD1Sets[RA1Q[$clog2(SRAMWIDTH)-1:0]];
ram2p1r1wbe_64x32 memory2(.CLKA(clk), .CLKB(clk),
.CEBA(~ce1), .CEBB(~ce2),
.WEBA('0), .WEBB(~we2),
.AA(ra1[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
.AB(wa2[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
.DA('0),
.DB(SRAMWriteData),
.BWEBA('0), .BWEBB(SRAMBitMask),
.QA(SRAMReadData),
.QB());
onehotdecoder #($clog2(SRAMNUMSETS)) oh1(wa2[$clog2(SRAMNUMSETS)-1:0], SRAMBitMaskPre); end else begin
genvar index;
for (index = 0; index < SRAMNUMSETS; index++) begin:readdatalinesetsmux
assign RD1Sets[index] = SRAMReadData[(index*WIDTH)+WIDTH-1 : (index*WIDTH)];
assign SRAMWriteData[index*2+1:index*2] = wd2;
assign SRAMBitMask[index*2+1:index*2] = {2{SRAMBitMaskPre[index]}};
end
flopen #($clog2(DEPTH)) mem_reg1 (clk, ce1, ra1, RA1Q);
assign rd1 = RD1Sets[RA1Q[$clog2(SRAMWIDTH)-1:0]];
ram2p1r1wbe_64x32 memory2(.CLKA(clk), .CLKB(clk),
.CEBA(~ce1), .CEBB(~ce2),
.WEBA('0), .WEBB(~we2),
.AA(ra1[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
.AB(wa2[$clog2(DEPTH)-1:$clog2(SRAMNUMSETS)]),
.DA('0),
.DB(SRAMWriteData),
.BWEBA('0), .BWEBB(SRAMBitMask),
.QA(SRAMReadData),
.QB());
end else begin // ***************************************************************************
// READ first SRAM model
// *************************************************************************** // ***************************************************************************
// READ first SRAM model integer i;
// ***************************************************************************
integer i;
// Read // Read
logic [$clog2(DEPTH)-1:0] ra1d; logic [$clog2(DEPTH)-1:0] ra1d;
flopen #($clog2(DEPTH)) adrreg(clk, ce1, ra1, ra1d); flopen #($clog2(DEPTH)) adrreg(clk, ce1, ra1, ra1d);
assign rd1 = mem[ra1d]; assign rd1 = mem[ra1d];
/* // Read /* // Read
always_ff @(posedge clk) always_ff @(posedge clk)
if(ce1) rd1 <= #1 mem[ra1]; */ if(ce1) rd1 <= #1 mem[ra1]; */
// Write divided into part for bytes and part for extra msbs // Write divided into part for bytes and part for extra msbs
if(WIDTH >= 8) if(WIDTH >= 8)
always @(posedge clk) always @(posedge clk)
if (ce2 & we2) if (ce2 & we2)
for(i = 0; i < WIDTH/8; i++) for(i = 0; i < WIDTH/8; i++)
if(bwe2[i]) mem[wa2][i*8 +: 8] <= #1 wd2[i*8 +: 8]; if(bwe2[i]) mem[wa2][i*8 +: 8] <= #1 wd2[i*8 +: 8];
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
always @(posedge clk)
if (ce2 & we2 & bwe2[WIDTH/8])
mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= #1 wd2[WIDTH-1:WIDTH-WIDTH%8];
if (WIDTH%8 != 0) // handle msbs if width not a multiple of 8
always @(posedge clk)
if (ce2 & we2 & bwe2[WIDTH/8])
mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= #1 wd2[WIDTH-1:WIDTH-WIDTH%8];
end end
endmodule endmodule

View File

@ -27,8 +27,8 @@
module ram2p1r1wbe_1024x36( module ram2p1r1wbe_1024x36(
input logic CLKA, input logic CLKA,
input logic CLKB, input logic CLKB,
input logic CEBA, input logic CEBA,
input logic CEBB, input logic CEBB,
input logic WEBA, input logic WEBA,
input logic WEBB, input logic WEBB,
input logic [9:0] AA, input logic [9:0] AA,
@ -43,12 +43,12 @@ module ram2p1r1wbe_1024x36(
// replace "generic1024x36RAM" with "TSDN..1024X36.." module from your memory vendor // replace "generic1024x36RAM" with "TSDN..1024X36.." module from your memory vendor
//generic1024x36RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, //generic1024x36RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
// use part of a larger RAM to avoid generating more flavors of RAM // use part of a larger RAM to avoid generating more flavors of RAM
logic [67:0] QAfull, QBfull; logic [67:0] QAfull, QBfull;
TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
.AA, .AB, .DA({32'b0, DA[35:0]}), .DB({32'b0, DB[35:0]}), .AA, .AB, .DA({32'b0, DA[35:0]}), .DB({32'b0, DB[35:0]}),
.BWEBA({32'b0, BWEBA[35:0]}), .BWEBB({32'b0, BWEBB[35:0]}), .QA(QAfull), .QB(QBfull)); .BWEBA({32'b0, BWEBA[35:0]}), .BWEBB({32'b0, BWEBB[35:0]}), .QA(QAfull), .QB(QBfull));
assign QA = QAfull[35:0]; assign QA = QAfull[35:0];
assign QB = QBfull[35:0]; assign QB = QBfull[35:0];

View File

@ -27,8 +27,8 @@
module ram2p1r1wbe_1024x68( module ram2p1r1wbe_1024x68(
input logic CLKA, input logic CLKA,
input logic CLKB, input logic CLKB,
input logic CEBA, input logic CEBA,
input logic CEBB, input logic CEBB,
input logic WEBA, input logic WEBA,
input logic WEBB, input logic WEBB,
input logic [9:0] AA, input logic [9:0] AA,
@ -43,8 +43,8 @@ module ram2p1r1wbe_1024x68(
// replace "generic1024x68RAM" with "TSDN..1024X68.." module from your memory vendor // replace "generic1024x68RAM" with "TSDN..1024X68.." module from your memory vendor
//generic1024x68RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, //generic1024x68RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, TSDN28HPCPA1024X68M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
endmodule endmodule

View File

@ -27,8 +27,8 @@
module ram2p1r1wbe_128x64( module ram2p1r1wbe_128x64(
input logic CLKA, input logic CLKA,
input logic CLKB, input logic CLKB,
input logic CEBA, input logic CEBA,
input logic CEBB, input logic CEBB,
input logic WEBA, input logic WEBA,
input logic WEBB, input logic WEBB,
input logic [6:0] AA, input logic [6:0] AA,
@ -43,8 +43,8 @@ module ram2p1r1wbe_128x64(
// replace "generic128x64RAM" with "TSDN..128X64.." module from your memory vendor // replace "generic128x64RAM" with "TSDN..128X64.." module from your memory vendor
TSDN28HPCPA128X64M4FW sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, TSDN28HPCPA128X64M4FW sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
// generic128x64RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, // generic128x64RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
endmodule endmodule

View File

@ -27,8 +27,8 @@
module ram2p1r1wbe_2048x64( module ram2p1r1wbe_2048x64(
input logic CLKA, input logic CLKA,
input logic CLKB, input logic CLKB,
input logic CEBA, input logic CEBA,
input logic CEBB, input logic CEBB,
input logic WEBA, input logic WEBA,
input logic WEBB, input logic WEBB,
input logic [8:0] AA, input logic [8:0] AA,
@ -43,8 +43,8 @@ module ram2p1r1wbe_2048x64(
// replace "generic2048x64RAM" with "TSDN..2048X64.." module from your memory vendor // replace "generic2048x64RAM" with "TSDN..2048X64.." module from your memory vendor
TSDN28HPCPA2048X64MMFW sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, TSDN28HPCPA2048X64MMFW sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
// generic2048x64RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, // generic2048x64RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
endmodule endmodule

View File

@ -27,8 +27,8 @@
module ram2p1r1wbe_64x32( module ram2p1r1wbe_64x32(
input logic CLKA, input logic CLKA,
input logic CLKB, input logic CLKB,
input logic CEBA, input logic CEBA,
input logic CEBB, input logic CEBB,
input logic WEBA, input logic WEBA,
input logic WEBB, input logic WEBB,
input logic [5:0] AA, input logic [5:0] AA,
@ -43,7 +43,7 @@ module ram2p1r1wbe_64x32(
// replace "generic64x32RAM" with "TSDN..64X32.." module from your memory vendor // replace "generic64x32RAM" with "TSDN..64X32.." module from your memory vendor
//generic64x32RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, //generic64x32RAM sramIP (.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
// .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); // .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
TSDN28HPCPA64X32M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB, TSDN28HPCPA64X32M4MW sramIP(.CLKA, .CLKB, .CEBA, .CEBB, .WEBA, .WEBB,
.AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB); .AA, .AB, .DA, .DB, .BWEBA, .BWEBB, .QA, .QB);
endmodule endmodule

View File

@ -28,8 +28,8 @@
`include "wally-config.vh" `include "wally-config.vh"
module rom1p1r #(parameter ADDR_WIDTH = 8, module rom1p1r #(parameter ADDR_WIDTH = 8,
parameter DATA_WIDTH = 32, parameter DATA_WIDTH = 32,
parameter PRELOAD_ENABLED = 0) parameter PRELOAD_ENABLED = 0)
(input logic clk, (input logic clk,
input logic ce, input logic ce,
input logic [ADDR_WIDTH-1:0] addr, input logic [ADDR_WIDTH-1:0] addr,
@ -37,7 +37,7 @@ module rom1p1r #(parameter ADDR_WIDTH = 8,
); );
// Core Memory // Core Memory
logic [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0]; logic [DATA_WIDTH-1:0] ROM [(2**ADDR_WIDTH)-1:0];
/* if ((`USE_SRAM == 1) & (ADDR_WDITH == 7) & (DATA_WIDTH == 64)) begin /* if ((`USE_SRAM == 1) & (ADDR_WDITH == 7) & (DATA_WIDTH == 64)) begin
rom1p1r_128x64 rom1 (.CLK(clk), .CEB(~ce), .A(addr[6:0]), .Q(dout)); rom1p1r_128x64 rom1 (.CLK(clk), .CEB(~ce), .A(addr[6:0]), .Q(dout));
@ -46,55 +46,55 @@ module rom1p1r #(parameter ADDR_WIDTH = 8,
end else begin */ end else begin */
always @ (posedge clk) begin always @ (posedge clk) begin
if(ce) dout <= ROM[addr]; if(ce) dout <= ROM[addr];
end end
// for FPGA, initialize with zero-stage bootloader // for FPGA, initialize with zero-stage bootloader
if(PRELOAD_ENABLED) if(PRELOAD_ENABLED)
initial begin initial begin
ROM[0] = 64'h9581819300002197; ROM[0] = 64'h9581819300002197;
ROM[1] = 64'h4281420141014081; ROM[1] = 64'h4281420141014081;
ROM[2] = 64'h4481440143814301; ROM[2] = 64'h4481440143814301;
ROM[3] = 64'h4681460145814501; ROM[3] = 64'h4681460145814501;
ROM[4] = 64'h4881480147814701; ROM[4] = 64'h4881480147814701;
ROM[5] = 64'h4a814a0149814901; ROM[5] = 64'h4a814a0149814901;
ROM[6] = 64'h4c814c014b814b01; ROM[6] = 64'h4c814c014b814b01;
ROM[7] = 64'h4e814e014d814d01; ROM[7] = 64'h4e814e014d814d01;
ROM[8] = 64'h0110011b4f814f01; ROM[8] = 64'h0110011b4f814f01;
ROM[9] = 64'h059b45011161016e; ROM[9] = 64'h059b45011161016e;
ROM[10] = 64'h0004063705fe0010; ROM[10] = 64'h0004063705fe0010;
ROM[11] = 64'h05a000ef8006061b; ROM[11] = 64'h05a000ef8006061b;
ROM[12] = 64'h0ff003930000100f; ROM[12] = 64'h0ff003930000100f;
ROM[13] = 64'h4e952e3110060e37; ROM[13] = 64'h4e952e3110060e37;
ROM[14] = 64'hc602829b0053f2b7; ROM[14] = 64'hc602829b0053f2b7;
ROM[15] = 64'h2023fe02dfe312fd; ROM[15] = 64'h2023fe02dfe312fd;
ROM[16] = 64'h829b0053f2b7007e; ROM[16] = 64'h829b0053f2b7007e;
ROM[17] = 64'hfe02dfe312fdc602; ROM[17] = 64'hfe02dfe312fdc602;
ROM[18] = 64'h4de31efd000e2023; ROM[18] = 64'h4de31efd000e2023;
ROM[19] = 64'h059bf1402573fdd0; ROM[19] = 64'h059bf1402573fdd0;
ROM[20] = 64'h0000061705e20870; ROM[20] = 64'h0000061705e20870;
ROM[21] = 64'h0010029b01260613; ROM[21] = 64'h0010029b01260613;
ROM[22] = 64'h11010002806702fe; ROM[22] = 64'h11010002806702fe;
ROM[23] = 64'h84b2842ae426e822; ROM[23] = 64'h84b2842ae426e822;
ROM[24] = 64'h892ee04aec064511; ROM[24] = 64'h892ee04aec064511;
ROM[25] = 64'h06e000ef07e000ef; ROM[25] = 64'h06e000ef07e000ef;
ROM[26] = 64'h979334fd02905563; ROM[26] = 64'h979334fd02905563;
ROM[27] = 64'h07930177d4930204; ROM[27] = 64'h07930177d4930204;
ROM[28] = 64'h4089093394be2004; ROM[28] = 64'h4089093394be2004;
ROM[29] = 64'h04138522008905b3; ROM[29] = 64'h04138522008905b3;
ROM[30] = 64'h19e3014000ef2004; ROM[30] = 64'h19e3014000ef2004;
ROM[31] = 64'h64a2644260e2fe94; ROM[31] = 64'h64a2644260e2fe94;
ROM[32] = 64'h6749808261056902; ROM[32] = 64'h6749808261056902;
ROM[33] = 64'hdfed8b8510472783; ROM[33] = 64'hdfed8b8510472783;
ROM[34] = 64'h2423479110a73823; ROM[34] = 64'h2423479110a73823;
ROM[35] = 64'h10472783674910f7; ROM[35] = 64'h10472783674910f7;
ROM[36] = 64'h20058693ffed8b89; ROM[36] = 64'h20058693ffed8b89;
ROM[37] = 64'h05a1118737836749; ROM[37] = 64'h05a1118737836749;
ROM[38] = 64'hfed59be3fef5bc23; ROM[38] = 64'hfed59be3fef5bc23;
ROM[39] = 64'h1047278367498082; ROM[39] = 64'h1047278367498082;
ROM[40] = 64'h47858082dfed8b85; ROM[40] = 64'h47858082dfed8b85;
ROM[41] = 64'h40a7853b4015551b; ROM[41] = 64'h40a7853b4015551b;
ROM[42] = 64'h808210a7a02367c9; ROM[42] = 64'h808210a7a02367c9;
end end
endmodule endmodule

View File

@ -26,7 +26,7 @@
module rom1p1r_128x32( module rom1p1r_128x32(
input logic CLK, input logic CLK,
input logic CEB, input logic CEB,
input logic [6:0] A, input logic [6:0] A,
output logic [31:0] Q output logic [31:0] Q
); );

View File

@ -25,14 +25,14 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module rom1p1r_128x64( module rom1p1r_128x64(
input logic CLK, input logic CLK,
input logic CEB, input logic CEB,
input logic [6:0] A, input logic [6:0] A,
output logic [63:0] Q output logic [63:0] Q
); );
// replace "generic64x128RAM" with "TS3N..64X128.." module from your memory vendor // replace "generic64x128RAM" with "TS3N..64X128.." module from your memory vendor
ts3n28hpcpa128x64m8m romIP (.CLK, .CEB, .A, .Q); ts3n28hpcpa128x64m8m romIP (.CLK, .CEB, .A, .Q);
// generic64x128ROM romIP (.CLK, .CEB, .A, .Q); // generic64x128ROM romIP (.CLK, .CEB, .A, .Q);
endmodule endmodule

View File

@ -30,7 +30,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module bmuctrl( module bmuctrl(
input logic clk, reset, input logic clk, reset,
// Decode stage control signals // Decode stage control signals
input logic StallD, FlushD, // Stall, flush Decode stage input logic StallD, FlushD, // Stall, flush Decode stage
input logic [31:0] InstrD, // Instruction in Decode stage input logic [31:0] InstrD, // Instruction in Decode stage
@ -43,7 +43,7 @@ module bmuctrl(
output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage output logic BSubArithD, // TRUE if ext, clr, andn, orn, xnor instruction in Decode Stage
output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage output logic IllegalBitmanipInstrD, // Indicates if it is unrecognized B instruction in Decode Stage
// Execute stage control signals // Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
output logic [2:0] ALUSelectD, // ALU select output logic [2:0] ALUSelectD, // ALU select
output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding output logic [1:0] BSelectE, // Indicates if ZBA_ZBB_ZBC_ZBS instruction in one-hot encoding
output logic [2:0] ZBBSelectE, // ZBB mux select signal output logic [2:0] ZBBSelectE, // ZBB mux select signal
@ -66,7 +66,7 @@ module bmuctrl(
`define BMUCTRLW 17 `define BMUCTRLW 17
logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals logic [`BMUCTRLW-1:0] BMUControlsD; // Main B Instructions Decoder control signals
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; assign OpD = InstrD[6:0];

View File

@ -31,7 +31,7 @@
module controller( module controller(
input logic clk, reset, input logic clk, reset,
// Decode stage control signals // Decode stage control signals
input logic StallD, FlushD, // Stall, flush Decode stage input logic StallD, FlushD, // Stall, flush Decode stage
input logic [31:0] InstrD, // Instruction in Decode stage input logic [31:0] InstrD, // Instruction in Decode stage
@ -41,11 +41,11 @@ module controller(
output logic JumpD, // Jump instruction output logic JumpD, // Jump instruction
output logic BranchD, // Branch instruction output logic BranchD, // Branch instruction
// Execute stage control signals // Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] FlagsE, // Comparison flags ({eq, lt}) input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
input logic FWriteIntE, // Write integer register, coming from FPU controller input logic FWriteIntE, // Write integer register, coming from FPU controller
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit) output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
output logic ALUSrcAE, ALUSrcBE, // ALU operands output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, // Selects result to pass on to Memory stage output logic ALUResultSrcE, // Selects result to pass on to Memory stage
output logic [2:0] ALUSelectE, // ALU mux select signal output logic [2:0] ALUSelectE, // ALU mux select signal
output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit) output logic MemReadE, CSRReadE, // Instruction reads memory, reads a CSR (needed for Hazard unit)
@ -74,7 +74,7 @@ module controller(
output logic FWriteIntM, // FPU controller writes integer register file output logic FWriteIntM, // FPU controller writes integer register file
// Writeback stage control signals // Writeback stage control signals
input logic StallW, FlushW, // Stall, flush Writeback stage input logic StallW, FlushW, // Stall, flush Writeback stage
output logic RegWriteW, IntDivW, // Instruction writes a register, is an integer divide output logic RegWriteW, IntDivW, // Instruction writes a register, is an integer divide
output logic [2:0] ResultSrcW, // Select source of result to write back to register file output logic [2:0] ResultSrcW, // Select source of result to write back to register file
// Stall during CSRs // Stall during CSRs
output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions
@ -89,16 +89,16 @@ module controller(
`define CTRLW 23 `define CTRLW 23
// pipelined control signals // pipelined control signals
logic RegWriteD, RegWriteE; // RegWrite (register will be written) logic RegWriteD, RegWriteE; // RegWrite (register will be written)
logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file logic [2:0] ResultSrcD, ResultSrcE, ResultSrcM; // Select which result to write back to register file
logic [1:0] MemRWD, MemRWE; // Store (write to memory) logic [1:0] MemRWD, MemRWE; // Store (write to memory)
logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3) logic ALUOpD; // 0 for address generation, 1 for all other operations (must use Funct3)
logic BaseW64D; // W64 for Base instructions specifically logic BaseW64D; // W64 for Base instructions specifically
logic BaseRegWriteD; // Indicates if Base instruction register write instruction logic BaseRegWriteD; // Indicates if Base instruction register write instruction
logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu logic BaseSubArithD; // Indicates if Base instruction subtracts, sra, slt, sltu
logic BaseALUSrcBD; // Base instruction ALU B source select signal logic BaseALUSrcBD; // Base instruction ALU B source select signal
logic [2:0] ALUControlD; // Determines ALU operation logic [2:0] ALUControlD; // Determines ALU operation
logic ALUSrcAD, ALUSrcBD; // ALU inputs logic ALUSrcAD, ALUSrcBD; // ALU inputs
logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction logic ALUResultSrcD, W64D, MDUD; // ALU result, is RV64 W-type, is multiply/divide instruction
logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR logic CSRZeroSrcD; // Ignore setting and clearing zeros to CSR
logic CSRReadD; // CSR read instruction logic CSRReadD; // CSR read instruction
@ -115,7 +115,7 @@ module controller(
logic BranchTakenE; // Branch is taken logic BranchTakenE; // Branch is taken
logic eqE, ltE; // Comparator outputs logic eqE, ltE; // Comparator outputs
logic unused; logic unused;
logic BranchFlagE; // Branch flag to use (chosen between eq or lt) logic BranchFlagE; // Branch flag to use (chosen between eq or lt)
logic IEURegWriteE; // Register write logic IEURegWriteE; // Register write
logic BRegWriteE; // Register write from BMU controller in Execute Stage logic BRegWriteE; // Register write from BMU controller in Execute Stage
logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers logic IllegalERegAdrD; // RV32E attempts to write upper 16 registers
@ -146,29 +146,29 @@ module controller(
logic Funct7ZeroD, Funct7b5D, IShiftD, INoShiftD; logic Funct7ZeroD, Funct7b5D, IShiftD, INoShiftD;
logic Funct7ShiftZeroD, Funct7Shiftb5D; logic Funct7ShiftZeroD, Funct7Shiftb5D;
assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions
assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub
assign Funct7ShiftZeroD = (`XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD; assign Funct7ShiftZeroD = (`XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD;
assign Funct7Shiftb5D = (`XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D; assign Funct7Shiftb5D = (`XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D;
assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms
assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101)); assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101));
assign IFunctD = IShiftD | INoShiftD; assign IFunctD = IShiftD | INoShiftD;
assign RFunctD = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD; assign RFunctD = ((Funct3D == 3'b000 | Funct3D == 3'b101) & Funct7b5D) | Funct7ZeroD;
assign MFunctD = (Funct7D == 7'b0000001) & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv assign MFunctD = (Funct7D == 7'b0000001) & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
assign LFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 | assign LFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | Funct3D == 3'b100 | Funct3D == 3'b101 |
((`XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110)); ((`XLEN == 64) & (Funct3D == 3'b011 | Funct3D == 3'b110));
assign SFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 | assign SFunctD = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b010 |
((`XLEN == 64) & (Funct3D == 3'b011)); ((`XLEN == 64) & (Funct3D == 3'b011));
assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches
assign JFunctD = (Funct3D == 3'b000); assign JFunctD = (Funct3D == 3'b000);
end else begin:legalcheck2 end else begin:legalcheck2
assign IFunctD = 1; // Don't bother to separate out shift decoding assign IFunctD = 1; // Don't bother to separate out shift decoding
assign RFunctD = ~Funct7D[0]; // Not a multiply assign RFunctD = ~Funct7D[0]; // Not a multiply
assign MFunctD = Funct7D[0] & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv assign MFunctD = Funct7D[0] & (`M_SUPPORTED | (`ZMMUL_SUPPORTED & ~Funct3D[2])); // muldiv
assign LFunctD = 1; // don't bother to check Funct3 for loads assign LFunctD = 1; // don't bother to check Funct3 for loads
assign SFunctD = 1; // don't bother to check Funct3 for stores assign SFunctD = 1; // don't bother to check Funct3 for stores
assign BFunctD = 1; // don't bother to check Funct3 for branches assign BFunctD = 1; // don't bother to check Funct3 for branches
assign JFunctD = 1; // don't bother to check Funct3 for jumps assign JFunctD = 1; // don't bother to check Funct3 for jumps
end end
// Main Instruction Decoder // Main Instruction Decoder
@ -182,7 +182,7 @@ module controller(
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_1; // flw - only legal if FP supported
7'b0001111: if (`ZIFENCEI_SUPPORTED) 7'b0001111: if (`ZIFENCEI_SUPPORTED)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_1_0_00_0; // fence
else else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_0; // fence treated as nop
7'b0010011: if (IFunctD) 7'b0010011: if (IFunctD)
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_0_0_0_0_0_00_0; // I-type ALU

View File

@ -34,7 +34,7 @@ module forward(
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers
input logic MemReadE, MDUE, CSRReadE, // Execute stage instruction is a load (MemReadE), divide (MDUE), or CSR read (CSRReadE) input logic MemReadE, MDUE, CSRReadE, // Execute stage instruction is a load (MemReadE), divide (MDUE), or CSR read (CSRReadE)
input logic RegWriteM, RegWriteW, // Instruction in Memory or Writeback stage writes register file input logic RegWriteM, RegWriteW, // Instruction in Memory or Writeback stage writes register file
input logic FCvtIntE, // FPU convert float to int input logic FCvtIntE, // FPU convert float to int
input logic SCE, // Store Conditional instruction input logic SCE, // Store Conditional instruction
// Forwarding controls // Forwarding controls
output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers

View File

@ -29,27 +29,27 @@
`include "wally-config.vh" `include "wally-config.vh"
module ieu ( module ieu (
input logic clk, reset, input logic clk, reset,
// Decode stage signals // Decode stage signals
input logic [31:0] InstrD, // Instruction input logic [31:0] InstrD, // Instruction
input logic IllegalIEUFPUInstrD, // Illegal instruction input logic IllegalIEUFPUInstrD, // Illegal instruction
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
// Execute stage signals // Execute stage signals
input logic [`XLEN-1:0] PCE, // PC input logic [`XLEN-1:0] PCE, // PC
input logic [`XLEN-1:0] PCLinkE, // PC + 4 input logic [`XLEN-1:0] PCLinkE, // PC + 4
output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE) output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE)
input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int
output logic [`XLEN-1:0] IEUAdrE, // Memory address output logic [`XLEN-1:0] IEUAdrE, // Memory address
output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
output logic [2:0] Funct3E, // Funct3 instruction field output logic [2:0] Funct3E, // Funct3 instruction field
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B
output logic [4:0] RdE, // Destination register output logic [4:0] RdE, // Destination register
// Memory stage signals // Memory stage signals
input logic SquashSCW, // Squash store conditional, from LSU input logic SquashSCW, // Squash store conditional, from LSU
output logic [1:0] MemRWM, // Read/write control goes to LSU output logic [1:0] MemRWM, // Read/write control goes to LSU
output logic [1:0] AtomicM, // Atomic control goes to LSU output logic [1:0] AtomicM, // Atomic control goes to LSU
output logic [`XLEN-1:0] WriteDataM, // Write data to LSU output logic [`XLEN-1:0] WriteDataM, // Write data to LSU
output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU
output logic [`XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU output logic [`XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU
output logic [4:0] RdM, // Destination register output logic [4:0] RdM, // Destination register
input logic [`XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp) input logic [`XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp)
@ -66,12 +66,12 @@ module ieu (
output logic [4:0] RdW, // Destination register output logic [4:0] RdW, // Destination register
input logic [`XLEN-1:0] ReadDataW, // LSU's read data input logic [`XLEN-1:0] ReadDataW, // LSU's read data
// Hazard unit signals // Hazard unit signals
input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit
output logic MDUStallD, CSRRdStallD, StoreStallD, output logic MDUStallD, CSRRdStallD, StoreStallD,
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
); );
logic [2:0] ImmSrcD; // Select type of immediate extension logic [2:0] ImmSrcD; // Select type of immediate extension

View File

@ -35,8 +35,8 @@ module shifter (
input logic Right, Rotate, W64, SubArith, // Shift right, rotate, W64-type operation, arithmetic shift input logic Right, Rotate, W64, SubArith, // Shift right, rotate, W64-type operation, arithmetic shift
output logic [`XLEN-1:0] Y); // Shifted result output logic [`XLEN-1:0] Y); // Shifted result
logic [2*`XLEN-2:0] z, zshift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits logic [2*`XLEN-2:0] Z, ZShift; // Input to funnel shifter, shifted amount before truncated to 32 or 64 bits
logic [`LOG_XLEN-1:0] amttrunc, Offset; // Shift amount adjusted for RV64, right-shift amount logic [`LOG_XLEN-1:0] TruncAmt, Offset; // Shift amount adjusted for RV64, right-shift amount
logic Sign; // Sign bit for sign extension logic Sign; // Sign bit for sign extension
assign Sign = A[`XLEN-1] & SubArith; // sign bit for sign extension assign Sign = A[`XLEN-1] & SubArith; // sign bit for sign extension
@ -44,17 +44,17 @@ module shifter (
if (`ZBB_SUPPORTED) begin: rotfunnel32 //rv32 shifter with rotates if (`ZBB_SUPPORTED) begin: rotfunnel32 //rv32 shifter with rotates
always_comb // funnel mux always_comb // funnel mux
case({Right, Rotate}) case({Right, Rotate})
2'b00: z = {A[31:0], 31'b0}; 2'b00: Z = {A[31:0], 31'b0};
2'b01: z = {A[31:0], A[31:1]}; 2'b01: Z = {A[31:0], A[31:1]};
2'b10: z = {{31{Sign}}, A[31:0]}; 2'b10: Z = {{31{Sign}}, A[31:0]};
2'b11: z = {A[30:0], A[31:0]}; 2'b11: Z = {A[30:0], A[31:0]};
endcase endcase
end else begin: norotfunnel32 //rv32 shifter without rotates end else begin: norotfunnel32 //rv32 shifter without rotates
always_comb // funnel mux always_comb // funnel mux
if (Right) z = {{31{Sign}}, A[31:0]}; if (Right) Z = {{31{Sign}}, A[31:0]};
else z = {A[31:0], 31'b0}; else Z = {A[31:0], 31'b0};
end end
assign amttrunc = Amt; // shift amount assign TruncAmt = Amt; // shift amount
end else begin // rv64 end else begin // rv64
logic [`XLEN-1:0] A64; logic [`XLEN-1:0] A64;
mux3 #(64) extendmux({{32{1'b0}}, A[31:0]}, {{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, A64); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux mux3 #(64) extendmux({{32{1'b0}}, A[31:0]}, {{32{A[31]}}, A[31:0]}, A, {~W64, SubArith}, A64); // bottom 32 bits are always A[31:0], so effectively a 32-bit upper mux
@ -64,25 +64,25 @@ module shifter (
mux2 #(`XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotatons mux2 #(`XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotatons
always_comb // funnel mux always_comb // funnel mux
case ({Right, Rotate}) case ({Right, Rotate})
2'b00: z = {A64[63:0],{63'b0}}; 2'b00: Z = {A64[63:0],{63'b0}};
2'b01: z = {RotA[63:0], RotA[63:1]}; 2'b01: Z = {RotA[63:0], RotA[63:1]};
2'b10: z = {{63{Sign}}, A64[63:0]}; 2'b10: Z = {{63{Sign}}, A64[63:0]};
2'b11: z = {RotA[62:0], RotA[63:0]}; 2'b11: Z = {RotA[62:0], RotA[63:0]};
endcase endcase
end else begin: norotfunnel64 // rv64 shifter without rotates end else begin: norotfunnel64 // rv64 shifter without rotates
always_comb // funnel mux always_comb // funnel mux
if (Right) z = {{63{Sign}}, A64[63:0]}; if (Right) Z = {{63{Sign}}, A64[63:0]};
else z = {A64[63:0], {63'b0}}; else Z = {A64[63:0], {63'b0}};
end end
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift assign TruncAmt = W64 ? {1'b0, Amt[4:0]} : Amt; // 32- or 64-bit shift
end end
// Opposite offset for right shifts // Opposite offset for right shifts
assign Offset = Right ? amttrunc : ~amttrunc; assign Offset = Right ? TruncAmt : ~TruncAmt;
// Funnel operation // Funnel operation
assign zshift = z >> Offset; assign ZShift = Z >> Offset;
assign Y = zshift[`XLEN-1:0]; assign Y = ZShift[`XLEN-1:0];
endmodule endmodule

View File

@ -31,10 +31,10 @@
module RASPredictor #(parameter int StackSize = 16 )( module RASPredictor #(parameter int StackSize = 16 )(
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM, input logic StallF, StallD, StallE, StallM, FlushD, FlushE, FlushM,
input logic BPReturnWrongD, // Prediction class is wrong input logic BPReturnWrongD, // Prediction class is wrong
input logic ReturnD, input logic ReturnD,
input logic ReturnE, CallE, // Instr class input logic ReturnE, CallE, // Instr class
input logic BPReturnF, input logic BPReturnF,
input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a call input logic [`XLEN-1:0] PCLinkE, // PC of instruction after a call
@ -48,14 +48,14 @@ module RASPredictor #(parameter int StackSize = 16 )(
logic [StackSize-1:0] [`XLEN-1:0] memory; logic [StackSize-1:0] [`XLEN-1:0] memory;
integer index; integer index;
logic PopF; logic PopF;
logic PushE; logic PushE;
logic RepairD; logic RepairD;
logic IncrRepairD, DecRepairD; logic IncrRepairD, DecRepairD;
logic DecrementPtr; logic DecrementPtr;
logic FlushedReturnDE; logic FlushedReturnDE;
logic WrongPredReturnD; logic WrongPredReturnD;
assign PopF = BPReturnF & ~StallD & ~FlushD; assign PopF = BPReturnF & ~StallD & ~FlushD;
@ -85,7 +85,7 @@ module RASPredictor #(parameter int StackSize = 16 )(
always_ff @ (posedge clk) begin always_ff @ (posedge clk) begin
if(reset) begin if(reset) begin
for(index=0; index<StackSize; index++) for(index=0; index<StackSize; index++)
memory[index] <= {`XLEN{1'b0}}; memory[index] <= {`XLEN{1'b0}};
end else if(PushE) begin end else if(PushE) begin
memory[NextPtr] <= #1 PCLinkE; memory[NextPtr] <= #1 PCLinkE;
end end

View File

@ -69,35 +69,33 @@ module bpred (
output logic IClassWrongM // Class prediction is wrong output logic IClassWrongM // Class prediction is wrong
); );
logic [1:0] BPDirPredF; logic [1:0] BPDirPredF;
logic [`XLEN-1:0] BPBTAF, RASPCF; logic [`XLEN-1:0] BPBTAF, RASPCF;
logic BPPCWrongE; logic BPPCWrongE;
logic IClassWrongE; logic IClassWrongE;
logic BPDirPredWrongE; logic BPDirPredWrongE;
logic BPPCSrcF; logic BPPCSrcF;
logic [`XLEN-1:0] BPPCF; logic [`XLEN-1:0] BPPCF;
logic [`XLEN-1:0] PC0NextF; logic [`XLEN-1:0] PC0NextF;
logic [`XLEN-1:0] PCCorrectE; logic [`XLEN-1:0] PCCorrectE;
logic [3:0] WrongPredInstrClassD; logic [3:0] WrongPredInstrClassD;
logic BTBTargetWrongE; logic BTBTargetWrongE;
logic RASTargetWrongE; logic RASTargetWrongE;
logic [`XLEN-1:0] BPBTAD;
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
logic ReturnD, CallD;
logic ReturnE, CallE;
logic BranchM, JumpM, ReturnM, CallM;
logic BranchW, JumpW, ReturnW, CallW;
logic BPReturnWrongD;
logic [`XLEN-1:0] BPBTAE;
logic [`XLEN-1:0] BPBTAD;
logic BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF;
logic BPBranchF, BPJumpF, BPReturnF, BPCallF;
logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
logic ReturnD, CallD;
logic ReturnE, CallE;
logic BranchM, JumpM, ReturnM, CallM;
logic BranchW, JumpW, ReturnW, CallW;
logic BPReturnWrongD;
logic [`XLEN-1:0] BPBTAE;
// Part 1 branch direction prediction // Part 1 branch direction prediction
// look into the 2 port Sram model. something is wrong. // look into the 2 port Sram model. something is wrong.
@ -149,25 +147,25 @@ module bpred (
btb #(`BTB_SIZE) btb #(`BTB_SIZE)
TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, TargetPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PCNextF, .PCF, .PCD, .PCE, .PCM, .PCNextF, .PCF, .PCD, .PCE, .PCM,
.BPBTAF, .BPBTAD, .BPBTAE, .BPBTAF, .BPBTAD, .BPBTAE,
.BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}), .BTBIClassF({BTBCallF, BTBReturnF, BTBJumpF, BTBBranchF}),
.IClassWrongM, .IClassWrongE, .IClassWrongM, .IClassWrongE,
.IEUAdrE, .IEUAdrM, .IEUAdrE, .IEUAdrM,
.InstrClassD({CallD, ReturnD, JumpD, BranchD}), .InstrClassD({CallD, ReturnD, JumpD, BranchD}),
.InstrClassE({CallE, ReturnE, JumpE, BranchE}), .InstrClassE({CallE, ReturnE, JumpE, BranchE}),
.InstrClassM({CallM, ReturnM, JumpM, BranchM}), .InstrClassM({CallM, ReturnM, JumpM, BranchM}),
.InstrClassW({CallW, ReturnW, JumpW, BranchW})); .InstrClassW({CallW, ReturnW, JumpW, BranchW}));
icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, icpred #(`INSTR_CLASS_PRED) icpred(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW, .PostSpillInstrRawF, .InstrD, .BranchD, .BranchE, .JumpD, .JumpE, .BranchM, .BranchW, .JumpM, .JumpW,
.CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF, .CallD, .CallE, .CallM, .CallW, .ReturnD, .ReturnE, .ReturnM, .ReturnW, .BTBCallF, .BTBReturnF, .BTBJumpF,
.BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD); .BTBBranchF, .BPCallF, .BPReturnF, .BPJumpF, .BPBranchF, .IClassWrongM, .IClassWrongE, .BPReturnWrongD);
// Part 3 RAS // Part 3 RAS
RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, RASPredictor RASPredictor(.clk, .reset, .StallF, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.BPReturnF, .ReturnD, .ReturnE, .CallE, .BPReturnF, .ReturnD, .ReturnE, .CallE,
.BPReturnWrongD, .RASPCF, .PCLinkE); .BPReturnWrongD, .RASPCF, .PCLinkE);
// Check the prediction // Check the prediction
// if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address. // if it is a CFI then check if the next instruction address (PCD) matches the branch's target or fallthrough address.
@ -192,11 +190,11 @@ module bpred (
// If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE. // If the fence/csrw was predicted as a taken branch then we select PCF, rather PCE.
// Effectively this is PCM+4 or the non-existant PCLinkM // Effectively this is PCM+4 or the non-existant PCLinkM
if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE); if(`INSTR_CLASS_PRED) mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
else assign NextValidPCE = PCE; else assign NextValidPCE = PCE;
if(`ZICOUNTERS_SUPPORTED) begin if(`ZICOUNTERS_SUPPORTED) begin
logic [`XLEN-1:0] RASPCD, RASPCE; logic [`XLEN-1:0] RASPCD, RASPCE;
logic BTAWrongE, RASPredPCWrongE; logic BTAWrongE, RASPredPCWrongE;
// performance counters // performance counters
// 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now // 1. class (class wrong / minstret) (IClassWrongM / csr) // Correct now
// 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal) // 2. target btb (btb target wrong / class[0,1,3]) (btb target wrong / (br + j + jal)
@ -207,15 +205,15 @@ module bpred (
// could be wrong or the fall through address selected for branch predict not taken. // could be wrong or the fall through address selected for branch predict not taken.
// By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of // By pipeline the BTB's PC and RAS address through the pipeline we can measure the accuracy of
// both without the above inaccuracies. // both without the above inaccuracies.
// **** use BPBTAWrongM from BTB. // **** use BPBTAWrongM from BTB.
assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE; assign BTAWrongE = (BPBTAE != IEUAdrE) & (BranchE | JumpE & ~ReturnE) & PCSrcE;
assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE; assign RASPredPCWrongE = (RASPCE != IEUAdrE) & ReturnE & PCSrcE;
flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD); flopenrc #(`XLEN) RASTargetDReg(clk, reset, FlushD, ~StallD, RASPCF, RASPCD);
flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE); flopenrc #(`XLEN) RASTargetEReg(clk, reset, FlushE, ~StallE, RASPCD, RASPCE);
flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM, flopenrc #(3) BPPredWrongRegM(clk, reset, FlushM, ~StallM,
{BPDirPredWrongE, BTAWrongE, RASPredPCWrongE}, {BPDirPredWrongE, BTAWrongE, RASPredPCWrongE},
{BPDirPredWrongM, BTAWrongM, RASPredPCWrongM}); {BPDirPredWrongM, BTAWrongM, RASPredPCWrongM});
end else begin end else begin
assign {BTAWrongM, RASPredPCWrongM} = '0; assign {BTAWrongM, RASPredPCWrongM} = '0;

View File

@ -31,34 +31,34 @@
`include "wally-config.vh" `include "wally-config.vh"
module btb #(parameter Depth = 10 ) ( module btb #(parameter Depth = 10 ) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW, input logic StallF, StallD, StallE, StallM, StallW, FlushD, FlushE, FlushM, FlushW,
input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages input logic [`XLEN-1:0] PCNextF, PCF, PCD, PCE, PCM,// PC at various stages
output logic [`XLEN-1:0] BPBTAF, // BTB's guess at PC output logic [`XLEN-1:0] BPBTAF, // BTB's guess at PC
output logic [`XLEN-1:0] BPBTAD, output logic [`XLEN-1:0] BPBTAD,
output logic [`XLEN-1:0] BPBTAE, output logic [`XLEN-1:0] BPBTAE,
output logic [3:0] BTBIClassF, // BTB's guess at instruction class output logic [3:0] BTBIClassF, // BTB's guess at instruction class
// update // update
input logic IClassWrongM, // BTB's instruction class guess was wrong input logic IClassWrongM, // BTB's instruction class guess was wrong
input logic IClassWrongE, input logic IClassWrongE,
input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb input logic [`XLEN-1:0] IEUAdrE, // Branch/jump target address to insert into btb
input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb input logic [`XLEN-1:0] IEUAdrM, // Branch/jump target address to insert into btb
input logic [3:0] InstrClassD, // Instruction class to insert into btb input logic [3:0] InstrClassD, // Instruction class to insert into btb
input logic [3:0] InstrClassE, // Instruction class to insert into btb input logic [3:0] InstrClassE, // Instruction class to insert into btb
input logic [3:0] InstrClassM, // Instruction class to insert into btb input logic [3:0] InstrClassM, // Instruction class to insert into btb
input logic [3:0] InstrClassW input logic [3:0] InstrClassW
); );
logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex; logic [Depth-1:0] PCNextFIndex, PCFIndex, PCDIndex, PCEIndex, PCMIndex, PCWIndex;
logic [`XLEN-1:0] ResetPC; logic [`XLEN-1:0] ResetPC;
logic MatchD, MatchE, MatchM, MatchW, MatchX; logic MatchD, MatchE, MatchM, MatchW, MatchX;
logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF; logic [`XLEN+3:0] ForwardBTBPrediction, ForwardBTBPredictionF;
logic [`XLEN+3:0] TableBTBPredF; logic [`XLEN+3:0] TableBTBPredF;
logic [`XLEN-1:0] IEUAdrW; logic [`XLEN-1:0] IEUAdrW;
logic [`XLEN-1:0] PCW; logic [`XLEN-1:0] PCW;
logic BTBWrongE, BPBTAWrongE; logic BTBWrongE, BPBTAWrongE;
logic BTBWrongM, BPBTAWrongM; logic BTBWrongM, BPBTAWrongM;
// hashing function for indexing the PC // hashing function for indexing the PC
@ -111,5 +111,4 @@ module btb #(parameter Depth = 10 ) (
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW); flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW); flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
endmodule endmodule

View File

@ -42,30 +42,30 @@ module gshare #(parameter k = 10,
input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE input logic BPBranchF, BranchD, BranchE, BranchM, BranchW, PCSrcE
); );
logic MatchF, MatchD, MatchE, MatchM, MatchW; logic MatchF, MatchD, MatchE, MatchM, MatchW;
logic MatchX; logic MatchX;
logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF; logic [1:0] TableBPDirPredF, BPDirPredD, BPDirPredE, FwdNewDirPredF;
logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW; logic [1:0] NewBPDirPredE, NewBPDirPredM, NewBPDirPredW;
logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW; logic [k-1:0] IndexNextF, IndexF, IndexD, IndexE, IndexM, IndexW;
logic [k-1:0] GHRF, GHRD, GHRE, GHRM; logic [k-1:0] GHRF, GHRD, GHRE, GHRM;
logic [k-1:0] GHRNextM, GHRNextF; logic [k-1:0] GHRNextM, GHRNextF;
logic PCSrcM; logic PCSrcM;
if(TYPE == 1) begin if(TYPE == 1) begin
assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; assign IndexNextF = GHRNextF ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]}; assign IndexF = GHRF ^ {PCF[k+1] ^ PCF[1], PCF[k:2]};
assign IndexD = GHRD ^ {PCD[k+1] ^ PCD[1], PCD[k:2]}; assign IndexD = GHRD ^ {PCD[k+1] ^ PCD[1], PCD[k:2]};
assign IndexE = GHRE ^ {PCE[k+1] ^ PCE[1], PCE[k:2]}; assign IndexE = GHRE ^ {PCE[k+1] ^ PCE[1], PCE[k:2]};
assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]};
end else if(TYPE == 0) begin end else if(TYPE == 0) begin
assign IndexNextF = GHRNextF; assign IndexNextF = GHRNextF;
assign IndexF = GHRF; assign IndexF = GHRF;
assign IndexD = GHRD; assign IndexD = GHRD;
assign IndexE = GHRE; assign IndexE = GHRE;
assign IndexM = GHRM; assign IndexM = GHRM;
end end
flopenrc #(k) IndexWReg(clk, reset, FlushW, ~StallW, IndexM, IndexW); flopenrc #(k) IndexWReg(clk, reset, FlushW, ~StallW, IndexM, IndexW);
@ -79,7 +79,7 @@ module gshare #(parameter k = 10,
assign FwdNewDirPredF = MatchD ? {2{BPDirPredD[1]}} : assign FwdNewDirPredF = MatchD ? {2{BPDirPredD[1]}} :
MatchE ? {NewBPDirPredE} : MatchE ? {NewBPDirPredE} :
MatchM ? {NewBPDirPredM} : MatchM ? {NewBPDirPredM} :
NewBPDirPredW ; NewBPDirPredW ;
assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF; assign BPDirPredF = MatchX ? FwdNewDirPredF : TableBPDirPredF;

View File

@ -42,20 +42,20 @@ module gsharebasic #(parameter k = 10,
input logic BranchE, BranchM, PCSrcE input logic BranchE, BranchM, PCSrcE
); );
logic [k-1:0] IndexNextF, IndexM; logic [k-1:0] IndexNextF, IndexM;
logic [1:0] BPDirPredD, BPDirPredE; logic [1:0] BPDirPredD, BPDirPredE;
logic [1:0] NewBPDirPredE, NewBPDirPredM; logic [1:0] NewBPDirPredE, NewBPDirPredM;
logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR; logic [k-1:0] GHRF, GHRD, GHRE, GHRM, GHR;
logic [k-1:0] GHRNext; logic [k-1:0] GHRNext;
logic PCSrcM; logic PCSrcM;
if(TYPE == 1) begin if(TYPE == 1) begin
assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]}; assign IndexNextF = GHR ^ {PCNextF[k+1] ^ PCNextF[1], PCNextF[k:2]};
assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]}; assign IndexM = GHRM ^ {PCM[k+1] ^ PCM[1], PCM[k:2]};
end else if(TYPE == 0) begin end else if(TYPE == 0) begin
assign IndexNextF = GHRNext; assign IndexNextF = GHRNext;
assign IndexM = GHRM; assign IndexM = GHRM;
end end
ram2p1r1wbe #(2**k, 2) PHT(.clk(clk), ram2p1r1wbe #(2**k, 2) PHT(.clk(clk),

View File

@ -45,16 +45,16 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)(
output logic IClassWrongM, BPReturnWrongD, IClassWrongE output logic IClassWrongM, BPReturnWrongD, IClassWrongE
); );
logic IClassWrongD; logic IClassWrongD;
logic BPBranchD, BPJumpD, BPReturnD, BPCallD; logic BPBranchD, BPJumpD, BPReturnD, BPCallD;
if (!INSTR_CLASS_PRED) begin : DirectClassDecode if (!INSTR_CLASS_PRED) begin : DirectClassDecode
// This section is mainly for testing, verification, and PPA comparison. // This section is mainly for testing, verification, and PPA comparison.
// An alternative to using the BTB to store the instruction class is to partially decode // An alternative to using the BTB to store the instruction class is to partially decode
// the instructions in the Fetch stage into, Call, Return, Jump, and Branch instructions. // the instructions in the Fetch stage into, Call, Return, Jump, and Branch instructions.
// This logic is not described in the text book as of 23 February 2023. // This logic is not described in the text book as of 23 February 2023.
logic ccall, cj, cjr, ccallr, CJumpF, CBranchF; logic ccall, cj, cjr, ccallr, CJumpF, CBranchF;
logic NCJumpF, NCBranchF; logic NCJumpF, NCBranchF;
if(`C_SUPPORTED) begin if(`C_SUPPORTED) begin
logic [4:0] CompressedOpcF; logic [4:0] CompressedOpcF;
@ -75,10 +75,10 @@ module icpred #(parameter INSTR_CLASS_PRED = 1)(
assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF); assign BPBranchF = NCBranchF | (`C_SUPPORTED & CBranchF);
assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF)); assign BPJumpF = NCJumpF | (`C_SUPPORTED & (CJumpF));
assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5 assign BPReturnF = (NCJumpF & (PostSpillInstrRawF[19:15] & 5'h1B) == 5'h01) | // returnurn must returnurn to ra or r5
(`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01)); (`C_SUPPORTED & (ccallr | cjr) & ((PostSpillInstrRawF[11:7] & 5'h1B) == 5'h01));
assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5 assign BPCallF = (NCJumpF & (PostSpillInstrRawF[11:07] & 5'h1B) == 5'h01) | // call(r) must link to ra or x5
(`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01))); (`C_SUPPORTED & (ccall | (ccallr & (PostSpillInstrRawF[11:7] & 5'h1b) == 5'h01)));
end else begin end else begin
// This section connects the BTB's instruction class prediction. // This section connects the BTB's instruction class prediction.

View File

@ -28,116 +28,116 @@
`include "wally-config.vh" `include "wally-config.vh"
module ifu ( module ifu (
input logic clk, reset, input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW, input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation
// Command from CPU // Command from CPU
input logic InvalidateICacheM, // Clears all instruction cache valid bits input logic InvalidateICacheM, // Clears all instruction cache valid bits
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE) input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
input logic InstrValidD, InstrValidE, InstrValidM, input logic InstrValidD, InstrValidE, InstrValidM,
input logic BranchD, BranchE, input logic BranchD, BranchE,
input logic JumpD, JumpE, input logic JumpD, JumpE,
// Bus interface // Bus interface
output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
input logic IFUHREADY, // Bus ready from IFU to EBU input logic IFUHREADY, // Bus ready from IFU to EBU
output logic IFUHWRITE, // Bus write operation from IFU to EBU output logic IFUHWRITE, // Bus write operation from IFU to EBU
output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
output logic [`XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW output logic [`XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
// Execute // Execute
output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
input logic PCSrcE, // Executation stage branch is taken input logic PCSrcE, // Executation stage branch is taken
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address input logic [`XLEN-1:0] IEUAdrM, // The branch/jump target address
output logic [`XLEN-1:0] PCE, // Execution stage instruction address output logic [`XLEN-1:0] PCE, // Execution stage instruction address
output logic BPWrongE, // Prediction is wrong output logic BPWrongE, // Prediction is wrong
output logic BPWrongM, // Prediction is wrong output logic BPWrongM, // Prediction is wrong
// Mem // Mem
output logic CommittedF, // I$ or bus memory operation started, delay interrupts output logic CommittedF, // I$ or bus memory operation started, delay interrupts
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence output logic [`XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence
output logic [31:0] InstrD, // The decoded instruction in Decode stage output logic [31:0] InstrD, // The decoded instruction in Decode stage
output logic [31:0] InstrM, // The decoded instruction in Memory stage output logic [31:0] InstrM, // The decoded instruction in Memory stage
output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
output logic [`XLEN-1:0] PCM, // Memory stage instruction address output logic [`XLEN-1:0] PCM, // Memory stage instruction address
// branch predictor // branch predictor
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
output logic BPDirPredWrongM, // Prediction direction is wrong output logic BPDirPredWrongM, // Prediction direction is wrong
output logic BTAWrongM, // Prediction target wrong output logic BTAWrongM, // Prediction target wrong
output logic RASPredPCWrongM, // RAS prediction is wrong output logic RASPredPCWrongM, // RAS prediction is wrong
output logic IClassWrongM, // Class prediction is wrong output logic IClassWrongM, // Class prediction is wrong
output logic ICacheStallF, // I$ busy with multicycle operation output logic ICacheStallF, // I$ busy with multicycle operation
// Faults // Faults
input logic IllegalBaseInstrD, // Illegal non-compressed instruction input logic IllegalBaseInstrD, // Illegal non-compressed instruction
input logic IllegalFPUInstrD, // Illegal FP instruction input logic IllegalFPUInstrD, // Illegal FP instruction
output logic InstrPageFaultF, // Instruction page fault output logic InstrPageFaultF, // Instruction page fault
output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
// mmu management // mmu management
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
input logic [`XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB input logic [`XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
input logic ITLBWriteF, // Writes PTE and PageType to ITLB input logic ITLBWriteF, // Writes PTE and PageType to ITLB
input logic [`XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration input logic [`XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration
input logic STATUS_MXR, // Status CSR: make executable page readable input logic STATUS_MXR, // Status CSR: make executable page readable
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
input logic STATUS_MPRV, // Status CSR: modify machine privilege input logic STATUS_MPRV, // Status CSR: modify machine privilege
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit
output logic InstrAccessFaultF, // Instruction access fault output logic InstrAccessFaultF, // Instruction access fault
output logic ICacheAccess, // Report I$ read to performance counters output logic ICacheAccess, // Report I$ read to performance counters
output logic ICacheMiss // Report I$ miss to performance counters output logic ICacheMiss // Report I$ miss to performance counters
); );
localparam [31:0] nop = 32'h00000013; // instruction for NOP localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4 logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
logic [`XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed) logic [`XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed)
logic [`XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill logic [`XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill
logic [`XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j) logic [`XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j)
logic [`XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F logic [`XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F
logic [`XLEN-1:0] PCD; // Decode stage instruction address logic [`XLEN-1:0] PCD; // Decode stage instruction address
logic [`XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence logic [`XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence
logic [`XLEN-1:0] PCF; // Fetch stage instruction address logic [`XLEN-1:0] PCF; // Fetch stage instruction address
logic [`PA_BITS-1:0] PCPF; // Physical address after address translation logic [`PA_BITS-1:0] PCPF; // Physical address after address translation
logic [`XLEN+1:0] PCFExt; // logic [`XLEN+1:0] PCFExt; //
logic [31:0] IROMInstrF; // Instruction from the IROM logic [31:0] IROMInstrF; // Instruction from the IROM
logic [31:0] ICacheInstrF; // Instruction from the I$ logic [31:0] ICacheInstrF; // Instruction from the I$
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
logic CompressedF; // The fetched instruction is compressed logic CompressedF; // The fetched instruction is compressed
logic CompressedD; // The decoded instruction is compressed logic CompressedD; // The decoded instruction is compressed
logic CompressedE; // The execution instruction is compressed logic CompressedE; // The execution instruction is compressed
logic CompressedM; // The execution instruction is compressed logic CompressedM; // The execution instruction is compressed
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good
logic [1:0] IFURWF; // IFU alreays read IFURWF = 10 logic [1:0] IFURWF; // IFU alreays read IFURWF = 10
logic [31:0] InstrE; // Instruction in the Execution stage logic [31:0] InstrE; // Instruction in the Execution stage
logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush
logic CacheableF; // PMA indicates instruction address is cacheable logic CacheableF; // PMA indicates instruction address is cacheable
logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF
logic BusStall; // Bus interface busy with multicycle operation logic BusStall; // Bus interface busy with multicycle operation
logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation
logic GatedStallD; // StallD gated by selected next spill logic GatedStallD; // StallD gated by selected next spill
// branch predictor signal // branch predictor signal
logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF logic [`XLEN-1:0] PC1NextF; // Branch predictor next PCF
logic BusCommittedF; // Bus memory operation in flight, delay interrupts logic BusCommittedF; // Bus memory operation in flight, delay interrupts
logic CacheCommittedF; // I$ memory operation started, delay interrupts logic CacheCommittedF; // I$ memory operation started, delay interrupts
logic SelIROM; // PMA indicates instruction address is in the IROM logic SelIROM; // PMA indicates instruction address is in the IROM
logic [15:0] InstrRawE, InstrRawM; logic [15:0] InstrRawE, InstrRawM;
assign PCFExt = {2'b00, PCSpillF}; assign PCFExt = {2'b00, PCSpillF};
@ -208,13 +208,13 @@ module ifu (
// delay the interrupt until the LSU is in a clean state. // delay the interrupt until the LSU is in a clean state.
assign CommittedF = CacheCommittedF | BusCommittedF; assign CommittedF = CacheCommittedF | BusCommittedF;
logic IgnoreRequest; logic IgnoreRequest;
assign IgnoreRequest = ITLBMissF | FlushD; assign IgnoreRequest = ITLBMissF | FlushD;
// The IROM uses untranslated addresses, so it is not compatible with virtual memory. // The IROM uses untranslated addresses, so it is not compatible with virtual memory.
if (`IROM_SUPPORTED) begin : irom if (`IROM_SUPPORTED) begin : irom
logic IROMce; logic IROMce;
assign IROMce = ~GatedStallD | reset; assign IROMce = ~GatedStallD | reset;
assign IFURWF = 2'b10; assign IFURWF = 2'b10;
irom irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[`XLEN-1:0]), .IROMInstrF); irom irom(.clk, .ce(IROMce), .Adr(PCSpillNextF[`XLEN-1:0]), .IROMInstrF);
end else begin end else begin

View File

@ -27,10 +27,10 @@
`include "wally-config.vh" `include "wally-config.vh"
module irom( module irom(
input logic clk, input logic clk,
input logic ce, // Chip Enable. 0: Holds IROMInstrF constant input logic ce, // Chip Enable. 0: Holds IROMInstrF constant
input logic [`XLEN-1:0] Adr, // PCNextFSpill input logic [`XLEN-1:0] Adr, // PCNextFSpill
output logic [31:0] IROMInstrF // Instruction read data output logic [31:0] IROMInstrF // Instruction read data
); );
localparam XLENBYTES = `XLEN/8; localparam XLENBYTES = `XLEN/8;
@ -38,16 +38,16 @@ module irom(
localparam OFFSET = $clog2(XLENBYTES); localparam OFFSET = $clog2(XLENBYTES);
logic [`XLEN-1:0] IROMInstrFFull; logic [`XLEN-1:0] IROMInstrFFull;
logic [31:0] RawIROMInstrF; logic [31:0] RawIROMInstrF;
logic [1:0] AdrD; logic [1:0] AdrD;
flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD); flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD);
rom1p1r #(ADDR_WDITH, `XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull)); rom1p1r #(ADDR_WDITH, `XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
if (`XLEN == 32) assign RawIROMInstrF = IROMInstrFFull; if (`XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
else begin else begin
// IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two // IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two
// haves. Adr is the Next PCF not PCF so we delay 1 cycle. // haves. Adr is the Next PCF not PCF so we delay 1 cycle.
assign RawIROMInstrF = AdrD[1] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0]; assign RawIROMInstrF = AdrD[1] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
end end
// If the memory addres is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes. // If the memory addres is aligned to 2 bytes return the upper 2 bytes in the lower 2 bytes.

View File

@ -34,31 +34,32 @@
module spill #( module spill #(
parameter CACHE_ENABLED // Changes spill threshold to 1 if there is no cache parameter CACHE_ENABLED // Changes spill threshold to 1 if there is no cache
)(input logic clk, )(input logic clk,
input logic reset, input logic reset,
input logic StallD, FlushD, input logic StallD, FlushD,
input logic [`XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage input logic [`XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage
input logic [`XLEN-1:2] PCPlus4F, // PCF + 4 input logic [`XLEN-1:2] PCPlus4F, // PCF + 4
input logic [`XLEN-1:0] PCNextF, // The next PCF input logic [`XLEN-1:0] PCNextF, // The next PCF
input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
input logic IFUCacheBusStallD, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched input logic IFUCacheBusStallD, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
input logic ITLBMissF, // ITLB miss, ignore memory request input logic ITLBMissF, // ITLB miss, ignore memory request
input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active) input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
output logic [`XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill output logic [`XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill
output logic [`XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill output logic [`XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill
output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline
output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction
output logic CompressedF); // The fetched instruction is compressed output logic CompressedF); // The fetched instruction is compressed
// Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1] // Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1]
typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype; typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype;
statetype CurrState, NextState;
localparam SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1; localparam SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1;
logic [`XLEN-1:0] PCPlus2F;
logic TakeSpillF; statetype CurrState, NextState;
logic SpillF; logic [`XLEN-1:0] PCPlus2F;
logic SelSpillF; logic TakeSpillF;
logic SpillSaveF; logic SpillF;
logic [15:0] InstrFirstHalfF; logic SelSpillF;
logic SpillSaveF;
logic [15:0] InstrFirstHalfF;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// PC logic // PC logic
@ -109,7 +110,7 @@ module spill #(
// Need to use always comb to avoid pessimistic x propagation if PostSpillInstrRawF is x // Need to use always comb to avoid pessimistic x propagation if PostSpillInstrRawF is x
always_comb always_comb
if (PostSpillInstrRawF[1:0] != 2'b11) CompressedF = 1'b1; if (PostSpillInstrRawF[1:0] != 2'b11) CompressedF = 1'b1;
else CompressedF = 1'b0; else CompressedF = 1'b0;
endmodule endmodule

View File

@ -30,14 +30,14 @@
`include "wally-config.vh" `include "wally-config.vh"
module dtim( module dtim(
input logic clk, input logic clk,
input logic FlushW, input logic FlushW,
input logic ce, // Chip Enable. 0: Holds ReadDataWordM input logic ce, // Chip Enable. 0: Holds ReadDataWordM
input logic [1:0] MemRWM, // Read/Write control input logic [1:0] MemRWM, // Read/Write control
input logic [`PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address input logic [`PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address
input logic [`LLEN-1:0] WriteDataM, // Write data from IEU input logic [`LLEN-1:0] WriteDataM, // Write data from IEU
input logic [`LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write input logic [`LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write
output logic [`LLEN-1:0] ReadDataWordM // Read data before subword selection output logic [`LLEN-1:0] ReadDataWordM // Read data before subword selection
); );
logic we; logic we;

View File

@ -37,17 +37,17 @@ module lrsc(
input logic MemReadM, // Memory read input logic MemReadM, // Memory read
input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write
output logic [1:0] LSURWM, // Memory operation after potential squash of SC output logic [1:0] LSURWM, // Memory operation after potential squash of SC
input logic [1:0] LSUAtomicM, // Atomic memory operaiton input logic [1:0] LSUAtomicM, // Atomic memory operaiton
input logic [`PA_BITS-1:0] PAdrM, // Physical memory address input logic [`PA_BITS-1:0] PAdrM, // Physical memory address
output logic SquashSCW // Squash the store conditional by not allowing rf write output logic SquashSCW // Squash the store conditional by not allowing rf write
); );
// possible bug: *** double check if PreLSURWM needs to be flushed by ignorerequest. // possible bug: *** double check if PreLSURWM needs to be flushed by ignorerequest.
// Handle atomic load reserved / store conditional // Handle atomic load reserved / store conditional
logic [`PA_BITS-1:2] ReservationPAdrW; logic [`PA_BITS-1:2] ReservationPAdrW;
logic ReservationValidM, ReservationValidW; logic ReservationValidM, ReservationValidW;
logic lrM, scM, WriteAdrMatchM; logic lrM, scM, WriteAdrMatchM;
logic SquashSCM; logic SquashSCM;
assign lrM = MemReadM & LSUAtomicM[0]; assign lrM = MemReadM & LSUAtomicM[0];
assign scM = PreLSURWM[0] & LSUAtomicM[0]; assign scM = PreLSURWM[0] & LSUAtomicM[0];
@ -56,7 +56,7 @@ module lrsc(
assign LSURWM = SquashSCM ? 2'b00 : PreLSURWM; assign LSURWM = SquashSCM ? 2'b00 : PreLSURWM;
always_comb begin // ReservationValidM (next value of valid reservation) always_comb begin // ReservationValidM (next value of valid reservation)
if (lrM) ReservationValidM = 1; // set valid on load reserve if (lrM) ReservationValidM = 1; // set valid on load reserve
// if we implement multiple harts invalidate reservation if another hart stores to this reservation. // if we implement multiple harts invalidate reservation if another hart stores to this reservation.
else if (scM) ReservationValidM = 0; // clear valid on store to same address or any sc else if (scM) ReservationValidM = 0; // clear valid on store to same address or any sc
else ReservationValidM = ReservationValidW; // otherwise don't change valid else ReservationValidM = ReservationValidW; // otherwise don't change valid
end end

View File

@ -78,61 +78,61 @@ module lsu (
output logic [`XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU output logic [`XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU
// page table walker // page table walker
input logic [`XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR input logic [`XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
input logic [1:0] STATUS_MPP, // Machine previous privilege mode input logic [1:0] STATUS_MPP, // Machine previous privilege mode
input logic [`XLEN-1:0] PCSpillF, // Fetch PC input logic [`XLEN-1:0] PCSpillF, // Fetch PC
input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
output logic [`XLEN-1:0] PTE, // Page table entry write to ITLB output logic [`XLEN-1:0] PTE, // Page table entry write to ITLB
output logic [1:0] PageType, // Type of page table entry to write to ITLB output logic [1:0] PageType, // Type of page table entry to write to ITLB
output logic ITLBWriteF, // Write PTE to ITLB output logic ITLBWriteF, // Write PTE to ITLB
output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // PMP address from privileged unit input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // PMP address from privileged unit
); );
logic [`XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer logic [`XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer
logic [`XLEN+1:0] IEUAdrExtE; // Execution stage address zero-extended to PA_BITS or XLEN whichever is longer logic [`XLEN+1:0] IEUAdrExtE; // Execution stage address zero-extended to PA_BITS or XLEN whichever is longer
logic [`PA_BITS-1:0] PAdrM; // Physical memory address logic [`PA_BITS-1:0] PAdrM; // Physical memory address
logic [`XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address logic [`XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address
logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal
logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC
logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size
logic [6:0] LSUFunct7M; // AMO function gated by HPTW logic [6:0] LSUFunct7M; // AMO function gated by HPTW
logic [1:0] LSUAtomicM; // AMO signal gated by HPTW logic [1:0] LSUAtomicM; // AMO signal gated by HPTW
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1 logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
logic BusStall; // Bus interface busy with multicycle operation logic BusStall; // Bus interface busy with multicycle operation
logic HPTWStall; // HPTW busy with multicycle operation logic HPTWStall; // HPTW busy with multicycle operation
logic CacheableM; // PMA indicates memory address is cacheable logic CacheableM; // PMA indicates memory address is cacheable
logic BusCommittedM; // Bus memory operation in flight, delay interrupts logic BusCommittedM; // Bus memory operation in flight, delay interrupts
logic DCacheCommittedM; // D$ memory operation started, delay interrupts logic DCacheCommittedM; // D$ memory operation started, delay interrupts
logic [`LLEN-1:0] DTIMReadDataWordM; // DTIM read data logic [`LLEN-1:0] DTIMReadDataWordM; // DTIM read data
logic [`LLEN-1:0] DCacheReadDataWordM; // D$ read data logic [`LLEN-1:0] DCacheReadDataWordM; // D$ read data
logic [`LLEN-1:0] ReadDataWordMuxM; // DTIM or D$ read data logic [`LLEN-1:0] ReadDataWordMuxM; // DTIM or D$ read data
logic [`LLEN-1:0] LittleEndianReadDataWordM; // Endian-swapped read data logic [`LLEN-1:0] LittleEndianReadDataWordM; // Endian-swapped read data
logic [`LLEN-1:0] ReadDataWordM; // Read data before subword selection logic [`LLEN-1:0] ReadDataWordM; // Read data before subword selection
logic [`LLEN-1:0] ReadDataM; // Final read data logic [`LLEN-1:0] ReadDataM; // Final read data
logic [`XLEN-1:0] IHWriteDataM; // IEU or HPTW write data logic [`XLEN-1:0] IHWriteDataM; // IEU or HPTW write data
logic [`XLEN-1:0] IMAWriteDataM; // IEU, HPTW, or AMO write data logic [`XLEN-1:0] IMAWriteDataM; // IEU, HPTW, or AMO write data
logic [`LLEN-1:0] IMAFWriteDataM; // IEU, HPTW, AMO, or FPU write data logic [`LLEN-1:0] IMAFWriteDataM; // IEU, HPTW, AMO, or FPU write data
logic [`LLEN-1:0] LittleEndianWriteDataM; // Ending-swapped write data logic [`LLEN-1:0] LittleEndianWriteDataM; // Ending-swapped write data
logic [`LLEN-1:0] LSUWriteDataM; // Final write data logic [`LLEN-1:0] LSUWriteDataM; // Final write data
logic [(`LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write logic [(`LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write
logic DTLBMissM; // DTLB miss causes HPTW walk logic DTLBMissM; // DTLB miss causes HPTW walk
logic DTLBWriteM; // Writes PTE and PageType to DTLB logic DTLBWriteM; // Writes PTE and PageType to DTLB
logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits
logic LSULoadAccessFaultM; // Load acces fault logic LSULoadAccessFaultM; // Load acces fault
logic LSUStoreAmoAccessFaultM; // Store access fault logic LSUStoreAmoAccessFaultM; // Store access fault
logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle
logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation
logic SelDTIM; // Select DTIM rather than bus or D$ logic SelDTIM; // Select DTIM rather than bus or D$
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -164,8 +164,8 @@ module lsu (
assign PreLSURWM = MemRWM; assign PreLSURWM = MemRWM;
assign IHAdrM = IEUAdrExtM; assign IHAdrM = IEUAdrExtM;
assign LSUFunct3M = Funct3M; assign LSUFunct3M = Funct3M;
assign LSUFunct7M = Funct7M; assign LSUFunct7M = Funct7M;
assign LSUAtomicM = AtomicM; assign LSUAtomicM = AtomicM;
assign IHWriteDataM = WriteDataM; assign IHWriteDataM = WriteDataM;
assign LoadAccessFaultM = LSULoadAccessFaultM; assign LoadAccessFaultM = LSULoadAccessFaultM;
assign StoreAmoAccessFaultM = LSUStoreAmoAccessFaultM; assign StoreAmoAccessFaultM = LSUStoreAmoAccessFaultM;
@ -194,7 +194,7 @@ module lsu (
.PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM), .PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM),
.InstrAccessFaultF(), .LoadAccessFaultM(LSULoadAccessFaultM), .InstrAccessFaultF(), .LoadAccessFaultM(LSULoadAccessFaultM),
.StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM, .StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM,
.StoreAmoPageFaultM, .StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw. .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw.
.UpdateDA(DataUpdateDAM), .UpdateDA(DataUpdateDAM),
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), .AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0),
@ -227,7 +227,7 @@ module lsu (
logic [1:0] DTIMMemRWM; logic [1:0] DTIMMemRWM;
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory. // The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
mux2 #(`PA_BITS) DTIMAdrMux(IEUAdrExtE[`PA_BITS-1:0], IEUAdrExtM[`PA_BITS-1:0], MemRWM[0], DTIMAdr); mux2 #(`PA_BITS) DTIMAdrMux(IEUAdrExtE[`PA_BITS-1:0], IEUAdrExtM[`PA_BITS-1:0], MemRWM[0], DTIMAdr);
assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0; assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0;
// **** fix ReadDataWordM to be LLEN. ByteMask is wrong length. // **** fix ReadDataWordM to be LLEN. ByteMask is wrong length.
// **** create config to support DTIM with floating point. // **** create config to support DTIM with floating point.
@ -250,18 +250,18 @@ module lsu (
logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback
logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
logic [1:0] BusRW; // Uncached bus memory access logic [1:0] BusRW; // Uncached bus memory access
logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush
logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11) logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11)
logic [1:0] CacheAtomicM; // Cache AMO logic [1:0] CacheAtomicM; // Cache AMO
logic FlushDCache; // Suppress d cache flush if there is an ITLB miss. logic FlushDCache; // Suppress d cache flush if there is an ITLB miss.
assign BusRW = ~CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0; assign BusRW = ~CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0;
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM; assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM;
assign CacheRWM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0; assign CacheRWM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0;
assign CacheAtomicM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSUAtomicM : '0; assign CacheAtomicM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSUAtomicM : '0;
assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW); assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW);
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache( .NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache(
@ -285,8 +285,8 @@ module lsu (
.Cacheable(CacheableOrFlushCacheM), .BusRW, .Stall(GatedStallW), .Cacheable(CacheableOrFlushCacheM), .BusRW, .Stall(GatedStallW),
.BusStall, .BusCommitted(BusCommittedM)); .BusStall, .BusCommitted(BusCommittedM));
// Mux between the 3 sources of read data, 0: cache, 1: Bus, 2: DTIM // Mux between the 3 sources of read data, 0: cache, 1: Bus, 2: DTIM
// Uncache bus access may be smaller width than LLEN. Duplicate LLENPOVERAHBW times. // Uncache bus access may be smaller width than LLEN. Duplicate LLENPOVERAHBW times.
// *** DTIMReadDataWordM should be increased to LLEN. // *** DTIMReadDataWordM should be increased to LLEN.
// pma should generate exception for LLEN read to periph. // pma should generate exception for LLEN read to periph.
mux3 #(`LLEN) UnCachedDataMux(.d0(DCacheReadDataWordM), .d1({LLENPOVERAHBW{FetchBuffer[`XLEN-1:0]}}), mux3 #(`LLEN) UnCachedDataMux(.d0(DCacheReadDataWordM), .d1({LLENPOVERAHBW{FetchBuffer[`XLEN-1:0]}}),
@ -305,7 +305,7 @@ module lsu (
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM), .HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM),
.Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer)); .Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM // Mux between the 2 sources of read data, 0: Bus, 1: DTIM
if(`DTIM_SUPPORTED) mux2 #(`XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM); if(`DTIM_SUPPORTED) mux2 #(`XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM);
else assign ReadDataWordMuxM = FetchBuffer[`XLEN-1:0]; else assign ReadDataWordMuxM = FetchBuffer[`XLEN-1:0];
assign LSUHBURST = 3'b0; assign LSUHBURST = 3'b0;
@ -338,7 +338,7 @@ module lsu (
// Subword Accesses // Subword Accesses
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
subwordread subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM, subwordread subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM,
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM); .FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
subwordwrite subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM); subwordwrite subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM);
// Compute byte masks // Compute byte masks

View File

@ -31,16 +31,16 @@
module subwordread module subwordread
( (
input logic [`LLEN-1:0] ReadDataWordMuxM, input logic [`LLEN-1:0] ReadDataWordMuxM,
input logic [2:0] PAdrM, input logic [2:0] PAdrM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic FpLoadStoreM, input logic FpLoadStoreM,
input logic BigEndianM, input logic BigEndianM,
output logic [`LLEN-1:0] ReadDataM output logic [`LLEN-1:0] ReadDataM
); );
logic [7:0] ByteM; logic [7:0] ByteM;
logic [15:0] HalfwordM; logic [15:0] HalfwordM;
logic [2:0] PAdrSwap; logic [2:0] PAdrSwap;
// Funct3M[2] is the unsigned bit. mask upper bits. // Funct3M[2] is the unsigned bit. mask upper bits.
// Funct3M[1:0] is the size of the memory access. // Funct3M[1:0] is the size of the memory access.
@ -87,11 +87,11 @@ module subwordread
3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh 3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
3'b010: ReadDataM = {{`LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw 3'b010: ReadDataM = {{`LLEN-32{WordM[31]|FpLoadStoreM}}, WordM[31:0]}; // lw/flw
3'b011: ReadDataM = {{`LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld 3'b011: ReadDataM = {{`LLEN-64{DblWordM[63]|FpLoadStoreM}}, DblWordM[63:0]}; // ld/fld
3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu 3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
// 3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128 //3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu 3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu 3'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
endcase endcase
end else begin:swrmux // 32-bit end else begin:swrmux // 32-bit
@ -114,13 +114,13 @@ module subwordread
// sign extension // sign extension
always_comb always_comb
case(Funct3M) case(Funct3M)
3'b000: ReadDataM = {{`LLEN-8{ByteM[7]}}, ByteM}; // lb 3'b000: ReadDataM = {{`LLEN-8{ByteM[7]}}, ByteM}; // lb
3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh 3'b001: ReadDataM = {{`LLEN-16{HalfwordM[15]|FpLoadStoreM}}, HalfwordM[15:0]}; // lh/flh
3'b010: ReadDataM = {{`LLEN-32{ReadDataWordMuxM[31]|FpLoadStoreM}}, ReadDataWordMuxM[31:0]}; // lw/flw 3'b010: ReadDataM = {{`LLEN-32{ReadDataWordMuxM[31]|FpLoadStoreM}}, ReadDataWordMuxM[31:0]}; // lw/flw
3'b011: ReadDataM = ReadDataWordMuxM; // fld 3'b011: ReadDataM = ReadDataWordMuxM; // fld
3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu 3'b100: ReadDataM = {{`LLEN-8{1'b0}}, ByteM[7:0]}; // lbu
3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu 3'b101: ReadDataM = {{`LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
endcase endcase
end end
endmodule endmodule

View File

@ -36,7 +36,7 @@ module div(
input logic IntDivE, // integer division/remainder instruction of any type input logic IntDivE, // integer division/remainder instruction of any type
input logic DivSignedE, // signed division input logic DivSignedE, // signed division
input logic W64E, // W-type instructions (divw, divuw, remw, remuw) input logic W64E, // W-type instructions (divw, divuw, remw, remuw)
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Forwarding mux outputs for Source A and B input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE,// Forwarding mux outputs for Source A and B
output logic DivBusyE, // Divide is busy - stall pipeline output logic DivBusyE, // Divide is busy - stall pipeline
output logic [`XLEN-1:0] QuotM, RemM // Quotient and remainder outputs output logic [`XLEN-1:0] QuotM, RemM // Quotient and remainder outputs
); );

View File

@ -29,62 +29,62 @@
`include "wally-config.vh" `include "wally-config.vh"
module mdu( module mdu(
input logic clk, reset, input logic clk, reset,
input logic StallM, StallW, input logic StallM, StallW,
input logic FlushE, FlushM, FlushW, input logic FlushE, FlushM, FlushW,
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
input logic [2:0] Funct3E, Funct3M, // type of MDU operation input logic [2:0] Funct3E, Funct3M, // type of MDU operation
input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions
output logic [`XLEN-1:0] MDUResultW, // multiply/divide result output logic [`XLEN-1:0] MDUResultW, // multiply/divide result
output logic DivBusyE // busy signal to stall pipeline in Execute stage output logic DivBusyE // busy signal to stall pipeline in Execute stage
); );
logic [`XLEN*2-1:0] ProdM; // double-width product from mul logic [`XLEN*2-1:0] ProdM; // double-width product from mul
logic [`XLEN-1:0] QuotM, RemM; // quotient and remainder from intdivrestoring logic [`XLEN-1:0] QuotM, RemM; // quotient and remainder from intdivrestoring
logic [`XLEN-1:0] PrelimResultM; // selected result before W truncation logic [`XLEN-1:0] PrelimResultM; // selected result before W truncation
logic [`XLEN-1:0] MDUResultM; // result after W truncation logic [`XLEN-1:0] MDUResultM; // result after W truncation
logic W64M; // W-type instruction logic W64M; // W-type instruction
// Multiplier // Multiplier
mul mul(.clk, .reset, .StallM, .FlushM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ProdM); mul mul(.clk, .reset, .StallM, .FlushM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ProdM);
// Divider // Divider
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing // Start a divide when a new division instruction is received and the divider isn't already busy or finishing
// When IDIV_ON_FPU is set, use the FPU divider instead // When IDIV_ON_FPU is set, use the FPU divider instead
// In ZMMUL, with M_SUPPORTED = 0, omit the divider // In ZMMUL, with M_SUPPORTED = 0, omit the divider
if ((`IDIV_ON_FPU) || (!`M_SUPPORTED)) begin:nodiv if ((`IDIV_ON_FPU) || (!`M_SUPPORTED)) begin:nodiv
assign QuotM = 0; assign QuotM = 0;
assign RemM = 0; assign RemM = 0;
assign DivBusyE = 0; assign DivBusyE = 0;
end else begin:div end else begin:div
div div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE, div div(.clk, .reset, .StallM, .FlushE, .DivSignedE(~Funct3E[0]), .W64E, .IntDivE,
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM); .ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
end end
// Result multiplexer // Result multiplexer
// For ZMMUL, QuotM and RemM are tied to 0, so the mux automatically simplifies // For ZMMUL, QuotM and RemM are tied to 0, so the mux automatically simplifies
always_comb always_comb
case (Funct3M) case (Funct3M)
3'b000: PrelimResultM = ProdM[`XLEN-1:0]; // mul 3'b000: PrelimResultM = ProdM[`XLEN-1:0]; // mul
3'b001: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulh 3'b001: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulh
3'b010: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhsu 3'b010: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhsu
3'b011: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhu 3'b011: PrelimResultM = ProdM[`XLEN*2-1:`XLEN]; // mulhu
3'b100: PrelimResultM = QuotM; // div 3'b100: PrelimResultM = QuotM; // div
3'b101: PrelimResultM = QuotM; // divu 3'b101: PrelimResultM = QuotM; // divu
3'b110: PrelimResultM = RemM; // rem 3'b110: PrelimResultM = RemM; // rem
3'b111: PrelimResultM = RemM; // remu 3'b111: PrelimResultM = RemM; // remu
endcase endcase
// Handle sign extension for W-type instructions // Handle sign extension for W-type instructions
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M); flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
if (`XLEN == 64) begin:resmux // RV64 has W-type instructions if (`XLEN == 64) begin:resmux // RV64 has W-type instructions
assign MDUResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM; assign MDUResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM;
end else begin:resmux // RV32 has no W-type instructions end else begin:resmux // RV32 has no W-type instructions
assign MDUResultM = PrelimResultM; assign MDUResultM = PrelimResultM;
end end
// Writeback stage pipeline register // Writeback stage pipeline register
flopenrc #(`XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW); flopenrc #(`XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW);
endmodule // mdu endmodule // mdu

View File

@ -32,116 +32,116 @@
`include "wally-config.vh" `include "wally-config.vh"
module hptw ( module hptw (
input logic clk, reset, input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table
input logic [`XLEN-1:0] PCSpillF, // addresses to translate input logic [`XLEN-1:0] PCSpillF, // addresses to translate
input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate
input logic [1:0] MemRWM, AtomicM, input logic [1:0] MemRWM, AtomicM,
// system status // system status
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
input logic DCacheStallM, // stall from LSU input logic DCacheStallM, // stall from LSU
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [6:0] Funct7M, input logic [6:0] Funct7M,
input logic ITLBMissF, input logic ITLBMissF,
input logic DTLBMissM, input logic DTLBMissM,
input logic FlushW, input logic FlushW,
input logic InstrUpdateDAF, input logic InstrUpdateDAF,
input logic DataUpdateDAM, input logic DataUpdateDAM,
output logic [`XLEN-1:0] PTE, // page table entry to TLBs output logic [`XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs output logic [1:0] PageType, // page type to TLBs
output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic [1:0] PreLSURWM, output logic [1:0] PreLSURWM,
output logic [`XLEN+1:0] IHAdrM, output logic [`XLEN+1:0] IHAdrM,
output logic [`XLEN-1:0] IHWriteDataM, output logic [`XLEN-1:0] IHWriteDataM,
output logic [1:0] LSUAtomicM, output logic [1:0] LSUAtomicM,
output logic [2:0] LSUFunct3M, output logic [2:0] LSUFunct3M,
output logic [6:0] LSUFunct7M, output logic [6:0] LSUFunct7M,
output logic IgnoreRequestTLB, output logic IgnoreRequestTLB,
output logic SelHPTW, output logic SelHPTW,
output logic HPTWStall, output logic HPTWStall,
input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM,
output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM
); );
typedef enum logic [3:0] {L0_ADR, L0_RD, typedef enum logic [3:0] {L0_ADR, L0_RD,
L1_ADR, L1_RD, L1_ADR, L1_RD,
L2_ADR, L2_RD, L2_ADR, L2_RD,
L3_ADR, L3_RD, L3_ADR, L3_RD,
LEAF, IDLE, UPDATE_PTE} statetype; LEAF, IDLE, UPDATE_PTE} statetype;
logic DTLBWalk; // register TLBs translation miss requests logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`PPN_BITS-1:0] CurrentPPN; logic [`PPN_BITS-1:0] CurrentPPN;
logic Executable, Writable, Readable, Valid, PTE_U; logic Executable, Writable, Readable, Valid, PTE_U;
logic Misaligned, MegapageMisaligned; logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
logic StartWalk; logic StartWalk;
logic TLBMiss; logic TLBMiss;
logic PRegEn; logic PRegEn;
logic [1:0] NextPageType; logic [1:0] NextPageType;
logic [`SVMODE_BITS-1:0] SvMode; logic [`SVMODE_BITS-1:0] SvMode;
logic [`XLEN-1:0] TranslationVAdr; logic [`XLEN-1:0] TranslationVAdr;
logic [`XLEN-1:0] NextPTE; logic [`XLEN-1:0] NextPTE;
logic UpdatePTE; logic UpdatePTE;
logic HPTWUpdateDA; logic HPTWUpdateDA;
logic [`PA_BITS-1:0] HPTWReadAdr; logic [`PA_BITS-1:0] HPTWReadAdr;
logic SelHPTWAdr; logic SelHPTWAdr;
logic [`XLEN+1:0] HPTWAdrExt; logic [`XLEN+1:0] HPTWAdrExt;
logic ITLBMissOrUpdateDAF; logic ITLBMissOrUpdateDAF;
logic DTLBMissOrUpdateDAM; logic DTLBMissOrUpdateDAM;
logic LSUAccessFaultM; logic LSUAccessFaultM;
logic [`PA_BITS-1:0] HPTWAdr; logic [`PA_BITS-1:0] HPTWAdr;
logic [1:0] HPTWRW; logic [1:0] HPTWRW;
logic [2:0] HPTWSize; // 32 or 64 bit access logic [2:0] HPTWSize; // 32 or 64 bit access
statetype WalkerState, NextWalkerState, InitialWalkerState; statetype WalkerState, NextWalkerState, InitialWalkerState;
// map hptw access faults onto either the original LSU load/store fault or instruction access fault // map hptw access faults onto either the original LSU load/store fault or instruction access fault
assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM; assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM;
assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0]; assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[0]; assign StoreAmoAccessFaultM = WalkerState == IDLE ? LSUStoreAmoAccessFaultM : LSUAccessFaultM & DTLBWalk & MemRWM[0];
assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: LSUAccessFaultM & ~DTLBWalk; assign HPTWInstrAccessFaultM = WalkerState == IDLE ? 1'b0: LSUAccessFaultM & ~DTLBWalk;
// Extract bits from CSRs and inputs // Extract bits from CSRs and inputs
assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS];
assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0];
assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF); assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF);
// Determine which address to translate // Determine which address to translate
mux2 #(`XLEN) vadrmux(PCSpillF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr); mux2 #(`XLEN) vadrmux(PCSpillF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr);
assign CurrentPPN = PTE[`PPN_BITS+9:10]; assign CurrentPPN = PTE[`PPN_BITS+9:10];
// State flops // State flops
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB) flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE; assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE;
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
// Assign PTE descriptors common across all XLEN values // Assign PTE descriptors common across all XLEN values
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table // For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
assign {PTE_U, Executable, Writable, Readable, Valid} = PTE[4:0]; assign {PTE_U, Executable, Writable, Readable, Valid} = PTE[4:0];
assign LeafPTE = Executable | Writable | Readable; assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid & ~(Writable & ~Readable); assign ValidPTE = Valid & ~(Writable & ~Readable);
assign ValidLeafPTE = ValidPTE & LeafPTE; assign ValidLeafPTE = ValidPTE & LeafPTE;
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
if(`SVADU_SUPPORTED) begin : hptwwrites if(`SVADU_SUPPORTED) begin : hptwwrites
logic ReadAccess, WriteAccess; logic ReadAccess, WriteAccess;
logic InvalidRead, InvalidWrite, InvalidOp; logic InvalidRead, InvalidWrite, InvalidOp;
logic UpperBitsUnequal; logic UpperBitsUnequal;
logic OtherPageFault; logic OtherPageFault;
logic [1:0] EffectivePrivilegeMode; logic [1:0] EffectivePrivilegeMode;
logic ImproperPrivilege; logic ImproperPrivilege;
logic SaveHPTWAdr, SelHPTWWriteAdr; logic SaveHPTWAdr, SelHPTWWriteAdr;
logic [`PA_BITS-1:0] HPTWWriteAdr; logic [`PA_BITS-1:0] HPTWWriteAdr;
logic SetDirty; logic SetDirty;
logic Dirty, Accessed; logic Dirty, Accessed;
logic [`XLEN-1:0] AccessedPTE; logic [`XLEN-1:0] AccessedPTE;
assign AccessedPTE = {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit assign AccessedPTE = {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE);
flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
assign SaveHPTWAdr = WalkerState == L0_ADR; assign SaveHPTWAdr = WalkerState == L0_ADR;
@ -158,11 +158,11 @@ module hptw (
((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk)); ((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk));
// Check for page faults // Check for page faults
vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr), vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr),
.SV39Mode(), .UpperBitsUnequal); .SV39Mode(), .UpperBitsUnequal);
assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable); assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable);
assign InvalidWrite = WriteAccess & ~Writable; assign InvalidWrite = WriteAccess & ~Writable;
assign InvalidOp = DTLBWalk ? (InvalidRead | InvalidWrite) : ~Executable; assign InvalidOp = DTLBWalk ? (InvalidRead | InvalidWrite) : ~Executable;
assign OtherPageFault = ImproperPrivilege | InvalidOp | UpperBitsUnequal | Misaligned | ~Valid; assign OtherPageFault = ImproperPrivilege | InvalidOp | UpperBitsUnequal | Misaligned | ~Valid;
// hptw needs to know if there is a Dirty or Access fault occuring on this // hptw needs to know if there is a Dirty or Access fault occuring on this
@ -181,62 +181,62 @@ module hptw (
assign HPTWRW[0] = '0; assign HPTWRW[0] = '0;
end end
// Enable and select signals based on states // Enable and select signals based on states
assign StartWalk = (WalkerState == IDLE) & TLBMiss; assign StartWalk = (WalkerState == IDLE) & TLBMiss;
assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD); assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk; assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk;
assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk; assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk;
// FSM to track PageType based on the levels of the page table traversed // FSM to track PageType based on the levels of the page table traversed
flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
always_comb always_comb
case (WalkerState) case (WalkerState)
L3_RD: NextPageType = 2'b11; // terapage L3_RD: NextPageType = 2'b11; // terapage
L2_RD: NextPageType = 2'b10; // gigapage L2_RD: NextPageType = 2'b10; // gigapage
L1_RD: NextPageType = 2'b01; // megapage L1_RD: NextPageType = 2'b01; // megapage
L0_RD: NextPageType = 2'b00; // kilopage L0_RD: NextPageType = 2'b00; // kilopage
default: NextPageType = PageType; default: NextPageType = PageType;
endcase endcase
// HPTWAdr muxing // HPTWAdr muxing
if (`XLEN==32) begin // RV32 if (`XLEN==32) begin // RV32
logic [9:0] VPN; logic [9:0] VPN;
logic [`PPN_BITS-1:0] PPN; logic [`PPN_BITS-1:0] PPN;
assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN; assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN;
assign HPTWReadAdr = {PPN, VPN, 2'b00}; assign HPTWReadAdr = {PPN, VPN, 2'b00};
assign HPTWSize = 3'b010; assign HPTWSize = 3'b010;
end else begin // RV64 end else begin // RV64
logic [8:0] VPN; logic [8:0] VPN;
logic [`PPN_BITS-1:0] PPN; logic [`PPN_BITS-1:0] PPN;
always_comb always_comb
case (WalkerState) // select VPN field based on HPTW state case (WalkerState) // select VPN field based on HPTW state
L3_ADR, L3_RD: VPN = TranslationVAdr[47:39]; L3_ADR, L3_RD: VPN = TranslationVAdr[47:39];
L2_ADR, L2_RD: VPN = TranslationVAdr[38:30]; L2_ADR, L2_RD: VPN = TranslationVAdr[38:30];
L1_ADR, L1_RD: VPN = TranslationVAdr[29:21]; L1_ADR, L1_RD: VPN = TranslationVAdr[29:21];
default: VPN = TranslationVAdr[20:12]; default: VPN = TranslationVAdr[20:12];
endcase endcase
assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) | assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) |
(SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN; (SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
assign HPTWReadAdr = {PPN, VPN, 3'b000}; assign HPTWReadAdr = {PPN, VPN, 3'b000};
assign HPTWSize = 3'b011; assign HPTWSize = 3'b011;
end end
// Initial state and misalignment for RV32/64 // Initial state and misalignment for RV32/64
if (`XLEN == 32) begin if (`XLEN == 32) begin
assign InitialWalkerState = L1_ADR; assign InitialWalkerState = L1_ADR;
assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0 assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0
assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned); assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned);
end else begin end else begin
logic GigapageMisaligned, TerapageMisaligned; logic GigapageMisaligned, TerapageMisaligned;
assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR; assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR;
assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0 assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0
assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0 assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0
assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0 assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0
assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned); assign Misaligned = ((WalkerState == L2_ADR) & TerapageMisaligned) | ((WalkerState == L1_ADR) & GigapageMisaligned) | ((WalkerState == L0_ADR) & MegapageMisaligned);
end end
// Page Table Walker FSM // Page Table Walker FSM
// there is a bug here. Each memory access needs to be potentially flushed if the PMA/P checkers // there is a bug here. Each memory access needs to be potentially flushed if the PMA/P checkers
// generate an access fault. Specially the store on UDPATE_PTE needs to check for access violation. // generate an access fault. Specially the store on UDPATE_PTE needs to check for access violation.
// I think the solution is to do 1 of the following // I think the solution is to do 1 of the following
@ -244,32 +244,32 @@ module hptw (
// 2. If the store would generate an exception don't store to dcache but still write the TLB. When we go back // 2. If the store would generate an exception don't store to dcache but still write the TLB. When we go back
// to LEAF then the PMA/P. Wait this does not work. The PMA/P won't be looking a the address in the table, but // to LEAF then the PMA/P. Wait this does not work. The PMA/P won't be looking a the address in the table, but
// rather than physical address of the translated instruction/data. So we must generate the exception. // rather than physical address of the translated instruction/data. So we must generate the exception.
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb always_comb
case (WalkerState) case (WalkerState)
IDLE: if (TLBMiss & ~DCacheStallM) NextWalkerState = InitialWalkerState; IDLE: if (TLBMiss & ~DCacheStallM) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48 L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD; L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
else NextWalkerState = L2_ADR; else NextWalkerState = L2_ADR;
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39 L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD; L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
else NextWalkerState = L1_ADR; else NextWalkerState = L1_ADR;
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32 L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD; L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
else NextWalkerState = L0_ADR; else NextWalkerState = L0_ADR;
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD; L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD; L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
LEAF: if (`SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE; LEAF: if (`SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE; UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
default: NextWalkerState = IDLE; // should never be reached default: NextWalkerState = IDLE; // should never be reached
endcase // case (WalkerState) endcase // case (WalkerState)
assign IgnoreRequestTLB = WalkerState == IDLE & TLBMiss; assign IgnoreRequestTLB = WalkerState == IDLE & TLBMiss;
assign SelHPTW = WalkerState != IDLE; assign SelHPTW = WalkerState != IDLE;

View File

@ -108,12 +108,12 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) (
.Cacheable, .Idempotent, .SelTIM, .Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
if (`PMP_ENTRIES > 0) if (`PMP_ENTRIES > 0) begin : pmp
pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.ExecuteAccessF, .WriteAccessM, .ReadAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM,
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
else begin end else begin
assign PMPInstrAccessFaultF = 0; assign PMPInstrAccessFaultF = 0;
assign PMPStoreAmoAccessFaultM = 0; assign PMPStoreAmoAccessFaultM = 0;
assign PMPLoadAccessFaultM = 0; assign PMPLoadAccessFaultM = 0;

View File

@ -38,7 +38,7 @@ module pmpadrdec (
input logic [`PA_BITS-3:0] PMPAdr, input logic [`PA_BITS-3:0] PMPAdr,
input logic PAgePMPAdrIn, input logic PAgePMPAdrIn,
output logic PAgePMPAdrOut, output logic PAgePMPAdrOut,
output logic Match, Active, output logic Match,
output logic L, X, W, R output logic L, X, W, R
); );
@ -84,7 +84,6 @@ module pmpadrdec (
assign X = PMPCfg[2]; assign X = PMPCfg[2];
assign W = PMPCfg[1]; assign W = PMPCfg[1];
assign R = PMPCfg[0]; assign R = PMPCfg[0];
assign Active = |PMPCfg[4:3];
// known bug: The size of the access is not yet checked. For example, if an NA4 entry matches 0xC-0xF and the system // known bug: The size of the access is not yet checked. For example, if an NA4 entry matches 0xC-0xF and the system
// attempts an 8-byte access to 0x8, the access should fail (see page 60 of privileged specification 20211203). This // attempts an 8-byte access to 0x8, the access should fail (see page 60 of privileged specification 20211203). This

View File

@ -53,25 +53,23 @@ module pmpchecker (
logic EnforcePMP; // should PMP be checked in this privilege level logic EnforcePMP; // should PMP be checked in this privilege level
logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges
logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address.
logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null
logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
if (`PMP_ENTRIES > 0) // prevent complaints about array of no elements when PMP_ENTRIES = 0 if (`PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0
pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
.PhysicalAddress, .PhysicalAddress,
.PMPCfg(PMPCFG_ARRAY_REGW), .PMPCfg(PMPCFG_ARRAY_REGW),
.PMPAdr(PMPADDR_ARRAY_REGW), .PMPAdr(PMPADDR_ARRAY_REGW),
.PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}), .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
.PAgePMPAdrOut(PAgePMPAdr), .PAgePMPAdrOut(PAgePMPAdr),
.Match, .Active, .L, .X, .W, .R); .Match, .L, .X, .W, .R);
end
priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches. priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
// Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region // Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |(L & FirstMatch) : |Active; assign EnforcePMP = (PrivilegeModeW != `M_MODE) | |(L & FirstMatch); // *** switch to this logic when PMP is initialized for non-machine mode
// assign EnforcePMP = (PrivilegeModeW != `M_MODE) | |(L & FirstMatch); // *** switch to this logic when PMP is initialized for non-machine mode
// *** remove unused Active lines from pmpadrdecs
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ; assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ;

View File

@ -84,8 +84,8 @@ module tlb #(parameter TLB_ENTRIES = 8, ITLB = 0) (
logic [1:0] HitPageType; logic [1:0] HitPageType;
logic CAMHit; logic CAMHit;
logic SV39Mode; logic SV39Mode;
logic Misaligned; logic Misaligned;
logic MegapageMisaligned; logic MegapageMisaligned;
if(`XLEN == 32) begin if(`XLEN == 32) begin
assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0 assign MegapageMisaligned = |(PPN[9:0]); // must have zero PPN0

View File

@ -96,11 +96,11 @@ module csr #(parameter
); );
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM; logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM;
logic [`XLEN-1:0] CSRReadValM; logic [`XLEN-1:0] CSRReadValM;
logic [`XLEN-1:0] CSRSrcM; logic [`XLEN-1:0] CSRSrcM;
logic [`XLEN-1:0] CSRRWM, CSRRSM, CSRRCM; logic [`XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
logic [`XLEN-1:0] CSRWriteValM; logic [`XLEN-1:0] CSRWriteValM;
logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW; logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
logic [`XLEN-1:0] STVEC_REGW, MTVEC_REGW; logic [`XLEN-1:0] STVEC_REGW, MTVEC_REGW;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW; logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW;
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
@ -117,7 +117,7 @@ module csr #(parameter
logic [`XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM; logic [`XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM;
logic MTrapM, STrapM; logic MTrapM, STrapM;
logic [`XLEN-1:0] EPC; logic [`XLEN-1:0] EPC;
logic RetM; logic RetM;
logic SelMtvecM; logic SelMtvecM;
logic [`XLEN-1:0] TVecAlignedM; logic [`XLEN-1:0] TVecAlignedM;
logic InstrValidNotFlushedM; logic InstrValidNotFlushedM;
@ -153,7 +153,7 @@ module csr #(parameter
logic VectoredM; logic VectoredM;
logic [`XLEN-1:0] TVecPlusCauseM; logic [`XLEN-1:0] TVecPlusCauseM;
assign VectoredM = InterruptM & (TVecM[1:0] == 2'b01); assign VectoredM = InterruptM & (TVecM[1:0] == 2'b01);
assign TVecPlusCauseM = {TVecAlignedM[`XLEN-1:6], CauseM[3:0], 2'b00}; // 64-byte alignment allows concatenation rather than addition assign TVecPlusCauseM = {TVecAlignedM[`XLEN-1:6], CauseM[3:0], 2'b00}; // 64-byte alignment allows concatenation rather than addition
mux2 #(`XLEN) trapvecmux(TVecAlignedM, TVecPlusCauseM, VectoredM, TrapVectorM); mux2 #(`XLEN) trapvecmux(TVecAlignedM, TVecPlusCauseM, VectoredM, TrapVectorM);
end else end else
assign TrapVectorM = TVecAlignedM; assign TrapVectorM = TVecAlignedM;

View File

@ -40,48 +40,48 @@ module csrc #(parameter
TIME = 12'hC01, TIME = 12'hC01,
TIMEH = 12'hC81 TIMEH = 12'hC81
) ( ) (
input logic clk, reset, input logic clk, reset,
input logic StallE, StallM, input logic StallE, StallM,
input logic FlushM, input logic FlushM,
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD, input logic InstrValidNotFlushedM, LoadStallD, StoreStallD,
input logic CSRMWriteM, CSRWriteM, input logic CSRMWriteM, CSRWriteM,
input logic BPDirPredWrongM, input logic BPDirPredWrongM,
input logic BTAWrongM, input logic BTAWrongM,
input logic RASPredPCWrongM, input logic RASPredPCWrongM,
input logic IClassWrongM, input logic IClassWrongM,
input logic BPWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, input logic [3:0] InstrClassM,
input logic DCacheMiss, input logic DCacheMiss,
input logic DCacheAccess, input logic DCacheAccess,
input logic ICacheMiss, input logic ICacheMiss,
input logic ICacheAccess, input logic ICacheAccess,
input logic ICacheStallF, input logic ICacheStallF,
input logic DCacheStallM, input logic DCacheStallM,
input logic sfencevmaM, input logic sfencevmaM,
input logic InterruptM, input logic InterruptM,
input logic ExceptionM, input logic ExceptionM,
input logic InvalidateICacheM, input logic InvalidateICacheM,
input logic DivBusyE, // integer divide busy input logic DivBusyE, // integer divide busy
input logic FDivBusyE, // floating point divide busy input logic FDivBusyE, // floating point divide busy
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
output logic [`XLEN-1:0] CSRCReadValM, output logic [`XLEN-1:0] CSRCReadValM,
output logic IllegalCSRCAccessM output logic IllegalCSRCAccessM
); );
logic [4:0] CounterNumM; logic [4:0] CounterNumM;
logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0]; logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0];
logic [`XLEN-1:0] HPMCOUNTERH_REGW[`COUNTERS-1:0]; logic [`XLEN-1:0] HPMCOUNTERH_REGW[`COUNTERS-1:0];
logic LoadStallE, LoadStallM; logic LoadStallE, LoadStallM;
logic StoreStallE, StoreStallM; logic StoreStallE, StoreStallM;
logic [`COUNTERS-1:0] WriteHPMCOUNTERM; logic [`COUNTERS-1:0] WriteHPMCOUNTERM;
logic [`COUNTERS-1:0] CounterEvent; logic [`COUNTERS-1:0] CounterEvent;
logic [63:0] HPMCOUNTERPlusM[`COUNTERS-1:0]; logic [63:0] HPMCOUNTERPlusM[`COUNTERS-1:0];
logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:0]; logic [`XLEN-1:0] NextHPMCOUNTERM[`COUNTERS-1:0];
genvar i; genvar i;
// Interface signals // Interface signals
flopenrc #(2) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d({StoreStallD, LoadStallD}), .q({StoreStallE, LoadStallE})); // don't flush the load stall during a load stall. flopenrc #(2) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d({StoreStallD, LoadStallD}), .q({StoreStallE, LoadStallE})); // don't flush the load stall during a load stall.
@ -97,11 +97,11 @@ module csrc #(parameter
assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction
assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions
assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions
assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong
assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction
assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target
assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
assign CounterEvent[11] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. assign CounterEvent[11] = LoadStallM & InstrValidNotFlushedM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
assign CounterEvent[12] = StoreStallM & InstrValidNotFlushedM; // Store Stall assign CounterEvent[12] = StoreStallM & InstrValidNotFlushedM; // Store Stall
assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access
@ -111,7 +111,7 @@ module csrc #(parameter
assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[18] = ICacheStallF; // i cache miss cycles assign CounterEvent[18] = ICacheStallF; // i cache miss cycles
assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes
assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i
assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma
assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low
assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low

View File

@ -34,14 +34,14 @@ module csri #(parameter
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, input logic InstrValidNotFlushedM,
input logic CSRMWriteM, CSRSWriteM, input logic CSRMWriteM, CSRSWriteM,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt, input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt,
input logic [11:0] MIDELEG_REGW, input logic [11:0] MIDELEG_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, output logic [11:0] MIP_REGW, MIE_REGW,
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
); );

View File

@ -72,30 +72,30 @@ module csrm #(parameter
MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11), MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11),
MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable
) ( ) (
input logic clk, reset, input logic clk, reset,
input logic InstrValidNotFlushedM, input logic InstrValidNotFlushedM,
input logic CSRMWriteM, MTrapM, input logic CSRMWriteM, MTrapM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW, input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
input logic [11:0] MIP_REGW, MIE_REGW, input logic [11:0] MIP_REGW, MIE_REGW,
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW, output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
output logic [`XLEN-1:0] MEPC_REGW, 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, output logic [`XLEN-1:0] MEDELEG_REGW,
output logic [11:0] MIDELEG_REGW, output logic [11:0] MIDELEG_REGW,
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
output logic WriteMSTATUSM, WriteMSTATUSHM, output logic WriteMSTATUSM, WriteMSTATUSHM,
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM
); );
logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW;
logic [`XLEN-1:0] MSCRATCH_REGW; logic [`XLEN-1:0] MSCRATCH_REGW;
logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW; logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW;
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
genvar i; genvar i;

View File

@ -44,23 +44,23 @@ module csrs #(parameter
STIMECMP = 12'h14D, STIMECMP = 12'h14D,
STIMECMPH = 12'h15D, STIMECMPH = 12'h15D,
SATP = 12'h180) ( SATP = 12'h180) (
input logic clk, reset, input logic clk, reset,
input logic InstrValidNotFlushedM, input logic InstrValidNotFlushedM,
input logic CSRSWriteM, STrapM, input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW, input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
input logic STATUS_TVM, input logic STATUS_TVM,
input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW, output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
output logic [`XLEN-1:0] SEPC_REGW, output logic [`XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW, output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
output logic WriteSSTATUSM, output logic WriteSSTATUSM,
output logic IllegalCSRSAccessM, output logic IllegalCSRSAccessM,
output logic STimerInt output logic STimerInt
); );
@ -68,13 +68,13 @@ module csrs #(parameter
localparam ZERO = {(`XLEN){1'b0}}; localparam ZERO = {(`XLEN){1'b0}};
localparam SEDELEG_MASK = ~(ZERO | `XLEN'b111 << 9); localparam SEDELEG_MASK = ~(ZERO | `XLEN'b111 << 9);
logic WriteSTVECM; logic WriteSTVECM;
logic WriteSSCRATCHM, WriteSEPCM; logic WriteSSCRATCHM, WriteSEPCM;
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
logic WriteSTIMECMPM, WriteSTIMECMPHM; logic WriteSTIMECMPM, WriteSTIMECMPHM;
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW; logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
logic [`XLEN-1:0] SCAUSE_REGW; logic [`XLEN-1:0] SCAUSE_REGW;
logic [63:0] STIMECMP_REGW; logic [63:0] STIMECMP_REGW;
// write enables // write enables
// *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM? // *** can InstrValidNotFlushed be factored out of all these writes into CSRWriteM?
@ -129,10 +129,10 @@ module csrs #(parameter
SCAUSE: CSRSReadValM = SCAUSE_REGW; SCAUSE: CSRSReadValM = SCAUSE_REGW;
STVAL: CSRSReadValM = STVAL_REGW; STVAL: CSRSReadValM = STVAL_REGW;
SATP: if (`VIRTMEM_SUPPORTED & (PrivilegeModeW == `M_MODE | ~STATUS_TVM)) CSRSReadValM = SATP_REGW; SATP: if (`VIRTMEM_SUPPORTED & (PrivilegeModeW == `M_MODE | ~STATUS_TVM)) CSRSReadValM = SATP_REGW;
else begin else begin
CSRSReadValM = 0; CSRSReadValM = 0;
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1; IllegalCSRSAccessM = 1;
end end
SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW}; SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
STIMECMP: if (`SSTC_SUPPORTED & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0]; STIMECMP: if (`SSTC_SUPPORTED & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0];
else begin else begin

View File

@ -68,7 +68,7 @@ module csrsr (
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be. assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
end else begin: csrsr32 // RV32 end else begin: csrsr32 // RV32
assign MSTATUS_REGW = {STATUS_SD, 8'b0, assign MSTATUS_REGW = {STATUS_SD, 8'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,

View File

@ -48,7 +48,7 @@ module csru #(parameter
logic [4:0] FFLAGS_REGW; logic [4:0] FFLAGS_REGW;
logic [2:0] NextFRMM; logic [2:0] NextFRMM;
logic [4:0] NextFFLAGSM; logic [4:0] NextFFLAGSM;
logic SetOrWriteFFLAGSM; logic SetOrWriteFFLAGSM;
// Write enables // Write enables
//assign WriteFCSRM = CSRUWriteM & (CSRAdrM == FCSR) & InstrValidNotFlushedM; //assign WriteFCSRM = CSRUWriteM & (CSRAdrM == FCSR) & InstrValidNotFlushedM;

View File

@ -34,86 +34,86 @@ module privileged (
input logic StallD, StallE, StallM, StallW, input logic StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
// CSR Reads and Writes, and values needed for traps // CSR Reads and Writes, and values needed for traps
input logic CSRReadM, CSRWriteM, // Read or write CSRs input logic CSRReadM, CSRWriteM, // Read or write CSRs
input logic [`XLEN-1:0] SrcAM, // GPR register to write input logic [`XLEN-1:0] SrcAM, // GPR register to write
input logic [31:0] InstrM, // Instruction input logic [31:0] InstrM, // Instruction
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
input logic [`XLEN-1:0] IEUAdrM, // address from IEU input logic [`XLEN-1:0] IEUAdrM, // address from IEU
input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic input logic [`XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic
// control signals // control signals
input logic InstrValidM, // Current instruction is valid (not flushed) input logic InstrValidM, // Current instruction is valid (not flushed)
input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt
input logic PrivilegedM, // privileged instruction input logic PrivilegedM, // privileged instruction
// processor events for performance counter logging // processor events for performance counter logging
input logic FRegWriteM, // instruction will write floating-point registers input logic FRegWriteM, // instruction will write floating-point registers
input logic LoadStallD, // load instruction is stalling input logic LoadStallD, // load instruction is stalling
input logic StoreStallD, // store instruction is stalling input logic StoreStallD, // store instruction is stalling
input logic ICacheStallF, // I cache stalled input logic ICacheStallF, // I cache stalled
input logic DCacheStallM, // D cache stalled input logic DCacheStallM, // D cache stalled
input logic BPDirPredWrongM, // branch predictor guessed wrong direction input logic BPDirPredWrongM, // branch predictor guessed wrong direction
input logic BTAWrongM, // branch predictor guessed wrong target input logic BTAWrongM, // branch predictor guessed wrong target
input logic RASPredPCWrongM, // return adddress stack guessed wrong target input logic RASPredPCWrongM, // return adddress stack guessed wrong target
input logic IClassWrongM, // branch predictor guessed wrong instruction class input logic IClassWrongM, // branch predictor guessed wrong instruction class
input logic BPWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, // actual instruction class input logic [3:0] InstrClassM, // actual instruction class
input logic DCacheMiss, // data cache miss input logic DCacheMiss, // data cache miss
input logic DCacheAccess, // data cache accessed (hit or miss) input logic DCacheAccess, // data cache accessed (hit or miss)
input logic ICacheMiss, // instruction cache miss input logic ICacheMiss, // instruction cache miss
input logic ICacheAccess, // instruction cache access input logic ICacheAccess, // instruction cache access
input logic DivBusyE, // integer divide busy input logic DivBusyE, // integer divide busy
input logic FDivBusyE, // floating point divide busy input logic FDivBusyE, // floating point divide busy
// fault sources // fault sources
input logic InstrAccessFaultF, // instruction access fault input logic InstrAccessFaultF, // instruction access fault
input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault
input logic HPTWInstrAccessFaultM, // hardware page table access fault while fetching instruction PTE input logic HPTWInstrAccessFaultM, // hardware page table access fault while fetching instruction PTE
input logic InstrPageFaultF, // page faults input logic InstrPageFaultF, // page faults
input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults
input logic InstrMisalignedFaultM, // misaligned instruction fault input logic InstrMisalignedFaultM, // misaligned instruction fault
input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault
input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU
input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources
input logic [63:0] MTIME_CLINT, // timer value from CLINT input logic [63:0] MTIME_CLINT, // timer value from CLINT
input logic [4:0] SetFflagsM, // set FCSR flags from FPU input logic [4:0] SetFflagsM, // set FCSR flags from FPU
input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses
// CSR outputs // CSR outputs
output logic [`XLEN-1:0] CSRReadValW, // Value read from CSR output logic [`XLEN-1:0] CSRReadValW, // Value read from CSR
output logic [1:0] PrivilegeModeW, // current privilege mode output logic [1:0] PrivilegeModeW, // current privilege mode
output logic [`XLEN-1:0] SATP_REGW, // supervisor address translation register output logic [`XLEN-1:0] SATP_REGW, // supervisor address translation register
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits
output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration entries to MMU output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration entries to MMU
output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // PMP address entries to MMU output var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0], // PMP address entries to MMU
output logic [2:0] FRM_REGW, // FPU rounding mode output logic [2:0] FRM_REGW, // FPU rounding mode
// PC logic output in privileged unit // PC logic output in privileged unit
output logic [`XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic output logic [`XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic
// control outputs // control outputs
output logic RetM, TrapM, // return instruction, or trap output logic RetM, TrapM, // return instruction, or trap
output logic sfencevmaM, // sfence.vma instruction output logic sfencevmaM, // sfence.vma instruction
input logic InvalidateICacheM, // fence instruction input logic InvalidateICacheM, // fence instruction
output logic BigEndianM, // Use big endian in current privilege mode output logic BigEndianM, // Use big endian in current privilege mode
// Fault outputs // Fault outputs
output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire
output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout
); );
logic [`LOG_XLEN-1:0] CauseM; // trap cause logic [`LOG_XLEN-1:0] CauseM; // trap cause
logic [`XLEN-1:0] MEDELEG_REGW; // exception delegation CSR logic [`XLEN-1:0] MEDELEG_REGW; // exception delegation CSR
logic [11:0] MIDELEG_REGW; // interrupt delegation CSR logic [11:0] MIDELEG_REGW; // interrupt delegation CSR
logic sretM, mretM; // supervisor / machine return instruction logic sretM, mretM; // supervisor / machine return instruction
logic IllegalCSRAccessM; // Illegal access to CSR logic IllegalCSRAccessM; // Illegal access to CSR
logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage
logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage
logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages
logic IllegalInstrFaultM; // Illegal instruction fault logic IllegalInstrFaultM; // Illegal instruction fault
logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit
logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables
logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits
logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
logic DelegateM; // trap should be delegated logic DelegateM; // trap should be delegated
logic wfiM; // wait for interrupt instruction logic wfiM; // wait for interrupt instruction
logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi
logic InterruptM; // interrupt occuring logic InterruptM; // interrupt occuring
logic ExceptionM; // Memory stage instruction caused a fault logic ExceptionM; // Memory stage instruction caused a fault
// track the current privilege level // track the current privilege level
privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM, privmode privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,

View File

@ -29,33 +29,33 @@
`include "wally-config.vh" `include "wally-config.vh"
module trap ( module trap (
input logic reset, input logic reset,
input logic InstrMisalignedFaultM, InstrAccessFaultM, HPTWInstrAccessFaultM, IllegalInstrFaultM, input logic InstrMisalignedFaultM, InstrAccessFaultM, HPTWInstrAccessFaultM, IllegalInstrFaultM,
input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM, input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM, input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources
input logic mretM, sretM, // return instructions input logic mretM, sretM, // return instructions
input logic wfiM, // wait for interrupt instruction input logic wfiM, // wait for interrupt instruction
input logic [1:0] PrivilegeModeW, // current privilege mode input logic [1:0] PrivilegeModeW, // current privilege mode
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs
input logic [`XLEN-1:0] MEDELEG_REGW, // exception delegation SR input logic [`XLEN-1:0] MEDELEG_REGW, // exception delegation SR
input logic STATUS_MIE, STATUS_SIE, // machine/supervisor interrupt enables input logic STATUS_MIE, STATUS_SIE, // machine/supervisor interrupt enables
input logic InstrValidM, // current instruction is valid, not flushed input logic InstrValidM, // current instruction is valid, not flushed
input logic CommittedM, CommittedF, // LSU/IFU has committed to a bus operation that can't be interrupted input logic CommittedM, CommittedF, // LSU/IFU has committed to a bus operation that can't be interrupted
output logic TrapM, // Trap is occurring output logic TrapM, // Trap is occurring
output logic RetM, // Return instruction being executed output logic RetM, // Return instruction being executed
output logic InterruptM, // Interrupt is occurring output logic InterruptM, // Interrupt is occurring
output logic ExceptionM, // exception is occurring output logic ExceptionM, // exception is occurring
output logic IntPendingM, // Interrupt is pending, might occur if enabled output logic IntPendingM, // Interrupt is pending, might occur if enabled
output logic DelegateM, // Delegate trap to supervisor handler output logic DelegateM, // Delegate trap to supervisor handler
output logic WFIStallM, // Stall due to WFI instruction output logic WFIStallM, // Stall due to WFI instruction
output logic [`LOG_XLEN-1:0] CauseM // trap cause output logic [`LOG_XLEN-1:0] CauseM // trap cause
); );
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
logic BothInstrAccessFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault logic BothInstrAccessFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
/////////////////////////////////////////// ///////////////////////////////////////////
// Determine pending enabled interrupts // Determine pending enabled interrupts

View File

@ -40,7 +40,7 @@ module clint_apb (
output logic [`XLEN-1:0] PRDATA, output logic [`XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
output logic [63:0] MTIME, output logic [63:0] MTIME,
output logic MTimerInt, MSwInt output logic MTimerInt, MSwInt
); );
logic MSIP; logic MSIP;

View File

@ -41,8 +41,8 @@ module gpio_apb (
output logic [`XLEN-1:0] PRDATA, output logic [`XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic [31:0] iof0, iof1, input logic [31:0] iof0, iof1,
input logic [31:0] GPIOPinsIn, input logic [31:0] GPIOIN,
output logic [31:0] GPIOPinsOut, GPIOPinsEn, output logic [31:0] GPIOOUT, GPIOEN,
output logic GPIOIntr output logic GPIOIntr
); );
@ -138,8 +138,8 @@ module gpio_apb (
// chip i/o // chip i/o
// connect OUT to IN for loopback testing // connect OUT to IN for loopback testing
if (`GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOPinsOut) | (~output_en & GPIOPinsIn)) & input_en; if (`GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en;
else assign input0d = GPIOPinsIn & input_en; else assign input0d = GPIOIN & input_en;
// synchroninzer for inputs // synchroninzer for inputs
flop #(32) sync1(PCLK,input0d,input1d); flop #(32) sync1(PCLK,input0d,input1d);
@ -148,8 +148,8 @@ module gpio_apb (
assign input_val = input3d; assign input_val = input3d;
assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0 assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0
assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val
assign GPIOPinsOut = gpio_out ^ out_xor; // per-bit flip output polarity assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity
assign GPIOPinsEn = output_en; assign GPIOEN = output_en;
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)}; assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)};
endmodule endmodule

View File

@ -43,37 +43,37 @@
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts // hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
module plic_apb ( module plic_apb (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [27:0] PADDR, input logic [27:0] PADDR,
input logic [`XLEN-1:0] PWDATA, input logic [`XLEN-1:0] PWDATA,
input logic [`XLEN/8-1:0] PSTRB, input logic [`XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [`XLEN-1:0] PRDATA, output logic [`XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic UARTIntr,GPIOIntr, input logic UARTIntr,GPIOIntr,
output logic MExtInt, SExtInt output logic MExtInt, SExtInt
); );
logic memwrite, memread; logic memwrite, memread;
logic [23:0] entry; logic [23:0] entry;
logic [31:0] Din, Dout; logic [31:0] Din, Dout;
// context-independent signals // context-independent signals
logic [`N:1] requests; logic [`N:1] requests;
logic [`N:1][2:0] intPriority; logic [`N:1][2:0] intPriority;
logic [`N:1] intInProgress, intPending, nextIntPending; logic [`N:1] intInProgress, intPending, nextIntPending;
// context-dependent signals // context-dependent signals
logic [`C-1:0][2:0] intThreshold; logic [`C-1:0][2:0] intThreshold;
logic [`C-1:0][`N:1] intEn; logic [`C-1:0][`N:1] intEn;
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
logic [`C-1:0][7:1][`N:1] irqMatrix; logic [`C-1:0][7:1][`N:1] irqMatrix;
logic [`C-1:0][7:1] priorities_with_irqs; logic [`C-1:0][7:1] priorities_with_irqs;
logic [`C-1:0][7:1] max_priority_with_irqs; logic [`C-1:0][7:1] max_priority_with_irqs;
logic [`C-1:0][`N:1] irqs_at_max_priority; logic [`C-1:0][`N:1] irqs_at_max_priority;
logic [`C-1:0][7:1] threshMask; logic [`C-1:0][7:1] threshMask;
// ======= // =======
// AHB I/O // AHB I/O
@ -97,7 +97,7 @@ module plic_apb (
// ================== // ==================
// Register Interface // Register Interface
// ================== // ==================
always @(posedge PCLK,negedge PRESETn) begin always @(posedge PCLK) begin
// resetting // resetting
if (~PRESETn) begin if (~PRESETn) begin
intPriority <= #1 {`N{3'b0}}; intPriority <= #1 {`N{3'b0}};

View File

@ -30,27 +30,27 @@
`define RAM_LATENCY 0 `define RAM_LATENCY 0
module ram_ahb #(parameter BASE=0, RANGE = 65535) ( module ram_ahb #(parameter BASE=0, RANGE = 65535) (
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic HSELRam, input logic HSELRam,
input logic [`PA_BITS-1:0] HADDR, input logic [`PA_BITS-1:0] HADDR,
input logic HWRITE, input logic HWRITE,
input logic HREADY, input logic HREADY,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic [`XLEN-1:0] HWDATA, input logic [`XLEN-1:0] HWDATA,
input logic [`XLEN/8-1:0] HWSTRB, input logic [`XLEN/8-1:0] HWSTRB,
output logic [`XLEN-1:0] HREADRam, output logic [`XLEN-1:0] HREADRam,
output logic HRESPRam, HREADYRam output logic HRESPRam, HREADYRam
); );
localparam ADDR_WIDTH = $clog2(RANGE/8); localparam ADDR_WIDTH = $clog2(RANGE/8);
localparam OFFSET = $clog2(`XLEN/8); localparam OFFSET = $clog2(`XLEN/8);
logic [`XLEN/8-1:0] ByteMask; logic [`XLEN/8-1:0] ByteMask;
logic [`PA_BITS-1:0] HADDRD, RamAddr; logic [`PA_BITS-1:0] HADDRD, RamAddr;
logic initTrans; logic initTrans;
logic memwrite, memwriteD, memread; logic memwrite, memwriteD, memread;
logic nextHREADYRam; logic nextHREADYRam;
logic DelayReady; logic DelayReady;
// a new AHB transactions starts when HTRANS requests a transaction, // a new AHB transactions starts when HTRANS requests a transaction,
// the peripheral is selected, and the previous transaction is completing // the peripheral is selected, and the previous transaction is completing
@ -92,13 +92,13 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
always_comb begin always_comb begin
case(CurrState) case(CurrState)
READY: if(initTrans & ~CycleFlag) NextState = DELAY; READY: if(initTrans & ~CycleFlag) NextState = DELAY;
else NextState = READY; else NextState = READY;
DELAY: if(CycleFlag) NextState = READY; DELAY: if(CycleFlag) NextState = READY;
else NextState = DELAY; else NextState = DELAY;
default: NextState = READY; default: NextState = READY;
endcase endcase
end end
assign CycleFlag = Cycle == `RAM_LATENCY; assign CycleFlag = Cycle == `RAM_LATENCY;
@ -109,6 +109,5 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
assign DelayReady = 0; assign DelayReady = 0;
end end
endmodule endmodule

View File

@ -37,19 +37,19 @@
/* verilator lint_off UNOPTFLAT */ /* verilator lint_off UNOPTFLAT */
module uartPC16550D( module uartPC16550D(
// Processor Interface // Processor Interface
input logic PCLK, PRESETn, // UART clock and active low reset input logic PCLK, PRESETn, // UART clock and active low reset
input logic [2:0] A, // address input (8 registers) input logic [2:0] A, // address input (8 registers)
input logic [7:0] Din, // 8-bit WriteData input logic [7:0] Din, // 8-bit WriteData
output logic [7:0] Dout, // 8-bit ReadData output logic [7:0] Dout, // 8-bit ReadData
input logic MEMRb, MEMWb, // Active low memory read/write input logic MEMRb, MEMWb, // Active low memory read/write
output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines
// Clocks // Clocks
output logic BAUDOUTb, // active low baud clock output logic BAUDOUTb, // active low baud clock
input logic RCLK, // usually BAUDOUTb tied to RCLK externally input logic RCLK, // usually BAUDOUTb tied to RCLK externally
// E1A Driver // E1A Driver
input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs
output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs
); );
// transmit and receive states // transmit and receive states
@ -62,63 +62,63 @@ module uartPC16550D(
logic [4:0] MCR; logic [4:0] MCR;
// Syncrhonized and delayed UART signals // Syncrhonized and delayed UART signals
logic SINd, DSRbd, DCDbd, CTSbd, RIbd; logic SINd, DSRbd, DCDbd, CTSbd, RIbd;
logic SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync; logic SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync;
logic DSRb2, DCDb2, CTSb2, RIb2; logic DSRb2, DCDb2, CTSb2, RIb2;
logic SOUTbit; logic SOUTbit;
// Control signals // Control signals
logic loop; // loopback mode logic loop; // loopback mode
logic DLAB; // Divisor Latch Access Bit (LCR bit 7) logic DLAB; // Divisor Latch Access Bit (LCR bit 7)
// Baud and rx/tx timing // Baud and rx/tx timing
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
logic [16+`UART_PRESCALE-1:0] baudcount; logic [16+`UART_PRESCALE-1:0] baudcount;
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16 logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
logic [3:0] rxbitsreceived, txbitssent; logic [3:0] rxbitsreceived, txbitssent;
statetype rxstate, txstate; statetype rxstate, txstate;
// shift registrs and FIFOs // shift registrs and FIFOs
logic [9:0] rxshiftreg; logic [9:0] rxshiftreg;
logic [10:0] rxfifo[15:0]; logic [10:0] rxfifo[15:0];
logic [7:0] txfifo[15:0]; logic [7:0] txfifo[15:0];
logic [4:0] rxfifotailunwrapped; logic [4:0] rxfifotailunwrapped;
logic [3:0] rxfifohead, rxfifotail, txfifohead, txfifotail, rxfifotriggerlevel; logic [3:0] rxfifohead, rxfifotail, txfifohead, txfifotail, rxfifotriggerlevel;
logic [3:0] rxfifoentries, txfifoentries; logic [3:0] rxfifoentries, txfifoentries;
logic [3:0] rxbitsexpected, txbitsexpected; logic [3:0] rxbitsexpected, txbitsexpected;
// receive data // receive data
logic [10:0] RXBR; logic [10:0] RXBR;
logic [9:0] rxtimeoutcnt; logic [9:0] rxtimeoutcnt;
logic rxcentered; logic rxcentered;
logic rxparity, rxparitybit, rxstopbit; logic rxparity, rxparitybit, rxstopbit;
logic rxparityerr, rxoverrunerr, rxframingerr, rxbreak, rxfifohaserr; logic rxparityerr, rxoverrunerr, rxframingerr, rxbreak, rxfifohaserr;
logic rxdataready; logic rxdataready;
logic rxfifoempty, rxfifotriggered, rxfifotimeout; logic rxfifoempty, rxfifotriggered, rxfifotimeout;
logic rxfifodmaready; logic rxfifodmaready;
logic [8:0] rxdata9; logic [8:0] rxdata9;
logic [7:0] rxdata; logic [7:0] rxdata;
logic [15:0] RXerrbit, rxfullbit; logic [15:0] RXerrbit, rxfullbit;
logic [31:0] rxfullbitunwrapped; logic [31:0] rxfullbitunwrapped;
// transmit data // transmit data
logic [7:0] TXHR, nexttxdata; logic [7:0] TXHR, nexttxdata;
logic [11:0] txdata, txsr; logic [11:0] txdata, txsr;
logic txnextbit, txhrfull, txsrfull; logic txnextbit, txhrfull, txsrfull;
logic txparity; logic txparity;
logic txfifoempty, txfifofull, txfifodmaready; logic txfifoempty, txfifofull, txfifodmaready;
// control signals // control signals
logic fifoenabled, fifodmamodesel, evenparitysel; logic fifoenabled, fifodmamodesel, evenparitysel;
// interrupts // interrupts
logic RXerr, RXerrIP, squashRXerrIP, prevSquashRXerrIP, setSquashRXerrIP, resetSquashRXerrIP; logic RXerr, RXerrIP, squashRXerrIP, prevSquashRXerrIP, setSquashRXerrIP, resetSquashRXerrIP;
logic THRE, THRE_IP, squashTHRE_IP, prevSquashTHRE_IP, setSquashTHRE_IP, resetSquashTHRE_IP; logic THRE, THRE_IP, squashTHRE_IP, prevSquashTHRE_IP, setSquashTHRE_IP, resetSquashTHRE_IP;
logic rxdataavailintr, modemstatusintr, intrpending; logic rxdataavailintr, modemstatusintr, intrpending;
logic [2:0] intrID; logic [2:0] intrID;
logic baudpulseComb; logic baudpulseComb;
logic HeadPointerLastMove; logic HeadPointerLastMove;
/////////////////////////////////////////// ///////////////////////////////////////////
// Input synchronization: 2-stage synchronizer // Input synchronization: 2-stage synchronizer
@ -126,7 +126,7 @@ module uartPC16550D(
always_ff @(posedge PCLK) begin always_ff @(posedge PCLK) begin
{SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb}; {SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb};
{SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} : {SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} :
{SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing {SINd, DSRbd, DCDbd, CTSbd, RIbd}; // syncrhonized signals, handle loopback testing
{DSRb2, DCDb2, CTSb2, RIb2} <= #1 {DSRbsync, DCDbsync, CTSbsync, RIbsync}; // for detecting state changes {DSRb2, DCDb2, CTSb2, RIb2} <= #1 {DSRbsync, DCDbsync, CTSbsync, RIbsync}; // for detecting state changes
end end
@ -141,8 +141,8 @@ module uartPC16550D(
MCR <= #1 5'b0; MCR <= #1 5'b0;
LSR <= #1 8'b01100000; LSR <= #1 8'b01100000;
MSR <= #1 4'b0; MSR <= #1 4'b0;
DLL <= #1 8'd1; // this cannot be zero with DLM also zer0. DLL <= #1 8'd1; // this cannot be zero with DLM also zer0.
DLM <= #1 8'b0; DLM <= #1 8'b0;
SCR <= #1 8'b0; // not strictly necessary to reset SCR <= #1 8'b0; // not strictly necessary to reset
end else begin end else begin
if (~MEMWb) begin if (~MEMWb) begin
@ -290,7 +290,7 @@ module uartPC16550D(
assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time
// receive FIFO and register // receive FIFO and register
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK)
if (~PRESETn) begin if (~PRESETn) begin
rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; RXBR <= #1 0; rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; RXBR <= #1 0;
end else begin end else begin
@ -367,7 +367,7 @@ module uartPC16550D(
end end
/////////////////////////////////////////// ///////////////////////////////////////////
// transmit timing and control // transmit timing and control
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin if (~PRESETn) begin
@ -455,20 +455,20 @@ module uartPC16550D(
end end
always_ff @(posedge PCLK, negedge PRESETn) begin always_ff @(posedge PCLK, negedge PRESETn) begin
// special condition to check if the fifo is empty or full. Because the head // special condition to check if the fifo is empty or full. Because the head
// pointer indicates where the next write goes and not the location of the // pointer indicates where the next write goes and not the location of the
// current head, the head and tail pointer being equal imply two different // current head, the head and tail pointer being equal imply two different
// things. First it could mean the fifo is empty and second it could mean // things. First it could mean the fifo is empty and second it could mean
// the fifo is full. To differenciate we need to know which pointer moved // the fifo is full. To differenciate we need to know which pointer moved
// to cause them to be equal. If the head pointer moved then it is full. // to cause them to be equal. If the head pointer moved then it is full.
// If the tail pointer moved then it is empty. it resets to empty so // If the tail pointer moved then it is empty. it resets to empty so
// if reset with the tail pointer indicating the last update. // if reset with the tail pointer indicating the last update.
if(~PRESETn) if(~PRESETn)
HeadPointerLastMove <= 1'b0; HeadPointerLastMove <= 1'b0;
else if(fifoenabled & ~MEMWb & A == 3'b000 & ~DLAB) else if(fifoenabled & ~MEMWb & A == 3'b000 & ~DLAB)
HeadPointerLastMove <= 1'b1; HeadPointerLastMove <= 1'b1;
else if(fifoenabled & ~txfifoempty & ~txsrfull & txstate == UART_IDLE) else if(fifoenabled & ~txfifoempty & ~txsrfull & txstate == UART_IDLE)
HeadPointerLastMove <= 1'b0; HeadPointerLastMove <= 1'b0;
end end
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove; assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
@ -477,7 +477,7 @@ module uartPC16550D(
(txfifohead + 16 - txfifotail); (txfifohead + 16 - txfifotail);
// verilator lint_on WIDTH // verilator lint_on WIDTH
//assign txfifofull = (txfifoentries == 4'b1111); //assign txfifofull = (txfifoentries == 4'b1111);
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove; assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
// transmit buffer ready bit // transmit buffer ready bit
always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1) always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)

View File

@ -31,58 +31,58 @@
module uncore ( module uncore (
// AHB Bus Interface // AHB Bus Interface
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic TIMECLK, input logic TIMECLK,
input logic [`PA_BITS-1:0] HADDR, input logic [`PA_BITS-1:0] HADDR,
input logic [`AHBW-1:0] HWDATA, input logic [`AHBW-1:0] HWDATA,
input logic [`XLEN/8-1:0] HWSTRB, input logic [`XLEN/8-1:0] HWSTRB,
input logic HWRITE, input logic HWRITE,
input logic [2:0] HSIZE, input logic [2:0] HSIZE,
input logic [2:0] HBURST, input logic [2:0] HBURST,
input logic [3:0] HPROT, input logic [3:0] HPROT,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic HMASTLOCK, input logic HMASTLOCK,
input logic [`AHBW-1:0] HRDATAEXT, input logic [`AHBW-1:0] HRDATAEXT,
input logic HREADYEXT, HRESPEXT, input logic HREADYEXT, HRESPEXT,
output logic [`AHBW-1:0] HRDATA, output logic [`AHBW-1:0] HRDATA,
output logic HREADY, HRESP, output logic HREADY, HRESP,
output logic HSELEXT, output logic HSELEXT,
// peripheral pins // peripheral pins
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
output logic MExtInt, SExtInt, // External interrupts from PLIC output logic MExtInt, SExtInt, // External interrupts from PLIC
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
input logic [31:0] GPIOPinsIn, // GPIO pin input value input logic [31:0] GPIOIN, // GPIO pin input value
output logic [31:0] GPIOPinsOut, GPIOPinsEn, // GPIO pin output value and enable output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable
input logic UARTSin, // UART serial input input logic UARTSin, // UART serial input
output logic UARTSout, // UART serial output output logic UARTSout, // UART serial output
output logic SDCCmdOut, // SD Card command output output logic SDCCmdOut, // SD Card command output
output logic SDCCmdOE, // SD Card command output enable output logic SDCCmdOE, // SD Card command output enable
input logic SDCCmdIn, // SD Card command input input logic SDCCmdIn, // SD Card command input
input logic [3:0] SDCDatIn, // SD Card data input input logic [3:0] SDCDatIn, // SD Card data input
output logic SDCCLK // SD Card clock output logic SDCCLK // SD Card clock
); );
logic [`XLEN-1:0] HREADRam, HREADSDC; logic [`XLEN-1:0] HREADRam, HREADSDC;
logic [10:0] HSELRegions; logic [10:0] HSELRegions;
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC; logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD; logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
logic HRESPRam, HRESPSDC; logic HRESPRam, HRESPSDC;
logic HREADYRam, HRESPSDCD; logic HREADYRam, HRESPSDCD;
logic [`XLEN-1:0] HREADBootRom; logic [`XLEN-1:0] HREADBootRom;
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC; logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
logic HSELNoneD; logic HSELNoneD;
logic UARTIntr,GPIOIntr; logic UARTIntr,GPIOIntr;
logic SDCIntM; logic SDCIntM;
logic PCLK, PRESETn, PWRITE, PENABLE; logic PCLK, PRESETn, PWRITE, PENABLE;
logic [3:0] PSEL, PREADY; logic [3:0] PSEL, PREADY;
logic [31:0] PADDR; logic [31:0] PADDR;
logic [`XLEN-1:0] PWDATA; logic [`XLEN-1:0] PWDATA;
logic [`XLEN/8-1:0] PSTRB; logic [`XLEN/8-1:0] PSTRB;
logic [3:0][`XLEN-1:0] PRDATA; logic [3:0][`XLEN-1:0] PRDATA;
logic [`XLEN-1:0] HREADBRIDGE; logic [`XLEN-1:0] HREADBRIDGE;
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED; logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
// Use a trimmed down portion of the PMA checker - only the address decoders // Use a trimmed down portion of the PMA checker - only the address decoders
@ -133,9 +133,9 @@ module uncore (
gpio_apb gpio( gpio_apb gpio(
.PCLK, .PRESETn, .PSEL(PSEL[0]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE, .PCLK, .PRESETn, .PSEL(PSEL[0]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
.PRDATA(PRDATA[0]), .PREADY(PREADY[0]), .PRDATA(PRDATA[0]), .PREADY(PREADY[0]),
.iof0(), .iof1(), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .GPIOIntr); .iof0(), .iof1(), .GPIOIN, .GPIOOUT, .GPIOEN, .GPIOIntr);
end else begin : gpio end else begin : gpio
assign GPIOPinsOut = 0; assign GPIOPinsEn = 0; assign GPIOIntr = 0; assign GPIOOUT = 0; assign GPIOEN = 0; assign GPIOIntr = 0;
end end
if (`UART_SUPPORTED == 1) begin : uart if (`UART_SUPPORTED == 1) begin : uart
uart_apb uart( uart_apb uart(
@ -163,19 +163,19 @@ module uncore (
// AHB Read Multiplexer // AHB Read Multiplexer
assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) | assign HRDATA = ({`XLEN{HSELRamD}} & HREADRam) |
({`XLEN{HSELEXTD}} & HRDATAEXT) | ({`XLEN{HSELEXTD}} & HRDATAEXT) |
({`XLEN{HSELBRIDGED}} & HREADBRIDGE) | ({`XLEN{HSELBRIDGED}} & HREADBRIDGE) |
({`XLEN{HSELBootRomD}} & HREADBootRom) | ({`XLEN{HSELBootRomD}} & HREADBootRom) |
({`XLEN{HSELSDCD}} & HREADSDC); ({`XLEN{HSELSDCD}} & HREADSDC);
assign HRESP = HSELRamD & HRESPRam | assign HRESP = HSELRamD & HRESPRam |
HSELEXTD & HRESPEXT | HSELEXTD & HRESPEXT |
HSELBRIDGE & HRESPBRIDGE | HSELBRIDGE & HRESPBRIDGE |
HSELBootRomD & HRESPBootRom | HSELBootRomD & HRESPBootRom |
HSELSDC & HRESPSDC; HSELSDC & HRESPSDC;
assign HREADY = HSELRamD & HREADYRam | assign HREADY = HSELRamD & HREADYRam |
HSELEXTD & HREADYEXT | HSELEXTD & HREADYEXT |
HSELBRIDGED & HREADYBRIDGE | HSELBRIDGED & HREADYBRIDGE |
HSELBootRomD & HREADYBootRom | HSELBootRomD & HREADYBootRom |
HSELSDCD & HREADYSDC | HSELSDCD & HREADYSDC |

View File

@ -35,12 +35,12 @@ module wallypipelinedcore (
input logic MTimerInt, MExtInt, SExtInt, MSwInt, input logic MTimerInt, MExtInt, SExtInt, MSwInt,
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,
input logic HREADY, HRESP, input logic HREADY, HRESP,
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
output logic [`PA_BITS-1:0] HADDR, output logic [`PA_BITS-1:0] HADDR,
output logic [`AHBW-1:0] HWDATA, output logic [`AHBW-1:0] HWDATA,
output logic [`XLEN/8-1:0] HWSTRB, output logic [`XLEN/8-1:0] HWSTRB,
output logic HWRITE, output logic HWRITE,
output logic [2:0] HSIZE, output logic [2:0] HSIZE,
output logic [2:0] HBURST, output logic [2:0] HBURST,
@ -58,17 +58,17 @@ module wallypipelinedcore (
logic IntDivE, W64E; logic IntDivE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM; logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicM; logic [1:0] AtomicM;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
logic [`XLEN-1:0] SrcAM; logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E; logic [2:0] Funct3E;
logic [31:0] InstrD; logic [31:0] InstrD;
logic [31:0] InstrM, InstrOrigM; logic [31:0] InstrM, InstrOrigM;
logic [`XLEN-1:0] PCSpillF, PCE, PCLinkE; logic [`XLEN-1:0] PCSpillF, PCE, PCLinkE;
logic [`XLEN-1:0] PCM; logic [`XLEN-1:0] PCM;
logic [`XLEN-1:0] CSRReadValW, MDUResultW; logic [`XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF; logic [`XLEN-1:0] UnalignedPCNextF, PC2NextF;
logic [1:0] MemRWM; logic [1:0] MemRWM;
logic InstrValidD, InstrValidE, InstrValidM; logic InstrValidD, InstrValidE, InstrValidM;
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
logic IllegalBaseInstrD, IllegalFPUInstrD, IllegalIEUFPUInstrD; logic IllegalBaseInstrD, IllegalFPUInstrD, IllegalIEUFPUInstrD;
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM; logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
@ -86,8 +86,8 @@ module wallypipelinedcore (
logic [4:0] RdE, RdM, RdW; logic [4:0] RdE, RdM, RdW;
logic FPUStallD; logic FPUStallD;
logic FWriteIntE; logic FWriteIntE;
logic [`FLEN-1:0] FWriteDataM; logic [`FLEN-1:0] FWriteDataM;
logic [`XLEN-1:0] FIntResM; logic [`XLEN-1:0] FIntResM;
logic [`XLEN-1:0] FCvtIntResW; logic [`XLEN-1:0] FCvtIntResW;
logic FCvtIntW; logic FCvtIntW;
logic FDivBusyE; logic FDivBusyE;
@ -95,22 +95,22 @@ module wallypipelinedcore (
logic FCvtIntStallD; logic FCvtIntStallD;
logic FpLoadStoreM; logic FpLoadStoreM;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
logic [`XLEN-1:0] FIntDivResultW; logic [`XLEN-1:0] FIntDivResultW;
// memory management unit signals // memory management unit signals
logic ITLBWriteF; logic ITLBWriteF;
logic ITLBMissF; logic ITLBMissF;
logic [`XLEN-1:0] SATP_REGW; logic [`XLEN-1:0] SATP_REGW;
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
logic [1:0] STATUS_MPP, STATUS_FS; logic [1:0] STATUS_MPP, STATUS_FS;
logic [1:0] PrivilegeModeW; logic [1:0] PrivilegeModeW;
logic [`XLEN-1:0] PTE; logic [`XLEN-1:0] PTE;
logic [1:0] PageType; logic [1:0] PageType;
logic sfencevmaM, WFIStallM; logic sfencevmaM, WFIStallM;
logic SelHPTW; logic SelHPTW;
// PMA checker signals // PMA checker signals
var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0]; var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0];
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0]; var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
// IMem stalls // IMem stalls
@ -119,14 +119,14 @@ module wallypipelinedcore (
// cpu lsu interface // cpu lsu interface
logic [2:0] Funct3M; logic [2:0] Funct3M;
logic [`XLEN-1:0] IEUAdrE; logic [`XLEN-1:0] IEUAdrE;
logic [`XLEN-1:0] WriteDataM; logic [`XLEN-1:0] WriteDataM;
logic [`XLEN-1:0] IEUAdrM; logic [`XLEN-1:0] IEUAdrM;
logic [`LLEN-1:0] ReadDataW; logic [`LLEN-1:0] ReadDataW;
logic CommittedM; logic CommittedM;
// AHB ifu interface // AHB ifu interface
logic [`PA_BITS-1:0] IFUHADDR; logic [`PA_BITS-1:0] IFUHADDR;
logic [2:0] IFUHBURST; logic [2:0] IFUHBURST;
logic [1:0] IFUHTRANS; logic [1:0] IFUHTRANS;
logic [2:0] IFUHSIZE; logic [2:0] IFUHSIZE;
@ -134,9 +134,9 @@ module wallypipelinedcore (
logic IFUHREADY; logic IFUHREADY;
// AHB LSU interface // AHB LSU interface
logic [`PA_BITS-1:0] LSUHADDR; logic [`PA_BITS-1:0] LSUHADDR;
logic [`XLEN-1:0] LSUHWDATA; logic [`XLEN-1:0] LSUHWDATA;
logic [`XLEN/8-1:0] LSUHWSTRB; logic [`XLEN/8-1:0] LSUHWSTRB;
logic LSUHWRITE; logic LSUHWRITE;
logic LSUHREADY; logic LSUHREADY;
@ -160,8 +160,8 @@ module wallypipelinedcore (
logic BigEndianM; logic BigEndianM;
logic FCvtIntE; logic FCvtIntE;
logic CommittedF; logic CommittedF;
logic BranchD, BranchE, JumpD, JumpE; logic BranchD, BranchE, JumpD, JumpE;
logic DCacheStallM, ICacheStallF; logic DCacheStallM, ICacheStallF;
// instruction fetch unit: PC, branch prediction, instruction cache // instruction fetch unit: PC, branch prediction, instruction cache
ifu ifu(.clk, .reset, ifu ifu(.clk, .reset,
@ -247,20 +247,10 @@ module wallypipelinedcore (
ebu ebu(// IFU connections ebu ebu(// IFU connections
.clk, .reset, .clk, .reset,
// IFU interface // IFU interface
.IFUHADDR, .IFUHADDR, .IFUHBURST, .IFUHTRANS, .IFUHREADY, .IFUHSIZE,
.IFUHBURST,
.IFUHTRANS,
.IFUHREADY,
.IFUHSIZE,
// LSU interface // LSU interface
.LSUHADDR, .LSUHADDR, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE, .LSUHBURST,
.LSUHWDATA, .LSUHTRANS, .LSUHWRITE, .LSUHREADY,
.LSUHWSTRB,
.LSUHSIZE,
.LSUHBURST,
.LSUHTRANS,
.LSUHWRITE,
.LSUHREADY,
// BUS interface // BUS interface
.HREADY, .HRESP, .HCLK, .HRESETn, .HREADY, .HRESP, .HCLK, .HRESETn,
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST,

View File

@ -30,43 +30,43 @@
`include "wally-config.vh" `include "wally-config.vh"
module wallypipelinedsoc ( module wallypipelinedsoc (
input logic clk, input logic clk,
input logic reset_ext, // external asynchronous reset pin input logic reset_ext, // external asynchronous reset pin
output logic reset, // reset synchronized to clk to prevent races on release output logic reset, // reset synchronized to clk to prevent races on release
// AHB Interface // AHB Interface
input logic [`AHBW-1:0] HRDATAEXT, input logic [`AHBW-1:0] HRDATAEXT,
input logic HREADYEXT, HRESPEXT, input logic HREADYEXT, HRESPEXT,
output logic HSELEXT, output logic HSELEXT,
// outputs to external memory, shared with uncore memory // outputs to external memory, shared with uncore memory
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
output logic [`PA_BITS-1:0] HADDR, output logic [`PA_BITS-1:0] HADDR,
output logic [`AHBW-1:0] HWDATA, output logic [`AHBW-1:0] HWDATA,
output logic [`XLEN/8-1:0] HWSTRB, output logic [`XLEN/8-1:0] HWSTRB,
output logic HWRITE, output logic HWRITE,
output logic [2:0] HSIZE, output logic [2:0] HSIZE,
output logic [2:0] HBURST, output logic [2:0] HBURST,
output logic [3:0] HPROT, output logic [3:0] HPROT,
output logic [1:0] HTRANS, output logic [1:0] HTRANS,
output logic HMASTLOCK, output logic HMASTLOCK,
output logic HREADY, output logic HREADY,
// I/O Interface // I/O Interface
input logic TIMECLK, // optional for CLINT MTIME counter input logic TIMECLK, // optional for CLINT MTIME counter
input logic [31:0] GPIOPinsIn, // inputs from GPIO input logic [31:0] GPIOIN, // inputs from GPIO
output logic [31:0] GPIOPinsOut, // output values for GPIO output logic [31:0] GPIOOUT, // output values for GPIO
output logic [31:0] GPIOPinsEn, // output enables for GPIO output logic [31:0] GPIOEN, // output enables for GPIO
input logic UARTSin, // UART serial data input input logic UARTSin, // UART serial data input
output logic UARTSout, // UART serial data output output logic UARTSout, // UART serial data output
input logic SDCCmdIn, // SDC Command input input logic SDCCmdIn, // SDC Command input
output logic SDCCmdOut, // SDC Command output output logic SDCCmdOut, // SDC Command output
output logic SDCCmdOE, // SDC Command output enable output logic SDCCmdOE, // SDC Command output enable
input logic [3:0] SDCDatIn, // SDC data input input logic [3:0] SDCDatIn, // SDC data input
output logic SDCCLK // SDC clock output logic SDCCLK // SDC clock
); );
// Uncore signals // Uncore signals
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
logic HRESP; // response from AHB logic HRESP; // response from AHB
logic MTimerInt, MSwInt; // timer and software interrupts from CLINT logic MTimerInt, MSwInt;// timer and software interrupts from CLINT
logic [63:0] MTIME_CLINT; // from CLINT to CSRs logic [63:0] MTIME_CLINT; // from CLINT to CSRs
logic MExtInt,SExtInt; // from PLIC logic MExtInt,SExtInt; // from PLIC
@ -85,9 +85,9 @@ module wallypipelinedsoc (
uncore uncore(.HCLK, .HRESETn, .TIMECLK, uncore uncore(.HCLK, .HRESETn, .TIMECLK,
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
.HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT, .HREADYEXT, .HRESPEXT, .HRDATA, .HREADY, .HRESP, .HSELEXT,
.MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .UARTSin, .MTimerInt, .MSwInt, .MExtInt, .SExtInt, .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin,
.UARTSout, .MTIME_CLINT, .UARTSout, .MTIME_CLINT,
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK); .SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK);
end end
endmodule endmodule

View File

@ -90,6 +90,7 @@ module wallyTracer(rvviTrace rvvi);
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL; assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
logic valid; logic valid;
int csrid;
always_comb begin always_comb begin
// Since we are detected the CSR change by comparing the old value we need to // Since we are detected the CSR change by comparing the old value we need to
@ -116,7 +117,6 @@ module wallyTracer(rvviTrace rvvi);
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+7] << 56; pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+7] << 56;
csrid = 12'h3A0 + i4; csrid = 12'h3A0 + i4;
//if (CSRArray[csrid] != pmp) $display("Info: %m pmpcfg%0d [%03X] %016X -> %016X", i4, csrid, CSRArray[csrid], pmp);
CSRArray[csrid] = pmp; CSRArray[csrid] = pmp;
end end
@ -125,7 +125,6 @@ module wallyTracer(rvviTrace rvvi);
pmp = testbench.dut.core.priv.priv.csr.csrm.PMPADDR_ARRAY_REGW[i]; pmp = testbench.dut.core.priv.priv.csr.csrm.PMPADDR_ARRAY_REGW[i];
csrid = 12'h3B0 + i; csrid = 12'h3B0 + i;
//if (CSRArray[csrid] != pmp) $display("Info: %m Change pmpaddr%0d [%03X] %016X -> %016X", i, csrid, CSRArray[csrid], pmp);
CSRArray[csrid] = pmp; CSRArray[csrid] = pmp;
end end
@ -167,7 +166,17 @@ module wallyTracer(rvviTrace rvvi);
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW; CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW;
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
end else begin // hold the old value if the pipeline is stalled. end else begin // hold the old value if the pipeline is stalled.
// PMP CFG 3A0 to 3AF
for(csrid='h3A0; csrid<='h3AF; csrid++)
CSRArray[csrid] = CSRArrayOld[csrid];
// PMP ADDR 3B0 to 3EF
for(csrid='h3B0; csrid<='h3EF; csrid++)
CSRArray[csrid] = CSRArrayOld[csrid];
CSRArray[12'h300] = CSRArrayOld[12'h300]; CSRArray[12'h300] = CSRArrayOld[12'h300];
CSRArray[12'h310] = CSRArrayOld[12'h310]; CSRArray[12'h310] = CSRArrayOld[12'h310];
CSRArray[12'h305] = CSRArrayOld[12'h305]; CSRArray[12'h305] = CSRArrayOld[12'h305];
@ -209,7 +218,7 @@ module wallyTracer(rvviTrace rvvi);
end end
end end
genvar index; genvar index;
assign rf[0] = '0; assign rf[0] = '0;
for(index = 1; index < NUMREGS; index += 1) for(index = 1; index < NUMREGS; index += 1)
assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index]; assign rf[index] = testbench.dut.core.ieu.dp.regf.rf[index];
@ -286,26 +295,176 @@ module wallyTracer(rvviTrace rvvi);
// record previous csr value. // record previous csr value.
integer index4; integer index4;
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
for (index4 = 0; index4 < `NUM_CSRS; index4 += 1) begin CSRArrayOld[12'h300] = CSRArray[12'h300];
// IMPERAS CSRArrayOld[12'h310] = CSRArray[12'h310];
//CSR_W[index4] = (CSRArrayOld[index4] != CSRArray[index4]) ? 1 : 0; CSRArrayOld[12'h305] = CSRArray[12'h305];
CSRArrayOld[index4] = CSRArray[index4]; CSRArrayOld[12'h341] = CSRArray[12'h341];
end CSRArrayOld[12'h306] = CSRArray[12'h306];
CSRArrayOld[12'h320] = CSRArray[12'h320];
CSRArrayOld[12'h302] = CSRArray[12'h302];
CSRArrayOld[12'h303] = CSRArray[12'h303];
CSRArrayOld[12'h344] = CSRArray[12'h344];
CSRArrayOld[12'h304] = CSRArray[12'h304];
CSRArrayOld[12'h301] = CSRArray[12'h301];
CSRArrayOld[12'hF14] = CSRArray[12'hF14];
CSRArrayOld[12'h340] = CSRArray[12'h340];
CSRArrayOld[12'h342] = CSRArray[12'h342];
CSRArrayOld[12'h343] = CSRArray[12'h343];
CSRArrayOld[12'hF11] = CSRArray[12'hF11];
CSRArrayOld[12'hF12] = CSRArray[12'hF12];
CSRArrayOld[12'hF13] = CSRArray[12'hF13];
CSRArrayOld[12'hF15] = CSRArray[12'hF15];
CSRArrayOld[12'h34A] = CSRArray[12'h34A];
// MCYCLE and MINSTRET
CSRArrayOld[12'hB00] = CSRArray[12'hB00];
CSRArrayOld[12'hB02] = CSRArray[12'hB02];
// supervisor CSRs
CSRArrayOld[12'h100] = CSRArray[12'h100];
CSRArrayOld[12'h104] = CSRArray[12'h104];
CSRArrayOld[12'h105] = CSRArray[12'h105];
CSRArrayOld[12'h141] = CSRArray[12'h141];
CSRArrayOld[12'h106] = CSRArray[12'h106];
CSRArrayOld[12'h180] = CSRArray[12'h180];
CSRArrayOld[12'h140] = CSRArray[12'h140];
CSRArrayOld[12'h143] = CSRArray[12'h143];
CSRArrayOld[12'h142] = CSRArray[12'h142];
CSRArrayOld[12'h144] = CSRArray[12'h144];
// user CSRs
CSRArrayOld[12'h001] = CSRArray[12'h001];
CSRArrayOld[12'h002] = CSRArray[12'h002];
CSRArrayOld[12'h003] = CSRArray[12'h003];
// PMP CFG 3A0 to 3AF
for(index4='h3A0; index4<='h3AF; index4++)
CSRArrayOld[index4] = CSRArray[index4];
// PMP ADDR 3B0 to 3EF
for(index4='h3B0; index4<='h3EF; index4++)
CSRArrayOld[index4] = CSRArray[index4];
end end
// check for csr value change. // check for csr value change.
genvar index5; assign #2 CSR_W[12'h300] = (CSRArrayOld[12'h300] != CSRArray[12'h300]) ? 1 : 0;
for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin assign #2 CSR_W[12'h310] = (CSRArrayOld[12'h310] != CSRArray[12'h310]) ? 1 : 0;
// CSR_W should only indicate the change when the Writeback stage is not stalled and valid. assign #2 CSR_W[12'h305] = (CSRArrayOld[12'h305] != CSRArray[12'h305]) ? 1 : 0;
assign #2 CSR_W[index5] = (CSRArrayOld[index5] != CSRArray[index5]) ? 1 : 0; assign #2 CSR_W[12'h341] = (CSRArrayOld[12'h341] != CSRArray[12'h341]) ? 1 : 0;
assign rvvi.csr_wb[0][0][index5] = CSR_W[index5]; assign #2 CSR_W[12'h306] = (CSRArrayOld[12'h306] != CSRArray[12'h306]) ? 1 : 0;
assign rvvi.csr[0][0][index5] = CSRArray[index5]; assign #2 CSR_W[12'h320] = (CSRArrayOld[12'h320] != CSRArray[12'h320]) ? 1 : 0;
assign #2 CSR_W[12'h302] = (CSRArrayOld[12'h302] != CSRArray[12'h302]) ? 1 : 0;
assign #2 CSR_W[12'h303] = (CSRArrayOld[12'h303] != CSRArray[12'h303]) ? 1 : 0;
assign #2 CSR_W[12'h344] = (CSRArrayOld[12'h344] != CSRArray[12'h344]) ? 1 : 0;
assign #2 CSR_W[12'h304] = (CSRArrayOld[12'h304] != CSRArray[12'h304]) ? 1 : 0;
assign #2 CSR_W[12'h301] = (CSRArrayOld[12'h301] != CSRArray[12'h301]) ? 1 : 0;
assign #2 CSR_W[12'hF14] = (CSRArrayOld[12'hF14] != CSRArray[12'hF14]) ? 1 : 0;
assign #2 CSR_W[12'h340] = (CSRArrayOld[12'h340] != CSRArray[12'h340]) ? 1 : 0;
assign #2 CSR_W[12'h342] = (CSRArrayOld[12'h342] != CSRArray[12'h342]) ? 1 : 0;
assign #2 CSR_W[12'h343] = (CSRArrayOld[12'h343] != CSRArray[12'h343]) ? 1 : 0;
assign #2 CSR_W[12'hF11] = (CSRArrayOld[12'hF11] != CSRArray[12'hF11]) ? 1 : 0;
assign #2 CSR_W[12'hF12] = (CSRArrayOld[12'hF12] != CSRArray[12'hF12]) ? 1 : 0;
assign #2 CSR_W[12'hF13] = (CSRArrayOld[12'hF13] != CSRArray[12'hF13]) ? 1 : 0;
assign #2 CSR_W[12'hF15] = (CSRArrayOld[12'hF15] != CSRArray[12'hF15]) ? 1 : 0;
assign #2 CSR_W[12'h34A] = (CSRArrayOld[12'h34A] != CSRArray[12'h34A]) ? 1 : 0;
assign #2 CSR_W[12'hB00] = (CSRArrayOld[12'hB00] != CSRArray[12'hB00]) ? 1 : 0;
assign #2 CSR_W[12'hB02] = (CSRArrayOld[12'hB02] != CSRArray[12'hB02]) ? 1 : 0;
assign #2 CSR_W[12'h100] = (CSRArrayOld[12'h100] != CSRArray[12'h100]) ? 1 : 0;
assign #2 CSR_W[12'h104] = (CSRArrayOld[12'h104] != CSRArray[12'h104]) ? 1 : 0;
assign #2 CSR_W[12'h105] = (CSRArrayOld[12'h105] != CSRArray[12'h105]) ? 1 : 0;
assign #2 CSR_W[12'h141] = (CSRArrayOld[12'h141] != CSRArray[12'h141]) ? 1 : 0;
assign #2 CSR_W[12'h106] = (CSRArrayOld[12'h106] != CSRArray[12'h106]) ? 1 : 0;
assign #2 CSR_W[12'h180] = (CSRArrayOld[12'h180] != CSRArray[12'h180]) ? 1 : 0;
assign #2 CSR_W[12'h140] = (CSRArrayOld[12'h140] != CSRArray[12'h140]) ? 1 : 0;
assign #2 CSR_W[12'h143] = (CSRArrayOld[12'h143] != CSRArray[12'h143]) ? 1 : 0;
assign #2 CSR_W[12'h142] = (CSRArrayOld[12'h142] != CSRArray[12'h142]) ? 1 : 0;
assign #2 CSR_W[12'h144] = (CSRArrayOld[12'h144] != CSRArray[12'h144]) ? 1 : 0;
assign #2 CSR_W[12'h001] = (CSRArrayOld[12'h001] != CSRArray[12'h001]) ? 1 : 0;
assign #2 CSR_W[12'h002] = (CSRArrayOld[12'h002] != CSRArray[12'h002]) ? 1 : 0;
assign #2 CSR_W[12'h003] = (CSRArrayOld[12'h003] != CSRArray[12'h003]) ? 1 : 0;
assign rvvi.csr_wb[0][0][12'h300] = CSR_W[12'h300];
assign rvvi.csr_wb[0][0][12'h310] = CSR_W[12'h310];
assign rvvi.csr_wb[0][0][12'h305] = CSR_W[12'h305];
assign rvvi.csr_wb[0][0][12'h341] = CSR_W[12'h341];
assign rvvi.csr_wb[0][0][12'h306] = CSR_W[12'h306];
assign rvvi.csr_wb[0][0][12'h320] = CSR_W[12'h320];
assign rvvi.csr_wb[0][0][12'h302] = CSR_W[12'h302];
assign rvvi.csr_wb[0][0][12'h303] = CSR_W[12'h303];
assign rvvi.csr_wb[0][0][12'h344] = CSR_W[12'h344];
assign rvvi.csr_wb[0][0][12'h304] = CSR_W[12'h304];
assign rvvi.csr_wb[0][0][12'h301] = CSR_W[12'h301];
assign rvvi.csr_wb[0][0][12'hF14] = CSR_W[12'hF14];
assign rvvi.csr_wb[0][0][12'h340] = CSR_W[12'h340];
assign rvvi.csr_wb[0][0][12'h342] = CSR_W[12'h342];
assign rvvi.csr_wb[0][0][12'h343] = CSR_W[12'h343];
assign rvvi.csr_wb[0][0][12'hF11] = CSR_W[12'hF11];
assign rvvi.csr_wb[0][0][12'hF12] = CSR_W[12'hF12];
assign rvvi.csr_wb[0][0][12'hF13] = CSR_W[12'hF13];
assign rvvi.csr_wb[0][0][12'hF15] = CSR_W[12'hF15];
assign rvvi.csr_wb[0][0][12'h34A] = CSR_W[12'h34A];
assign rvvi.csr_wb[0][0][12'hB00] = CSR_W[12'hB00];
assign rvvi.csr_wb[0][0][12'hB02] = CSR_W[12'hB02];
assign rvvi.csr_wb[0][0][12'h100] = CSR_W[12'h100];
assign rvvi.csr_wb[0][0][12'h104] = CSR_W[12'h104];
assign rvvi.csr_wb[0][0][12'h105] = CSR_W[12'h105];
assign rvvi.csr_wb[0][0][12'h141] = CSR_W[12'h141];
assign rvvi.csr_wb[0][0][12'h106] = CSR_W[12'h106];
assign rvvi.csr_wb[0][0][12'h180] = CSR_W[12'h180];
assign rvvi.csr_wb[0][0][12'h140] = CSR_W[12'h140];
assign rvvi.csr_wb[0][0][12'h143] = CSR_W[12'h143];
assign rvvi.csr_wb[0][0][12'h142] = CSR_W[12'h142];
assign rvvi.csr_wb[0][0][12'h144] = CSR_W[12'h144];
assign rvvi.csr_wb[0][0][12'h001] = CSR_W[12'h001];
assign rvvi.csr_wb[0][0][12'h002] = CSR_W[12'h002];
assign rvvi.csr_wb[0][0][12'h003] = CSR_W[12'h003];
assign rvvi.csr[0][0][12'h300] = CSRArray[12'h300];
assign rvvi.csr[0][0][12'h310] = CSRArray[12'h310];
assign rvvi.csr[0][0][12'h305] = CSRArray[12'h305];
assign rvvi.csr[0][0][12'h341] = CSRArray[12'h341];
assign rvvi.csr[0][0][12'h306] = CSRArray[12'h306];
assign rvvi.csr[0][0][12'h320] = CSRArray[12'h320];
assign rvvi.csr[0][0][12'h302] = CSRArray[12'h302];
assign rvvi.csr[0][0][12'h303] = CSRArray[12'h303];
assign rvvi.csr[0][0][12'h344] = CSRArray[12'h344];
assign rvvi.csr[0][0][12'h304] = CSRArray[12'h304];
assign rvvi.csr[0][0][12'h301] = CSRArray[12'h301];
assign rvvi.csr[0][0][12'hF14] = CSRArray[12'hF14];
assign rvvi.csr[0][0][12'h340] = CSRArray[12'h340];
assign rvvi.csr[0][0][12'h342] = CSRArray[12'h342];
assign rvvi.csr[0][0][12'h343] = CSRArray[12'h343];
assign rvvi.csr[0][0][12'hF11] = CSRArray[12'hF11];
assign rvvi.csr[0][0][12'hF12] = CSRArray[12'hF12];
assign rvvi.csr[0][0][12'hF13] = CSRArray[12'hF13];
assign rvvi.csr[0][0][12'hF15] = CSRArray[12'hF15];
assign rvvi.csr[0][0][12'h34A] = CSRArray[12'h34A];
assign rvvi.csr[0][0][12'hB00] = CSRArray[12'hB00];
assign rvvi.csr[0][0][12'hB02] = CSRArray[12'hB02];
assign rvvi.csr[0][0][12'h100] = CSRArray[12'h100];
assign rvvi.csr[0][0][12'h104] = CSRArray[12'h104];
assign rvvi.csr[0][0][12'h105] = CSRArray[12'h105];
assign rvvi.csr[0][0][12'h141] = CSRArray[12'h141];
assign rvvi.csr[0][0][12'h106] = CSRArray[12'h106];
assign rvvi.csr[0][0][12'h180] = CSRArray[12'h180];
assign rvvi.csr[0][0][12'h140] = CSRArray[12'h140];
assign rvvi.csr[0][0][12'h143] = CSRArray[12'h143];
assign rvvi.csr[0][0][12'h142] = CSRArray[12'h142];
assign rvvi.csr[0][0][12'h144] = CSRArray[12'h144];
assign rvvi.csr[0][0][12'h001] = CSRArray[12'h001];
assign rvvi.csr[0][0][12'h002] = CSRArray[12'h002];
assign rvvi.csr[0][0][12'h003] = CSRArray[12'h003];
// PMP CFG 3A0 to 3AF
for(index='h3A0; index<='h3AF; index++) begin
assign #2 CSR_W[index] = (CSRArrayOld[index] != CSRArray[index]) ? 1 : 0;
assign rvvi.csr_wb[0][0][index] = CSR_W[index];
assign rvvi.csr[0][0][index] = CSRArray[index];
end end
// always @rvvi.clk $display("%t @rvvi.clk=%X", $time, rvvi.clk); // PMP ADDR 3B0 to 3EF
// always @rvvi.csr[0][0]['h300] $display("%t rvvi.csr[0][0]['h300]=%X", $time, rvvi.csr[0][0]['h300]); for(index='h3B0; index<='h3EF; index++) begin
// always @rvvi.csr_wb[0][0]['h300] $display("%t rvvi.csr_wb[0][0]['h300]=%X", $time, rvvi.csr_wb[0][0]['h300]); assign #2 CSR_W[index] = (CSRArrayOld[index] != CSRArray[index]) ? 1 : 0;
// always @rvvi.valid[0][0] $display("%t rvvi.valid[0][0]=%X", $time, rvvi.valid[0][0]); assign rvvi.csr_wb[0][0][index] = CSR_W[index];
assign rvvi.csr[0][0][index] = CSRArray[index];
end
// *** implementation only cancel? so sc does not clear? // *** implementation only cancel? so sc does not clear?
assign rvvi.lrsc_cancel[0][0] = '0; assign rvvi.lrsc_cancel[0][0] = '0;

View File

@ -702,7 +702,7 @@ module testbenchfp;
if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt
fcvt fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal), fcvt fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal),
.XZero(XZero), .XSubnorm(XSubnorm), .OpCtrl(OpCtrlVal), .IntZero, .XZero(XZero), .OpCtrl(OpCtrlVal), .IntZero,
.Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE)); .Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE));
end end

File diff suppressed because it is too large Load Diff

View File

@ -252,8 +252,8 @@ module testbench;
logic [3:0] HPROT; logic [3:0] HPROT;
logic [1:0] HTRANS; logic [1:0] HTRANS;
logic HMASTLOCK; logic HMASTLOCK;
logic [31:0] GPIOPinsIn; logic [31:0] GPIOIN;
logic [31:0] GPIOPinsOut, GPIOPinsEn; logic [31:0] GPIOOUT, GPIOEN;
logic UARTSin, UARTSout; logic UARTSin, UARTSout;
// FPGA-specific Stuff // FPGA-specific Stuff
@ -264,7 +264,7 @@ module testbench;
logic [3:0] SDCDatIn; logic [3:0] SDCDatIn;
// Hardwire UART, GPIO pins // Hardwire UART, GPIO pins
assign GPIOPinsIn = 0; assign GPIOIN = 0;
assign UARTSin = 1; assign UARTSin = 1;
// Wally // Wally
@ -272,7 +272,7 @@ module testbench;
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK, .HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK,
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HWSTRB, .HSIZE, .HBURST, .HPROT, .HRESETn, .HADDR, .HWDATA, .HWRITE, .HWSTRB, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK, .HTRANS, .HMASTLOCK,
.TIMECLK('0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .TIMECLK('0), .GPIOIN, .GPIOOUT, .GPIOEN,
.UARTSin, .UARTSout, .UARTSin, .UARTSout,
.SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn); .SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn);

View File

@ -30,6 +30,8 @@
`define PrintHPMCounters 1 `define PrintHPMCounters 1
`define BPRED_LOGGER 1 `define BPRED_LOGGER 1
`define I_CACHE_ADDR_LOGGER 1
`define D_CACHE_ADDR_LOGGER 1
module testbench; module testbench;
parameter DEBUG=0; parameter DEBUG=0;
@ -150,7 +152,7 @@ logic [3:0] dummy;
string signame, memfilename, pathname, objdumpfilename, adrstr, outputfile; string signame, memfilename, pathname, objdumpfilename, adrstr, outputfile;
integer outputFilePointer; integer outputFilePointer;
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic [31:0] GPIOIN, GPIOOUT, GPIOEN;
logic UARTSin, UARTSout; logic UARTSin, UARTSout;
logic SDCCLK; logic SDCCLK;
@ -169,7 +171,7 @@ logic [3:0] dummy;
logic InReset; logic InReset;
// instantiate device to be tested // instantiate device to be tested
assign GPIOPinsIn = 0; assign GPIOIN = 0;
assign UARTSin = 1; assign UARTSin = 1;
if(`EXT_MEM_SUPPORTED) begin if(`EXT_MEM_SUPPORTED) begin
@ -199,7 +201,7 @@ logic [3:0] dummy;
wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
.HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN,
.UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK); .UARTSin, .UARTSout, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn, .SDCCLK);
// Track names of instructions // Track names of instructions
@ -546,8 +548,56 @@ logic [3:0] dummy;
end end
end end
end end
end
if (`I_CACHE_ADDR_LOGGER == 1) begin
int file;
string LogFile;
logic resetD, resetEdge;
flop #(1) ResetDReg(clk, reset, resetD);
assign resetEdge = ~reset & resetD;
initial begin
LogFile = $psprintf("ICache.log");
file = $fopen(LogFile, "w");
end
always @(posedge clk) begin
if(resetEdge) $fwrite(file, "TRAIN\n");
if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename);
if(~dut.core.StallD & ~dut.core.FlushD) begin
$fwrite(file, "%h R\n", dut.core.ifu.PCPF);
end
if(EndSample) $fwrite(file, "END %s\n", memfilename);
end
end end
if (`D_CACHE_ADDR_LOGGER == 1) begin
int file;
string LogFile;
logic resetD, resetEdge;
flop #(1) ResetDReg(clk, reset, resetD);
assign resetEdge = ~reset & resetD;
initial begin
LogFile = $psprintf("DCache.log");
file = $fopen(LogFile, "w");
end
always @(posedge clk) begin
if(resetEdge) $fwrite(file, "TRAIN\n");
if(StartSample) $fwrite(file, "BEGIN %s\n", memfilename);
if(~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin
if(dut.core.lsu.bus.dcache.CacheRWM == 2'b10) begin
$fwrite(file, "%h R\n", dut.core.lsu.PAdrM);
end else if (dut.core.lsu.bus.dcache.CacheRWM == 2'b01) begin
$fwrite(file, "%h W\n", dut.core.lsu.PAdrM);
end else if (dut.core.lsu.bus.dcache.CacheAtomicM[1] == 1'b1) begin // *** This may change
$fwrite(file, "%h A\n", dut.core.lsu.PAdrM);
end else if (dut.core.lsu.bus.dcache.FlushDCache) begin
$fwrite(file, "%h F\n", dut.core.lsu.PAdrM);
end
end
if(EndSample) $fwrite(file, "END %s\n", memfilename);
end
end
if (`BPRED_SUPPORTED == 1) begin if (`BPRED_SUPPORTED == 1) begin
if (`BPRED_LOGGER) begin if (`BPRED_LOGGER) begin

Some files were not shown because too many files have changed in this diff Show More