mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'bitmanip_cleanup' of https://github.com/kipmacsaigoren/cvw into bitmanip_cleanup
This commit is contained in:
commit
bd1ac13f5f
@ -34,8 +34,8 @@ Clone your fork of the repo and run the setup script.
|
||||
|
||||
$ cd
|
||||
$ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw
|
||||
$ git remote add upstream https://github.com/openhwgroup/cvw
|
||||
$ cd cvw
|
||||
$ git remote add upstream https://github.com/openhwgroup/cvw
|
||||
$ source ./setup.sh
|
||||
|
||||
Add the following lines to your .bashrc or .bash_profile to run the setup script each time you log in.
|
||||
|
@ -29,7 +29,7 @@
|
||||
`include "wally-shared.vh"
|
||||
|
||||
`define FPGA 1
|
||||
`define QEMU 1
|
||||
`define QEMU 0
|
||||
// RV32 or RV64: XLEN = 32 or 64
|
||||
`define XLEN 64
|
||||
|
||||
|
41
docs/README-linux.md
Normal file
41
docs/README-linux.md
Normal 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, don’t 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 haven’t 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, you’ll 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
|
251
fpga/constraints/constraints-artyA7.xdc
Normal file
251
fpga/constraints/constraints-artyA7.xdc
Normal 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
|
||||
|
||||
|
@ -120,8 +120,6 @@ ebu/ebu.sv: logic HCLK
|
||||
ebu/ebu.sv: logic HREADY
|
||||
ebu/ebu.sv: logic HRESP
|
||||
ebu/ebu.sv: logic HADDR
|
||||
ebu/ebu.sv: logic HWDATA
|
||||
ebu/ebu.sv: logic HWSTRB
|
||||
ebu/ebu.sv: logic HWRITE
|
||||
ebu/ebu.sv: logic HSIZE
|
||||
ebu/ebu.sv: logic HBURST
|
||||
|
@ -88,7 +88,7 @@ module fpgaTop
|
||||
|
||||
|
||||
|
||||
wire [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
|
||||
wire [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
|
||||
wire SDCCmdIn;
|
||||
wire SDCCmdOE;
|
||||
@ -183,8 +183,8 @@ module fpgaTop
|
||||
|
||||
|
||||
|
||||
assign GPIOPinsIn = {28'b0, GPI};
|
||||
assign GPO = GPIOPinsOut[4:0];
|
||||
assign GPIOIN = {28'b0, GPI};
|
||||
assign GPO = GPIOOUT[4:0];
|
||||
assign ahblite_resetn = peripheral_aresetn;
|
||||
assign cpu_reset = bus_struct_reset;
|
||||
assign calib = c0_init_calib_complete;
|
||||
@ -231,9 +231,9 @@ module fpgaTop
|
||||
.HMASTLOCK(HMASTLOCK),
|
||||
.HREADY(HREADY),
|
||||
// GPIO
|
||||
.GPIOPinsIn(GPIOPinsIn),
|
||||
.GPIOPinsOut(GPIOPinsOut),
|
||||
.GPIOPinsEn(GPIOPinsEn),
|
||||
.GPIOIN(GPIOIN),
|
||||
.GPIOOUT(GPIOOUT),
|
||||
.GPIOEN(GPIOEN),
|
||||
// UART
|
||||
.UARTSin(UARTSin),
|
||||
.UARTSout(UARTSout),
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
all: riscoftests memfiles
|
||||
all: riscoftests memfiles coveragetests
|
||||
# *** Build old tests/imperas-riscv-tests for now;
|
||||
# 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
|
||||
@ -50,3 +50,6 @@ riscoftests:
|
||||
make -C ../tests/riscof/
|
||||
memfiles:
|
||||
make -f makefile-memfile wally-sim-files --jobs
|
||||
|
||||
coveragetests:
|
||||
make -C ../tests/coverage/
|
||||
|
@ -1,5 +1,7 @@
|
||||
#--showoverrides
|
||||
#--showcommands
|
||||
#--mpdconsole
|
||||
#--gdbconsole
|
||||
--showoverrides
|
||||
--showcommands
|
||||
|
||||
# Core settings
|
||||
--override cpu/unaligned=F
|
||||
@ -9,7 +11,12 @@
|
||||
--override cpu/misa_Extensions_mask=0x0
|
||||
|
||||
# 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
|
||||
# 'r': read access allowed
|
||||
@ -24,16 +31,16 @@
|
||||
# '8': 8-byte accesses allowed
|
||||
# '-', 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 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 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 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 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 "; # UNCORE_RAM
|
||||
--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 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 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 0x0010060000 -hi 0x00100600FF -attributes " rw--A- --4- " # GPIO error - 0x10006000 - 0x100060FF
|
||||
--callcommand refRoot/cpu/setPMA -lo 0x0080000000 -hi 0x008FFFFFFF -attributes " rwx--- 1248 " # UNCORE_RAM
|
||||
|
||||
# Enable the Imperas instruction coverage
|
||||
#-extlib refRoot/cpu/cv=imperas.com/intercept/riscvInstructionCoverage/1.0
|
||||
@ -42,7 +49,7 @@
|
||||
|
||||
# Add Imperas simulator application instruction tracing
|
||||
--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
|
||||
--override cpu/debugflags=6
|
||||
|
9
sim/run-imperas-linux.sh
Executable file
9
sim/run-imperas-linux.sh
Executable 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"
|
@ -51,7 +51,7 @@ vlog +incdir+../config/$1 \
|
||||
-suppress 7063 \
|
||||
+acc
|
||||
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 \
|
||||
+testDir=$env(TESTDIR) $env(OTHERFLAGS) +TRACE2COV_ENABLE=1 \
|
||||
-do "coverage save -onexit ./riscv.ucdb"
|
||||
|
@ -34,7 +34,7 @@ vlog +incdir+../config/$1 \
|
||||
-suppress 2583 \
|
||||
-suppress 7063
|
||||
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)
|
||||
view wave
|
||||
#-- display input and output signals as hexidecimal values
|
||||
|
@ -45,7 +45,7 @@ vlog +incdir+../config/$1 \
|
||||
-suppress 7063
|
||||
|
||||
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 \
|
||||
+testDir=$env(TESTDIR) $env(OTHERFLAGS)
|
||||
view wave
|
||||
|
150
sim/wally-linux-imperas.do
Normal file
150
sim/wally-linux-imperas.do
Normal 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
|
||||
#}
|
2
src/cache/cachefsm.sv
vendored
2
src/cache/cachefsm.sv
vendored
@ -135,7 +135,7 @@ module cachefsm #(parameter READ_ONLY_CACHE = 0) (
|
||||
end
|
||||
|
||||
// com back to CPU
|
||||
assign CacheCommitted = CurrState != STATE_READY;
|
||||
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & CurrState == STATE_READ_HOLD);
|
||||
assign CacheStall = (CurrState == STATE_READY & (FlushCache | AnyMiss)) |
|
||||
(CurrState == STATE_FETCH) |
|
||||
(CurrState == STATE_WRITEBACK) |
|
||||
|
8
src/cache/cacheway.sv
vendored
8
src/cache/cacheway.sv
vendored
@ -86,8 +86,6 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
||||
assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
|
||||
|
||||
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
|
||||
//assign SelTag = VictimWay | FlushWay;
|
||||
//assign SelData = HitWay | FlushWayEn | VictimWayEn;
|
||||
|
||||
mux2 #(1) selectedwaymux(HitWay, SelTag, SelNonHit , SelData);
|
||||
|
||||
@ -95,10 +93,6 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
||||
// 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 ClearValidWay = ClearValid & SelData;
|
||||
assign SetDirtyWay = SetDirty & SelData;
|
||||
@ -117,8 +111,6 @@ module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
||||
.addr(CacheSet), .dout(ReadTag), .bwe('1),
|
||||
.din(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .we(SetValidEN));
|
||||
|
||||
|
||||
|
||||
// AND portion of distributed tag multiplexer
|
||||
assign TagWay = SelTag ? ReadTag : '0; // AND part of AOMux
|
||||
assign DirtyWay = SelTag & Dirty & ValidWay;
|
||||
|
@ -33,7 +33,8 @@ module ahbcacheinterface #(
|
||||
parameter BEATSPERLINE, // Number of AHBW words (beats) in cacheline
|
||||
parameter AHBWLOGBWPL, // Log2 of ^
|
||||
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)
|
||||
parameter READ_ONLY_CACHE
|
||||
)(
|
||||
input logic HCLK, HRESETn,
|
||||
// bus interface controls
|
||||
@ -115,7 +116,7 @@ module ahbcacheinterface #(
|
||||
|
||||
flopen #(`AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[`AHBW/8-1:0], HWSTRB);
|
||||
|
||||
buscachefsm #(BeatCountThreshold, AHBWLOGBWPL) AHBBuscachefsm(
|
||||
buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm(
|
||||
.HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
|
||||
.CacheBusRW, .CacheBusAck, .BeatCount, .BeatCountDelayed,
|
||||
.HREADY, .HTRANS, .HWRITE, .HBURST);
|
||||
|
@ -53,7 +53,6 @@ module ahbinterface #(
|
||||
);
|
||||
|
||||
logic CaptureEn;
|
||||
|
||||
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));
|
||||
@ -70,4 +69,5 @@ module ahbinterface #(
|
||||
busfsm busfsm(.HCLK, .HRESETn, .Flush, .BusRW,
|
||||
.BusCommitted, .Stall, .BusStall, .CaptureEn, .HREADY,
|
||||
.HTRANS, .HWRITE);
|
||||
|
||||
endmodule
|
||||
|
@ -33,7 +33,8 @@
|
||||
// HCLK and clk must be the same clock!
|
||||
module buscachefsm #(
|
||||
parameter BeatCountThreshold, // Largest beat index
|
||||
parameter AHBWLOGBWPL // Log2 of BEATSPERLINE
|
||||
parameter AHBWLOGBWPL, // Log2 of BEATSPERLINE
|
||||
parameter READ_ONLY_CACHE
|
||||
)(
|
||||
input logic HCLK,
|
||||
input logic HRESETn,
|
||||
@ -121,7 +122,7 @@ module buscachefsm #(
|
||||
(CurrState == DATA_PHASE) |
|
||||
(CurrState == CACHE_FETCH & ~HREADY) |
|
||||
(CurrState == CACHE_WRITEBACK & ~HREADY);
|
||||
assign BusCommitted = CurrState != ADR_PHASE;
|
||||
assign BusCommitted = (CurrState != ADR_PHASE) & ~(READ_ONLY_CACHE & CurrState == MEM3);
|
||||
|
||||
// AHB bus interface
|
||||
assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW)) & ~Flush) |
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module controllerinputstage #(
|
||||
module controllerinput #(
|
||||
parameter SAVE_ENABLED = 1 // 1: Save manager inputs if Save = 1, 0: Don't save inputs
|
||||
)(
|
||||
input logic HCLK,
|
@ -66,7 +66,6 @@ module ebu (
|
||||
output logic HMASTLOCK // AHB master lock. Wally does not use
|
||||
);
|
||||
|
||||
|
||||
logic LSUDisable;
|
||||
logic LSUSelect;
|
||||
logic IFUSave;
|
||||
@ -89,8 +88,6 @@ module ebu (
|
||||
logic IFUReq;
|
||||
logic LSUReq;
|
||||
|
||||
|
||||
|
||||
assign HCLK = clk;
|
||||
assign HRESETn = ~reset;
|
||||
|
||||
@ -101,14 +98,14 @@ module ebu (
|
||||
// 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),
|
||||
.HWRITEIn(1'b0), .HSIZEIn(IFUHSIZE), .HBURSTIn(IFUHBURST), .HTRANSIn(IFUHTRANS), .HADDRIn(IFUHADDR),
|
||||
.HWRITEOut(IFUHWRITEOut), .HSIZEOut(IFUHSIZEOut), .HBURSTOut(IFUHBURSTOut), .HREADYOut(IFUHREADY),
|
||||
.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.
|
||||
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),
|
||||
.HWRITEIn(LSUHWRITE), .HSIZEIn(LSUHSIZE), .HBURSTIn(LSUHBURST), .HTRANSIn(LSUHTRANS), .HADDRIn(LSUHADDR), .HREADYOut(LSUHREADY),
|
||||
.HWRITEOut(LSUHWRITEOut), .HSIZEOut(LSUHSIZEOut), .HBURSTOut(LSUHBURSTOut),
|
||||
|
@ -41,7 +41,6 @@ module ebufsmarb (
|
||||
input logic LSUReq,
|
||||
input logic IFUReq,
|
||||
|
||||
|
||||
output logic IFUSave,
|
||||
output logic IFURestore,
|
||||
output logic IFUDisable,
|
||||
@ -57,7 +56,7 @@ module ebufsmarb (
|
||||
logic FinalBeat, FinalBeatD; // Indicates the last beat of a burst
|
||||
logic BeatCntEn;
|
||||
logic [3:0] BeatCount; // Position within a burst transfer
|
||||
logic CntReset;
|
||||
logic BeatCntReset;
|
||||
logic [3:0] Threshold; // Number of beats derived from HBURST
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -98,29 +97,26 @@ module ebufsmarb (
|
||||
// Burst mode logic
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
assign CntReset = NextState == IDLE;
|
||||
assign BeatCntReset = NextState == IDLE;
|
||||
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;
|
||||
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.
|
||||
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.
|
||||
// HBURST[2:1] Beats
|
||||
// 00 1
|
||||
// 01 4
|
||||
// 10 8
|
||||
// 11 16
|
||||
// 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 threshold
|
||||
// 00 1 0
|
||||
// 01 4 3
|
||||
// 10 8 7
|
||||
// 11 16 15
|
||||
always_comb
|
||||
if (HBURST[2:1] == 2'b00) Threshold = 4'b0000;
|
||||
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
|
||||
|
112
src/fpu/fctrl.sv
112
src/fpu/fctrl.sv
@ -75,44 +75,42 @@ module fctrl (
|
||||
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
|
||||
logic [2:0] FrmD, FrmE; // FP rounding mode
|
||||
logic [`FMTBITS-1:0] FmtD; // FP format
|
||||
logic [1:0] Fmt; // format - before possible reduction
|
||||
logic [1:0] Fmt, Fmt2; // format - before possible reduction
|
||||
logic SupportedFmt; // is the format supported
|
||||
logic SupportedFmt2; // is the source format supported for fp -> fp
|
||||
logic FCvtIntD, FCvtIntM; // convert to integer opperation
|
||||
|
||||
// FPU Instruction Decoder
|
||||
assign Fmt = Funct7D[1:0];
|
||||
assign Fmt2 = Rs2D[1:0]; // source format for fcvt fp->fp
|
||||
|
||||
// Note: only Fmt is checked; fcvt does not check destination format
|
||||
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & `D_SUPPORTED) |
|
||||
(Fmt == 2'b10 & `ZFH_SUPPORTED) | (Fmt == 2'b11 & `Q_SUPPORTED));
|
||||
assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & `D_SUPPORTED) |
|
||||
(Fmt2 == 2'b10 & `ZFH_SUPPORTED) | (Fmt2 == 2'b11 & `Q_SUPPORTED));
|
||||
|
||||
// decode the instruction
|
||||
// ControlsD: FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt
|
||||
always_comb
|
||||
if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled
|
||||
ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0;
|
||||
else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt)
|
||||
ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // for anything other than loads and stores, check for supported format
|
||||
else case(OpD)
|
||||
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt
|
||||
else begin
|
||||
ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // default: illegal FPU instruction
|
||||
/* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed
|
||||
case(OpD)
|
||||
7'b0000111: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flw
|
||||
3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // fld
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fld not supported
|
||||
3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flq
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flq not supported
|
||||
3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0_0; // flh
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // flh not supported
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
|
||||
endcase
|
||||
7'b0100111: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsw
|
||||
3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsd
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsd not supported
|
||||
3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsq
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsq not supported
|
||||
3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0_0; // fsh
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1_0; // fsh not supported
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
|
||||
endcase
|
||||
7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0_0; // fmadd
|
||||
7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0_0; // fmsub
|
||||
@ -128,56 +126,82 @@ module fctrl (
|
||||
3'b000: ControlsD = `FCTRLW'b1_0_00_xx_000_0_0_0; // fsgnj
|
||||
3'b001: ControlsD = `FCTRLW'b1_0_00_xx_001_0_0_0; // fsgnjn
|
||||
3'b010: ControlsD = `FCTRLW'b1_0_00_xx_010_0_0_0; // fsgnjx
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
|
||||
endcase
|
||||
7'b00101??: case(Funct3D)
|
||||
3'b000: ControlsD = `FCTRLW'b1_0_00_xx_110_0_0_0; // fmin
|
||||
3'b001: ControlsD = `FCTRLW'b1_0_00_xx_101_0_0_0; // fmax
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
|
||||
endcase
|
||||
7'b10100??: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b0_1_00_xx_010_0_0_0; // feq
|
||||
3'b001: ControlsD = `FCTRLW'b0_1_00_xx_001_0_0_0; // flt
|
||||
3'b000: ControlsD = `FCTRLW'b0_1_00_xx_011_0_0_0; // fle
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_000__0_1_0; // non-implemented instruction
|
||||
endcase
|
||||
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
|
||||
ControlsD = `FCTRLW'b0_1_10_xx_000_0_0_0; // fclass
|
||||
else if (Funct3D[1:0] == 2'b00) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w to int reg
|
||||
else if (Funct3D[1:0] == 2'b01) ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.d to int reg
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
|
||||
7'b1101000: case(Rs2D[1:0])
|
||||
2'b00: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s
|
||||
2'b01: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s
|
||||
2'b10: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s
|
||||
2'b11: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s
|
||||
else if (Funct3D == 3'b000 & Rs2D == 5'b00000)
|
||||
ControlsD = `FCTRLW'b0_1_11_xx_000_0_0_0; // fmv.x.w / fmv.x.d to int register
|
||||
7'b111100?: if (Funct3D == 3'b000 & Rs2D == 5'b00000)
|
||||
ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x / fmv.d.x to fp reg
|
||||
7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00)
|
||||
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.(d/q/h)
|
||||
7'b0100001: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b01)
|
||||
ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.(s/h/q)
|
||||
7'b0100010: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b10)
|
||||
ControlsD = `FCTRLW'b1_0_01_00_010_0_0_0; // fcvt.h.(s/d/q)
|
||||
7'b0100011: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b11)
|
||||
ControlsD = `FCTRLW'b1_0_01_00_011_0_0_0; // fcvt.q.(s/h/d)
|
||||
7'b1101000: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.s.w w->s
|
||||
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.s.wu wu->s
|
||||
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.s.l l->s
|
||||
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.s.lu lu->s
|
||||
endcase
|
||||
7'b1100000: case(Rs2D[1:0])
|
||||
2'b00: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w
|
||||
2'b01: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu
|
||||
2'b10: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l
|
||||
2'b11: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu
|
||||
7'b1100000: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.s s->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.s s->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.s s->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.s s->lu
|
||||
endcase
|
||||
7'b1111000: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.w.x to fp reg
|
||||
7'b0100000: ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0; // fcvt.s.d
|
||||
7'b1101001: case(Rs2D[1:0])
|
||||
2'b00: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d
|
||||
2'b01: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d
|
||||
2'b10: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d
|
||||
2'b11: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d
|
||||
7'b1101001: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.d.w w->d
|
||||
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.d.wu wu->d
|
||||
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.d.l l->d
|
||||
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.d.lu lu->d
|
||||
endcase
|
||||
7'b1100001: case(Rs2D[1:0])
|
||||
2'b00: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w
|
||||
2'b01: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu
|
||||
2'b10: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l
|
||||
2'b11: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu
|
||||
7'b1100001: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.d d->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.d d->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.d d->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.d d->lu
|
||||
endcase
|
||||
7'b1111001: ControlsD = `FCTRLW'b1_0_00_xx_011_0_0_0; // fmv.d.x to fp reg
|
||||
7'b0100001: ControlsD = `FCTRLW'b1_0_01_00_001_0_0_0; // fcvt.d.s
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
|
||||
7'b1101010: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.h.w w->h
|
||||
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.h.wu wu->h
|
||||
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.h.l l->h
|
||||
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.h.lu lu->h
|
||||
endcase
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_000_0_1_0; // non-implemented instruction
|
||||
7'b1100010: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.h h->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.h h->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.h h->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.h h->lu
|
||||
endcase
|
||||
7'b1101011: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0; // fcvt.q.w w->q
|
||||
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0; // fcvt.q.wu wu->q
|
||||
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0; // fcvt.q.l l->q
|
||||
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0; // fcvt.q.lu lu->q
|
||||
endcase
|
||||
7'b1100011: case(Rs2D)
|
||||
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1; // fcvt.w.q q->w
|
||||
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1; // fcvt.wu.q q->wu
|
||||
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1; // fcvt.l.q q->l
|
||||
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1; // fcvt.lu.q q->lu
|
||||
endcase
|
||||
endcase
|
||||
endcase
|
||||
/* verilator lint_off CASEINCOMPLETE */
|
||||
end
|
||||
|
||||
// unswizzle control bits
|
||||
assign #1 {FRegWriteD, FWriteIntD, FResSelD, PostProcSelD, OpCtrlD, FDivStartD, IllegalFPUInstrD, FCvtIntD} = ControlsD;
|
||||
|
@ -31,7 +31,7 @@
|
||||
module fdivsqrtstage4 (
|
||||
input logic [`DIVb-1:0] D,
|
||||
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+1:0] C,
|
||||
input logic SqrtE, j1,
|
||||
|
@ -94,7 +94,6 @@ module ram1p1rwbe #(parameter DEPTH=64, WIDTH=44) (
|
||||
always_ff @(posedge clk)
|
||||
if(ce) dout <= #1 mem[addr]; */
|
||||
|
||||
|
||||
// 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.
|
||||
// Therefore these always blocks use the older always @(posedge clk)
|
||||
|
@ -85,7 +85,6 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) (
|
||||
logic [SRAMWIDTH-1:0] SRAMBitMask;
|
||||
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
|
||||
@ -118,7 +117,7 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) (
|
||||
flopen #($clog2(DEPTH)) adrreg(clk, ce1, ra1, ra1d);
|
||||
assign rd1 = mem[ra1d];
|
||||
|
||||
/* // Read
|
||||
/* // Read
|
||||
always_ff @(posedge clk)
|
||||
if(ce1) rd1 <= #1 mem[ra1]; */
|
||||
|
||||
@ -133,7 +132,6 @@ module ram2p1r1wbe #(parameter DEPTH=1024, WIDTH=68) (
|
||||
always @(posedge clk)
|
||||
if (ce2 & we2 & bwe2[WIDTH/8])
|
||||
mem[wa2][WIDTH-1:WIDTH-WIDTH%8] <= #1 wd2[WIDTH-1:WIDTH-WIDTH%8];
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -32,7 +32,7 @@ module rom1p1r_128x64(
|
||||
);
|
||||
|
||||
// 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);
|
||||
|
||||
endmodule
|
||||
|
@ -131,6 +131,7 @@ module controller(
|
||||
logic JFunctD; // detect jalr instruction
|
||||
logic FenceM; // Fence.I or sfence.VMA instruction in memory stage
|
||||
logic [2:0] ALUSelectD; // ALU Output selection mux control
|
||||
logic IWValidFunct3D; // Detects if Funct3 is valid for IW instructions
|
||||
|
||||
// Extract fields
|
||||
assign OpD = InstrD[6:0];
|
||||
@ -161,6 +162,7 @@ module controller(
|
||||
((`XLEN == 64) & (Funct3D == 3'b011));
|
||||
assign BFunctD = (Funct3D[2:1] != 2'b01); // legal branches
|
||||
assign JFunctD = (Funct3D == 3'b000);
|
||||
assign IWValidFunct3D = Funct3D == 3'b000 | Funct3D == 3'b001 | Funct3D == 3'b101;
|
||||
end else begin:legalcheck2
|
||||
assign IFunctD = 1; // Don't bother to separate out shift decoding
|
||||
assign RFunctD = ~Funct7D[0]; // Not a multiply
|
||||
@ -169,6 +171,7 @@ module controller(
|
||||
assign SFunctD = 1; // don't bother to check Funct3 for stores
|
||||
assign BFunctD = 1; // don't bother to check Funct3 for branches
|
||||
assign JFunctD = 1; // don't bother to check Funct3 for jumps
|
||||
assign IWValidFunct3D = 1;
|
||||
end
|
||||
|
||||
// Main Instruction Decoder
|
||||
@ -187,7 +190,7 @@ module controller(
|
||||
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
|
||||
7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_0_0_0_0_0_0_0_0_00_0; // auipc
|
||||
7'b0011011: if (IFunctD & `XLEN == 64)
|
||||
7'b0011011: if (IFunctD & IWValidFunct3D & `XLEN == 64)
|
||||
ControlsD = `CTRLW'b1_000_01_00_000_0_1_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i
|
||||
7'b0100011: if (SFunctD)
|
||||
ControlsD = `CTRLW'b0_001_01_01_000_0_0_0_0_0_0_0_0_0_00_0; // stores
|
||||
|
@ -35,8 +35,8 @@ module shifter (
|
||||
input logic Right, Rotate, W64, SubArith, // Shift right, rotate, W64-type operation, arithmetic shift
|
||||
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 [`LOG_XLEN-1:0] amttrunc, Offset; // Shift amount adjusted for RV64, right-shift amount
|
||||
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] TruncAmt, Offset; // Shift amount adjusted for RV64, right-shift amount
|
||||
logic Sign; // 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
|
||||
always_comb // funnel mux
|
||||
case({Right, Rotate})
|
||||
2'b00: z = {A[31:0], 31'b0};
|
||||
2'b01: z = {A[31:0], A[31:1]};
|
||||
2'b10: z = {{31{Sign}}, A[31:0]};
|
||||
2'b11: z = {A[30:0], A[31:0]};
|
||||
2'b00: Z = {A[31:0], 31'b0};
|
||||
2'b01: Z = {A[31:0], A[31:1]};
|
||||
2'b10: Z = {{31{Sign}}, A[31:0]};
|
||||
2'b11: Z = {A[30:0], A[31:0]};
|
||||
endcase
|
||||
end else begin: norotfunnel32 //rv32 shifter without rotates
|
||||
always_comb // funnel mux
|
||||
if (Right) z = {{31{Sign}}, A[31:0]};
|
||||
else z = {A[31:0], 31'b0};
|
||||
if (Right) Z = {{31{Sign}}, A[31:0]};
|
||||
else Z = {A[31:0], 31'b0};
|
||||
end
|
||||
assign amttrunc = Amt; // shift amount
|
||||
assign TruncAmt = Amt; // shift amount
|
||||
end else begin // rv64
|
||||
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
|
||||
@ -64,25 +64,25 @@ module shifter (
|
||||
mux2 #(`XLEN) rotmux(A, {A[31:0], A[31:0]}, W64, RotA); // W64 rotatons
|
||||
always_comb // funnel mux
|
||||
case ({Right, Rotate})
|
||||
2'b00: z = {A64[63:0],{63'b0}};
|
||||
2'b01: z = {RotA[63:0], RotA[63:1]};
|
||||
2'b10: z = {{63{Sign}}, A64[63:0]};
|
||||
2'b11: z = {RotA[62:0], RotA[63:0]};
|
||||
2'b00: Z = {A64[63:0],{63'b0}};
|
||||
2'b01: Z = {RotA[63:0], RotA[63:1]};
|
||||
2'b10: Z = {{63{Sign}}, A64[63:0]};
|
||||
2'b11: Z = {RotA[62:0], RotA[63:0]};
|
||||
endcase
|
||||
end else begin: norotfunnel64 // rv64 shifter without rotates
|
||||
always_comb // funnel mux
|
||||
if (Right) z = {{63{Sign}}, A64[63:0]};
|
||||
else z = {A64[63:0], {63'b0}};
|
||||
if (Right) Z = {{63{Sign}}, A64[63:0]};
|
||||
else Z = {A64[63:0], {63'b0}};
|
||||
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
|
||||
|
||||
// Opposite offset for right shifts
|
||||
assign Offset = Right ? amttrunc : ~amttrunc;
|
||||
assign Offset = Right ? TruncAmt : ~TruncAmt;
|
||||
|
||||
// Funnel operation
|
||||
assign zshift = z >> Offset;
|
||||
assign Y = zshift[`XLEN-1:0];
|
||||
assign ZShift = Z >> Offset;
|
||||
assign Y = ZShift[`XLEN-1:0];
|
||||
endmodule
|
||||
|
||||
|
||||
|
@ -97,8 +97,6 @@ module bpred (
|
||||
logic BPReturnWrongD;
|
||||
logic [`XLEN-1:0] BPBTAE;
|
||||
|
||||
|
||||
|
||||
// Part 1 branch direction prediction
|
||||
// look into the 2 port Sram model. something is wrong.
|
||||
if (`BPRED_TYPE == "BP_TWOBIT") begin:Predictor
|
||||
|
@ -111,5 +111,4 @@ module btb #(parameter Depth = 10 ) (
|
||||
flopenr #(`XLEN) PCWReg(clk, reset, ~StallW, PCM, PCW);
|
||||
flopenr #(`XLEN) IEUAdrWReg(clk, reset, ~StallW, IEUAdrM, IEUAdrW);
|
||||
|
||||
|
||||
endmodule
|
||||
|
@ -251,7 +251,7 @@ module ifu (
|
||||
.NextSet(PCSpillNextF[11:0]),
|
||||
.PAdr(PCPF),
|
||||
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM));
|
||||
ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW)
|
||||
ahbcacheinterface #(WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1)
|
||||
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
|
||||
.HRDATA,
|
||||
.Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(),
|
||||
|
@ -51,8 +51,9 @@ module spill #(
|
||||
|
||||
// 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;
|
||||
statetype CurrState, NextState;
|
||||
localparam SPILLTHRESHOLD = CACHE_ENABLED ? `ICACHE_LINELENINBITS/32 : 1;
|
||||
|
||||
statetype CurrState, NextState;
|
||||
logic [`XLEN-1:0] PCPlus2F;
|
||||
logic TakeSpillF;
|
||||
logic SpillF;
|
||||
|
@ -275,7 +275,7 @@ module lsu (
|
||||
.FetchBuffer, .CacheBusRW,
|
||||
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0));
|
||||
|
||||
ahbcacheinterface #(.BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW)) ahbcacheinterface(
|
||||
ahbcacheinterface #(.BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW), .READ_ONLY_CACHE(0)) ahbcacheinterface(
|
||||
.HCLK(clk), .HRESETn(~reset), .Flush(FlushW),
|
||||
.HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB),
|
||||
.HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY),
|
||||
|
@ -88,7 +88,7 @@ module subwordread
|
||||
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'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'b110: ReadDataM = {{`LLEN-32{1'b0}}, WordM[31:0]}; // lwu
|
||||
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
|
||||
|
@ -36,7 +36,7 @@ module div(
|
||||
input logic IntDivE, // integer division/remainder instruction of any type
|
||||
input logic DivSignedE, // signed division
|
||||
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 [`XLEN-1:0] QuotM, RemM // Quotient and remainder outputs
|
||||
);
|
||||
|
@ -108,12 +108,12 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) (
|
||||
.Cacheable, .Idempotent, .SelTIM,
|
||||
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
|
||||
|
||||
if (`PMP_ENTRIES > 0)
|
||||
if (`PMP_ENTRIES > 0) begin : pmp
|
||||
pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW,
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
.ExecuteAccessF, .WriteAccessM, .ReadAccessM,
|
||||
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
|
||||
else begin
|
||||
end else begin
|
||||
assign PMPInstrAccessFaultF = 0;
|
||||
assign PMPStoreAmoAccessFaultM = 0;
|
||||
assign PMPLoadAccessFaultM = 0;
|
||||
|
@ -38,7 +38,7 @@ module pmpadrdec (
|
||||
input logic [`PA_BITS-3:0] PMPAdr,
|
||||
input logic PAgePMPAdrIn,
|
||||
output logic PAgePMPAdrOut,
|
||||
output logic Match, Active,
|
||||
output logic Match,
|
||||
output logic L, X, W, R
|
||||
);
|
||||
|
||||
@ -84,7 +84,6 @@ module pmpadrdec (
|
||||
assign X = PMPCfg[2];
|
||||
assign W = PMPCfg[1];
|
||||
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
|
||||
// attempts an 8-byte access to 0x8, the access should fail (see page 60 of privileged specification 20211203). This
|
||||
|
@ -53,25 +53,23 @@ module pmpchecker (
|
||||
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] 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] 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](
|
||||
.PhysicalAddress,
|
||||
.PMPCfg(PMPCFG_ARRAY_REGW),
|
||||
.PMPAdr(PMPADDR_ARRAY_REGW),
|
||||
.PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
|
||||
.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.
|
||||
|
||||
// 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
|
||||
// *** remove unused Active lines from pmpadrdecs
|
||||
assign EnforcePMP = (PrivilegeModeW != `M_MODE) | |(L & FirstMatch); // *** switch to this logic when PMP is initialized for non-machine mode
|
||||
|
||||
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;
|
||||
assign PMPStoreAmoAccessFaultM = EnforcePMP & WriteAccessM & ~|(W & FirstMatch) ;
|
||||
|
@ -55,7 +55,7 @@ module csr #(parameter
|
||||
input logic [4:0] SetFflagsM, // Set floating point flag bits in FCSR
|
||||
input logic [1:0] NextPrivilegeModeM, // STATUS bits updated based on next privilege mode
|
||||
input logic [1:0] PrivilegeModeW, // current privilege mode
|
||||
input logic [`LOG_XLEN-1:0] CauseM, // Trap cause
|
||||
input logic [3:0] CauseM, // Trap cause
|
||||
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
|
||||
// inputs for performance counters
|
||||
input logic LoadStallD,
|
||||
@ -79,7 +79,7 @@ module csr #(parameter
|
||||
// outputs from CSRs
|
||||
output logic [1:0] STATUS_MPP,
|
||||
output logic STATUS_SPP, STATUS_TSR, STATUS_TVM,
|
||||
output logic [`XLEN-1:0] MEDELEG_REGW,
|
||||
output logic [15:0] MEDELEG_REGW,
|
||||
output logic [`XLEN-1:0] SATP_REGW,
|
||||
output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
|
||||
output logic STATUS_MIE, STATUS_SIE,
|
||||
@ -107,7 +107,8 @@ module csr #(parameter
|
||||
logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM;
|
||||
logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
|
||||
logic WriteFRMM, WriteFFLAGSM;
|
||||
logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextCauseM, NextMtvalM;
|
||||
logic [`XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM;
|
||||
logic [4:0] NextCauseM;
|
||||
logic [11:0] CSRAdrM;
|
||||
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM;
|
||||
logic InsufficientCSRPrivilegeM;
|
||||
@ -153,7 +154,7 @@ module csr #(parameter
|
||||
logic VectoredM;
|
||||
logic [`XLEN-1:0] TVecPlusCauseM;
|
||||
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, 2'b00}; // 64-byte alignment allows concatenation rather than addition
|
||||
mux2 #(`XLEN) trapvecmux(TVecAlignedM, TVecPlusCauseM, VectoredM, TrapVectorM);
|
||||
end else
|
||||
assign TrapVectorM = TVecAlignedM;
|
||||
@ -196,7 +197,7 @@ module csr #(parameter
|
||||
assign CSRAdrM = InstrM[31:20];
|
||||
assign UnalignedNextEPCM = TrapM ? ((wfiM & IntPendingM) ? PCM+4 : PCM) : CSRWriteValM;
|
||||
assign NextEPCM = `C_SUPPORTED ? {UnalignedNextEPCM[`XLEN-1:1], 1'b0} : {UnalignedNextEPCM[`XLEN-1:2], 2'b00}; // 3.1.15 alignment
|
||||
assign NextCauseM = TrapM ? {InterruptM, {(`XLEN-`LOG_XLEN-1){1'b0}}, CauseM}: CSRWriteValM;
|
||||
assign NextCauseM = TrapM ? {InterruptM, CauseM}: {CSRWriteValM[`XLEN-1], CSRWriteValM[3:0]};
|
||||
assign NextMtvalM = TrapM ? NextFaultMtvalM : CSRWriteValM;
|
||||
assign CSRMWriteM = CSRWriteM & (PrivilegeModeW == `M_MODE);
|
||||
assign CSRSWriteM = CSRWriteM & (|PrivilegeModeW);
|
||||
|
@ -69,20 +69,21 @@ module csrm #(parameter
|
||||
DSCRATCH1 = 12'h7B3,
|
||||
// Constants
|
||||
ZERO = {(`XLEN){1'b0}},
|
||||
MEDELEG_MASK = ~(ZERO | `XLEN'b1 << 11),
|
||||
MEDELEG_MASK = 16'hB3FF,
|
||||
MIDELEG_MASK = 12'h222 // we choose to not make machine interrupts delegable
|
||||
) (
|
||||
input logic clk, reset,
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRMWriteM, MTrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
|
||||
input logic [4:0] NextCauseM,
|
||||
input logic [`XLEN-1:0] CSRWriteValM,
|
||||
input logic [11:0] MIP_REGW, MIE_REGW,
|
||||
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
|
||||
output logic [`XLEN-1:0] MEPC_REGW,
|
||||
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
|
||||
output logic [`XLEN-1:0] MEDELEG_REGW,
|
||||
output logic [15:0] MEDELEG_REGW,
|
||||
output logic [11:0] MIDELEG_REGW,
|
||||
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],
|
||||
@ -91,8 +92,7 @@ module csrm #(parameter
|
||||
);
|
||||
|
||||
logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW;
|
||||
logic [`XLEN-1:0] MSCRATCH_REGW;
|
||||
logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW;
|
||||
logic [`XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
|
||||
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
|
||||
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
|
||||
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
|
||||
@ -150,13 +150,13 @@ module csrm #(parameter
|
||||
// CSRs
|
||||
flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW);
|
||||
if (`S_SUPPORTED) begin:deleg // DELEG registers should exist
|
||||
flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK, MEDELEG_REGW);
|
||||
flopenr #(16) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM[15:0] & MEDELEG_MASK, MEDELEG_REGW);
|
||||
flopenr #(12) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM[11:0] & MIDELEG_MASK, MIDELEG_REGW);
|
||||
end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0;
|
||||
|
||||
flopenr #(`XLEN) MSCRATCHreg(clk, reset, WriteMSCRATCHM, CSRWriteValM, MSCRATCH_REGW);
|
||||
flopenr #(`XLEN) MEPCreg(clk, reset, WriteMEPCM, NextEPCM, MEPC_REGW);
|
||||
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
|
||||
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, {NextCauseM[4], {(`XLEN-5){1'b0}}, NextCauseM[3:0]}, MCAUSE_REGW);
|
||||
if(`QEMU) assign MTVAL_REGW = `XLEN'b0; // MTVAL tied to 0 in QEMU configuration
|
||||
else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
|
||||
flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW);
|
||||
@ -192,7 +192,7 @@ module csrm #(parameter
|
||||
MSTATUS: CSRMReadValM = MSTATUS_REGW;
|
||||
MSTATUSH: CSRMReadValM = MSTATUSH_REGW;
|
||||
MTVEC: CSRMReadValM = MTVEC_REGW;
|
||||
MEDELEG: CSRMReadValM = MEDELEG_REGW;
|
||||
MEDELEG: CSRMReadValM = {{(`XLEN-16){1'b0}}, MEDELEG_REGW};
|
||||
MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW};
|
||||
MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW};
|
||||
MIE: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIE_REGW};
|
||||
|
@ -48,7 +48,8 @@ module csrs #(parameter
|
||||
input logic InstrValidNotFlushedM,
|
||||
input logic CSRSWriteM, STrapM,
|
||||
input logic [11:0] CSRAdrM,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
|
||||
input logic [`XLEN-1:0] NextEPCM, NextMtvalM, SSTATUS_REGW,
|
||||
input logic [4:0] NextCauseM,
|
||||
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 [`XLEN-1:0] CSRWriteValM,
|
||||
@ -72,8 +73,7 @@ module csrs #(parameter
|
||||
logic WriteSSCRATCHM, WriteSEPCM;
|
||||
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
|
||||
logic WriteSTIMECMPM, WriteSTIMECMPHM;
|
||||
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
|
||||
logic [`XLEN-1:0] SCAUSE_REGW;
|
||||
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW;
|
||||
logic [63:0] STIMECMP_REGW;
|
||||
|
||||
// write enables
|
||||
@ -93,7 +93,7 @@ module csrs #(parameter
|
||||
flopenr #(`XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW);
|
||||
flopenr #(`XLEN) SSCRATCHreg(clk, reset, WriteSSCRATCHM, CSRWriteValM, SSCRATCH_REGW);
|
||||
flopenr #(`XLEN) SEPCreg(clk, reset, WriteSEPCM, NextEPCM, SEPC_REGW);
|
||||
flopenr #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, NextCauseM, SCAUSE_REGW);
|
||||
flopenr #(`XLEN) SCAUSEreg(clk, reset, WriteSCAUSEM, {NextCauseM[4], {(`XLEN-5){1'b0}}, NextCauseM[3:0]}, SCAUSE_REGW);
|
||||
flopenr #(`XLEN) STVALreg(clk, reset, WriteSTVALM, NextMtvalM, STVAL_REGW);
|
||||
if (`VIRTMEM_SUPPORTED)
|
||||
flopenr #(`XLEN) SATPreg(clk, reset, WriteSATPM, CSRWriteValM, SATP_REGW);
|
||||
@ -131,7 +131,7 @@ module csrs #(parameter
|
||||
SATP: if (`VIRTMEM_SUPPORTED & (PrivilegeModeW == `M_MODE | ~STATUS_TVM)) CSRSReadValM = SATP_REGW;
|
||||
else begin
|
||||
CSRSReadValM = 0;
|
||||
if (PrivilegeModeW == `S_MODE & STATUS_TVM) IllegalCSRSAccessM = 1;
|
||||
IllegalCSRSAccessM = 1;
|
||||
end
|
||||
SCOUNTEREN:CSRSReadValM = {{(`XLEN-32){1'b0}}, SCOUNTEREN_REGW};
|
||||
STIMECMP: if (`SSTC_SUPPORTED & (PrivilegeModeW == `M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[`XLEN-1:0];
|
||||
|
@ -96,8 +96,8 @@ module privileged (
|
||||
output logic WFIStallM // Stall in Memory stage for WFI until interrupt or timeout
|
||||
);
|
||||
|
||||
logic [`LOG_XLEN-1:0] CauseM; // trap cause
|
||||
logic [`XLEN-1:0] MEDELEG_REGW; // exception delegation CSR
|
||||
logic [3:0] CauseM; // trap cause
|
||||
logic [15:0] MEDELEG_REGW; // exception delegation CSR
|
||||
logic [11:0] MIDELEG_REGW; // interrupt delegation CSR
|
||||
logic sretM, mretM; // supervisor / machine return instruction
|
||||
logic IllegalCSRAccessM; // Illegal access to CSR
|
||||
|
@ -38,7 +38,7 @@ module trap (
|
||||
input logic wfiM, // wait for interrupt instruction
|
||||
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 [`XLEN-1:0] MEDELEG_REGW, // exception delegation SR
|
||||
input logic [15:0] MEDELEG_REGW, // exception delegation SR
|
||||
input logic STATUS_MIE, STATUS_SIE, // machine/supervisor interrupt enables
|
||||
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
|
||||
@ -49,7 +49,7 @@ module trap (
|
||||
output logic IntPendingM, // Interrupt is pending, might occur if enabled
|
||||
output logic DelegateM, // Delegate trap to supervisor handler
|
||||
output logic WFIStallM, // Stall due to WFI instruction
|
||||
output logic [`LOG_XLEN-1:0] CauseM // trap cause
|
||||
output logic [3:0] CauseM // trap cause
|
||||
);
|
||||
|
||||
logic MIntGlobalEnM, SIntGlobalEnM; // Global interupt enables
|
||||
@ -72,7 +72,7 @@ module trap (
|
||||
assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW);
|
||||
assign ValidIntsM = {12{~Committed}} & EnabledIntsM;
|
||||
assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request.
|
||||
assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM]) &
|
||||
assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) &
|
||||
(PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE);
|
||||
assign WFIStallM = wfiM & ~IntPendingM;
|
||||
|
||||
@ -109,7 +109,7 @@ module trap (
|
||||
else if (IllegalInstrFaultM) CauseM = 2;
|
||||
else if (InstrMisalignedFaultM) CauseM = 0;
|
||||
else if (BreakpointFaultM) CauseM = 3;
|
||||
else if (EcallFaultM) CauseM = {{(`LOG_XLEN-4){1'b0}}, {2'b10}, PrivilegeModeW};
|
||||
else if (EcallFaultM) CauseM = {2'b10, PrivilegeModeW};
|
||||
else if (LoadMisalignedFaultM) CauseM = 4;
|
||||
else if (StoreAmoMisalignedFaultM) CauseM = 6;
|
||||
else if (LoadPageFaultM) CauseM = 13;
|
||||
|
@ -41,8 +41,8 @@ module gpio_apb (
|
||||
output logic [`XLEN-1:0] PRDATA,
|
||||
output logic PREADY,
|
||||
input logic [31:0] iof0, iof1,
|
||||
input logic [31:0] GPIOPinsIn,
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn,
|
||||
input logic [31:0] GPIOIN,
|
||||
output logic [31:0] GPIOOUT, GPIOEN,
|
||||
output logic GPIOIntr
|
||||
);
|
||||
|
||||
@ -138,8 +138,8 @@ module gpio_apb (
|
||||
|
||||
// chip i/o
|
||||
// connect OUT to IN for loopback testing
|
||||
if (`GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOPinsOut) | (~output_en & GPIOPinsIn)) & input_en;
|
||||
else assign input0d = GPIOPinsIn & input_en;
|
||||
if (`GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en;
|
||||
else assign input0d = GPIOIN & input_en;
|
||||
|
||||
// synchroninzer for inputs
|
||||
flop #(32) sync1(PCLK,input0d,input1d);
|
||||
@ -148,8 +148,8 @@ module gpio_apb (
|
||||
assign input_val = input3d;
|
||||
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 GPIOPinsOut = gpio_out ^ out_xor; // per-bit flip output polarity
|
||||
assign GPIOPinsEn = output_en;
|
||||
assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity
|
||||
assign GPIOEN = output_en;
|
||||
|
||||
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)};
|
||||
endmodule
|
||||
|
@ -97,7 +97,7 @@ module plic_apb (
|
||||
// ==================
|
||||
// Register Interface
|
||||
// ==================
|
||||
always @(posedge PCLK,negedge PRESETn) begin
|
||||
always @(posedge PCLK) begin
|
||||
// resetting
|
||||
if (~PRESETn) begin
|
||||
intPriority <= #1 {`N{3'b0}};
|
||||
|
@ -109,6 +109,5 @@ module ram_ahb #(parameter BASE=0, RANGE = 65535) (
|
||||
assign DelayReady = 0;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -290,7 +290,7 @@ module uartPC16550D(
|
||||
assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time
|
||||
|
||||
// receive FIFO and register
|
||||
always_ff @(posedge PCLK, negedge PRESETn)
|
||||
always_ff @(posedge PCLK)
|
||||
if (~PRESETn) begin
|
||||
rxfifohead <= #1 0; rxfifotail <= #1 0; rxdataready <= #1 0; RXBR <= #1 0;
|
||||
end else begin
|
||||
|
@ -51,8 +51,8 @@ module uncore (
|
||||
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
|
||||
output logic MExtInt, SExtInt, // External interrupts from PLIC
|
||||
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
|
||||
input logic [31:0] GPIOPinsIn, // GPIO pin input value
|
||||
output logic [31:0] GPIOPinsOut, GPIOPinsEn, // GPIO pin output value and enable
|
||||
input logic [31:0] GPIOIN, // GPIO pin input value
|
||||
output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable
|
||||
input logic UARTSin, // UART serial input
|
||||
output logic UARTSout, // UART serial output
|
||||
output logic SDCCmdOut, // SD Card command output
|
||||
@ -133,9 +133,9 @@ module uncore (
|
||||
gpio_apb gpio(
|
||||
.PCLK, .PRESETn, .PSEL(PSEL[0]), .PADDR(PADDR[7:0]), .PWDATA, .PSTRB, .PWRITE, .PENABLE,
|
||||
.PRDATA(PRDATA[0]), .PREADY(PREADY[0]),
|
||||
.iof0(), .iof1(), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn, .GPIOIntr);
|
||||
.iof0(), .iof1(), .GPIOIN, .GPIOOUT, .GPIOEN, .GPIOIntr);
|
||||
end else begin : gpio
|
||||
assign GPIOPinsOut = 0; assign GPIOPinsEn = 0; assign GPIOIntr = 0;
|
||||
assign GPIOOUT = 0; assign GPIOEN = 0; assign GPIOIntr = 0;
|
||||
end
|
||||
if (`UART_SUPPORTED == 1) begin : uart
|
||||
uart_apb uart(
|
||||
|
@ -247,20 +247,10 @@ module wallypipelinedcore (
|
||||
ebu ebu(// IFU connections
|
||||
.clk, .reset,
|
||||
// IFU interface
|
||||
.IFUHADDR,
|
||||
.IFUHBURST,
|
||||
.IFUHTRANS,
|
||||
.IFUHREADY,
|
||||
.IFUHSIZE,
|
||||
.IFUHADDR, .IFUHBURST, .IFUHTRANS, .IFUHREADY, .IFUHSIZE,
|
||||
// LSU interface
|
||||
.LSUHADDR,
|
||||
.LSUHWDATA,
|
||||
.LSUHWSTRB,
|
||||
.LSUHSIZE,
|
||||
.LSUHBURST,
|
||||
.LSUHTRANS,
|
||||
.LSUHWRITE,
|
||||
.LSUHREADY,
|
||||
.LSUHADDR, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE, .LSUHBURST,
|
||||
.LSUHTRANS, .LSUHWRITE, .LSUHREADY,
|
||||
// BUS interface
|
||||
.HREADY, .HRESP, .HCLK, .HRESETn,
|
||||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST,
|
||||
|
@ -51,9 +51,9 @@ module wallypipelinedsoc (
|
||||
output logic HREADY,
|
||||
// I/O Interface
|
||||
input logic TIMECLK, // optional for CLINT MTIME counter
|
||||
input logic [31:0] GPIOPinsIn, // inputs from GPIO
|
||||
output logic [31:0] GPIOPinsOut, // output values for GPIO
|
||||
output logic [31:0] GPIOPinsEn, // output enables for GPIO
|
||||
input logic [31:0] GPIOIN, // inputs from GPIO
|
||||
output logic [31:0] GPIOOUT, // output values for GPIO
|
||||
output logic [31:0] GPIOEN, // output enables for GPIO
|
||||
input logic UARTSin, // UART serial data input
|
||||
output logic UARTSout, // UART serial data output
|
||||
input logic SDCCmdIn, // SDC Command input
|
||||
@ -66,7 +66,7 @@ module wallypipelinedsoc (
|
||||
// Uncore signals
|
||||
logic [`AHBW-1:0] HRDATA; // from AHB mux in uncore
|
||||
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 MExtInt,SExtInt; // from PLIC
|
||||
|
||||
@ -85,7 +85,7 @@ module wallypipelinedsoc (
|
||||
uncore uncore(.HCLK, .HRESETn, .TIMECLK,
|
||||
.HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HRDATAEXT,
|
||||
.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,
|
||||
.SDCCmdOut, .SDCCmdOE, .SDCCmdIn, .SDCDatIn, .SDCCLK);
|
||||
end
|
||||
|
@ -90,6 +90,7 @@ module wallyTracer(rvviTrace rvvi);
|
||||
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
|
||||
|
||||
logic valid;
|
||||
int csrid;
|
||||
|
||||
always_comb begin
|
||||
// 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;
|
||||
|
||||
csrid = 12'h3A0 + i4;
|
||||
//if (CSRArray[csrid] != pmp) $display("Info: %m pmpcfg%0d [%03X] %016X -> %016X", i4, csrid, CSRArray[csrid], pmp);
|
||||
CSRArray[csrid] = pmp;
|
||||
end
|
||||
|
||||
@ -125,7 +125,6 @@ module wallyTracer(rvviTrace rvvi);
|
||||
pmp = testbench.dut.core.priv.priv.csr.csrm.PMPADDR_ARRAY_REGW[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;
|
||||
end
|
||||
|
||||
@ -167,7 +166,17 @@ module wallyTracer(rvviTrace rvvi);
|
||||
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'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.
|
||||
|
||||
// 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'h310] = CSRArrayOld[12'h310];
|
||||
CSRArray[12'h305] = CSRArrayOld[12'h305];
|
||||
@ -286,26 +295,176 @@ module wallyTracer(rvviTrace rvvi);
|
||||
// record previous csr value.
|
||||
integer index4;
|
||||
always_ff @(posedge clk) begin
|
||||
for (index4 = 0; index4 < `NUM_CSRS; index4 += 1) begin
|
||||
// IMPERAS
|
||||
//CSR_W[index4] = (CSRArrayOld[index4] != CSRArray[index4]) ? 1 : 0;
|
||||
CSRArrayOld[12'h300] = CSRArray[12'h300];
|
||||
CSRArrayOld[12'h310] = CSRArray[12'h310];
|
||||
CSRArrayOld[12'h305] = CSRArray[12'h305];
|
||||
CSRArrayOld[12'h341] = CSRArray[12'h341];
|
||||
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.
|
||||
genvar index5;
|
||||
for(index5 = 0; index5 < `NUM_CSRS; index5 += 1) begin
|
||||
// CSR_W should only indicate the change when the Writeback stage is not stalled and valid.
|
||||
assign #2 CSR_W[index5] = (CSRArrayOld[index5] != CSRArray[index5]) ? 1 : 0;
|
||||
assign rvvi.csr_wb[0][0][index5] = CSR_W[index5];
|
||||
assign rvvi.csr[0][0][index5] = CSRArray[index5];
|
||||
assign #2 CSR_W[12'h300] = (CSRArrayOld[12'h300] != CSRArray[12'h300]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h310] = (CSRArrayOld[12'h310] != CSRArray[12'h310]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h305] = (CSRArrayOld[12'h305] != CSRArray[12'h305]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h341] = (CSRArrayOld[12'h341] != CSRArray[12'h341]) ? 1 : 0;
|
||||
assign #2 CSR_W[12'h306] = (CSRArrayOld[12'h306] != CSRArray[12'h306]) ? 1 : 0;
|
||||
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
|
||||
|
||||
// always @rvvi.clk $display("%t @rvvi.clk=%X", $time, rvvi.clk);
|
||||
// always @rvvi.csr[0][0]['h300] $display("%t rvvi.csr[0][0]['h300]=%X", $time, rvvi.csr[0][0]['h300]);
|
||||
// always @rvvi.csr_wb[0][0]['h300] $display("%t rvvi.csr_wb[0][0]['h300]=%X", $time, rvvi.csr_wb[0][0]['h300]);
|
||||
// always @rvvi.valid[0][0] $display("%t rvvi.valid[0][0]=%X", $time, rvvi.valid[0][0]);
|
||||
// PMP ADDR 3B0 to 3EF
|
||||
for(index='h3B0; index<='h3EF; 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
|
||||
|
||||
// *** implementation only cancel? so sc does not clear?
|
||||
assign rvvi.lrsc_cancel[0][0] = '0;
|
||||
|
@ -702,7 +702,7 @@ module testbenchfp;
|
||||
|
||||
if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt
|
||||
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));
|
||||
end
|
||||
|
||||
|
1030
testbench/testbench-linux-imperas.sv
Normal file
1030
testbench/testbench-linux-imperas.sv
Normal file
File diff suppressed because it is too large
Load Diff
@ -252,8 +252,8 @@ module testbench;
|
||||
logic [3:0] HPROT;
|
||||
logic [1:0] HTRANS;
|
||||
logic HMASTLOCK;
|
||||
logic [31:0] GPIOPinsIn;
|
||||
logic [31:0] GPIOPinsOut, GPIOPinsEn;
|
||||
logic [31:0] GPIOIN;
|
||||
logic [31:0] GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
|
||||
// FPGA-specific Stuff
|
||||
@ -264,7 +264,7 @@ module testbench;
|
||||
logic [3:0] SDCDatIn;
|
||||
|
||||
// Hardwire UART, GPIO pins
|
||||
assign GPIOPinsIn = 0;
|
||||
assign GPIOIN = 0;
|
||||
assign UARTSin = 1;
|
||||
|
||||
// Wally
|
||||
@ -272,7 +272,7 @@ module testbench;
|
||||
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK,
|
||||
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HWSTRB, .HSIZE, .HBURST, .HPROT,
|
||||
.HTRANS, .HMASTLOCK,
|
||||
.TIMECLK('0), .GPIOPinsIn, .GPIOPinsOut, .GPIOPinsEn,
|
||||
.TIMECLK('0), .GPIOIN, .GPIOOUT, .GPIOEN,
|
||||
.UARTSin, .UARTSout,
|
||||
.SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn);
|
||||
|
||||
|
@ -28,8 +28,10 @@
|
||||
`include "wally-config.vh"
|
||||
`include "tests.vh"
|
||||
|
||||
`define PrintHPMCounters 1
|
||||
`define BPRED_LOGGER 1
|
||||
`define PrintHPMCounters 0
|
||||
`define BPRED_LOGGER 0
|
||||
`define I_CACHE_ADDR_LOGGER 0
|
||||
`define D_CACHE_ADDR_LOGGER 0
|
||||
|
||||
module testbench;
|
||||
parameter DEBUG=0;
|
||||
@ -150,7 +152,7 @@ logic [3:0] dummy;
|
||||
string signame, memfilename, pathname, objdumpfilename, adrstr, outputfile;
|
||||
integer outputFilePointer;
|
||||
|
||||
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
|
||||
logic [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
|
||||
logic SDCCLK;
|
||||
@ -167,9 +169,10 @@ logic [3:0] dummy;
|
||||
logic InitializingMemories;
|
||||
integer ResetCount, ResetThreshold;
|
||||
logic InReset;
|
||||
logic Begin;
|
||||
|
||||
// instantiate device to be tested
|
||||
assign GPIOPinsIn = 0;
|
||||
assign GPIOIN = 0;
|
||||
assign UARTSin = 1;
|
||||
|
||||
if(`EXT_MEM_SUPPORTED) begin
|
||||
@ -199,7 +202,7 @@ logic [3:0] dummy;
|
||||
|
||||
wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
.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);
|
||||
|
||||
// Track names of instructions
|
||||
@ -415,7 +418,7 @@ logic [3:0] dummy;
|
||||
if(`PrintHPMCounters & `ZICOUNTERS_SUPPORTED) begin : HPMCSample
|
||||
integer HPMCindex;
|
||||
logic StartSampleFirst;
|
||||
logic StartSampleDelayed;
|
||||
logic StartSampleDelayed, BeginDelayed;
|
||||
logic EndSampleFirst, EndSampleDelayed;
|
||||
logic [`XLEN-1:0] InitialHPMCOUNTERH[`COUNTERS-1:0];
|
||||
|
||||
@ -474,8 +477,11 @@ logic [3:0] dummy;
|
||||
assign StartSampleFirst = InReset;
|
||||
flopr #(1) StartSampleReg(clk, reset, StartSampleFirst, StartSampleDelayed);
|
||||
assign StartSample = StartSampleFirst & ~ StartSampleDelayed;
|
||||
|
||||
assign EndSample = DCacheFlushStart & ~DCacheFlushDone;
|
||||
|
||||
flop #(1) BeginReg(clk, StartSampleFirst, BeginDelayed);
|
||||
assign Begin = StartSampleFirst & ~ BeginDelayed;
|
||||
|
||||
end
|
||||
|
||||
always @(negedge clk) begin
|
||||
@ -526,7 +532,7 @@ logic [3:0] dummy;
|
||||
|
||||
|
||||
// initialize the branch predictor
|
||||
if (`BPRED_SUPPORTED == 1) begin
|
||||
if (`BPRED_SUPPORTED) begin
|
||||
integer adrindex;
|
||||
|
||||
always @(*) begin
|
||||
@ -546,10 +552,66 @@ logic [3:0] dummy;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (`ICACHE_SUPPORTED && `I_CACHE_ADDR_LOGGER) begin
|
||||
int file;
|
||||
string LogFile;
|
||||
logic resetD, resetEdge;
|
||||
logic Enable;
|
||||
assign Enable = ~dut.core.StallD & ~dut.core.FlushD & dut.core.ifu.bus.icache.CacheRWF[1] & ~reset;
|
||||
flop #(1) ResetDReg(clk, reset, resetD);
|
||||
assign resetEdge = ~reset & resetD;
|
||||
initial begin
|
||||
LogFile = $psprintf("ICache.log");
|
||||
file = $fopen(LogFile, "w");
|
||||
$fwrite(file, "BEGIN %s\n", memfilename);
|
||||
end
|
||||
string HitMissString;
|
||||
assign HitMissString = dut.core.ifu.bus.icache.icache.CacheHit ? "H" : "M";
|
||||
always @(posedge clk) begin
|
||||
if(resetEdge) $fwrite(file, "TRAIN\n");
|
||||
if(Begin) $fwrite(file, "BEGIN %s\n", memfilename);
|
||||
if(Enable) begin // only log i cache reads
|
||||
$fwrite(file, "%h R %s\n", dut.core.ifu.PCPF, HitMissString);
|
||||
end
|
||||
if(EndSample) $fwrite(file, "END %s\n", memfilename);
|
||||
end
|
||||
end
|
||||
|
||||
if (`DCACHE_SUPPORTED && `D_CACHE_ADDR_LOGGER) begin
|
||||
int file;
|
||||
string LogFile;
|
||||
logic resetD, resetEdge;
|
||||
string HitMissString;
|
||||
flop #(1) ResetDReg(clk, reset, resetD);
|
||||
assign resetEdge = ~reset & resetD;
|
||||
assign HitMissString = dut.core.lsu.bus.dcache.dcache.CacheHit ? "H" : "M";
|
||||
initial begin
|
||||
LogFile = $psprintf("DCache.log");
|
||||
file = $fopen(LogFile, "w");
|
||||
$fwrite(file, "BEGIN %s\n", memfilename);
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
if(resetEdge) $fwrite(file, "TRAIN\n");
|
||||
if(Begin) $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 %s\n", dut.core.lsu.PAdrM, HitMissString);
|
||||
end else if (dut.core.lsu.bus.dcache.CacheRWM == 2'b01) begin
|
||||
$fwrite(file, "%h W %s\n", dut.core.lsu.PAdrM, HitMissString);
|
||||
end else if (dut.core.lsu.bus.dcache.CacheAtomicM[1] == 1'b1) begin // *** This may change
|
||||
$fwrite(file, "%h A %s\n", dut.core.lsu.PAdrM, HitMissString);
|
||||
end else if (dut.core.lsu.bus.dcache.FlushDCache) begin
|
||||
$fwrite(file, "%h F %s\n", dut.core.lsu.PAdrM, HitMissString);
|
||||
end
|
||||
end
|
||||
if(EndSample) $fwrite(file, "END %s\n", memfilename);
|
||||
end
|
||||
end
|
||||
|
||||
if (`BPRED_SUPPORTED == 1) begin
|
||||
if (`BPRED_SUPPORTED) begin
|
||||
if (`BPRED_LOGGER) begin
|
||||
string direction;
|
||||
int file;
|
||||
|
@ -73,7 +73,7 @@ module testbench;
|
||||
string testName;
|
||||
string memfilename, testDir, adrstr, elffilename;
|
||||
|
||||
logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn;
|
||||
logic [31:0] GPIOIN, GPIOOUT, GPIOEN;
|
||||
logic UARTSin, UARTSout;
|
||||
|
||||
logic SDCCLK;
|
||||
@ -217,7 +217,7 @@ module testbench;
|
||||
|
||||
|
||||
// instantiate device to be tested
|
||||
assign GPIOPinsIn = 0;
|
||||
assign GPIOIN = 0;
|
||||
assign UARTSin = 1;
|
||||
|
||||
if(`EXT_MEM_SUPPORTED) begin
|
||||
@ -247,7 +247,7 @@ module testbench;
|
||||
|
||||
wallypipelinedsoc dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT,
|
||||
.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);
|
||||
|
||||
// Track names of instructions
|
||||
|
@ -24,7 +24,7 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define PATH "../../tests/fp/vectors/"
|
||||
`define PATH "../tests/fp/vectors/"
|
||||
`define ADD_OPCTRL 3'b110
|
||||
`define MUL_OPCTRL 3'b100
|
||||
`define SUB_OPCTRL 3'b111
|
||||
|
@ -46,7 +46,10 @@ string tvpaths[] = '{
|
||||
`COVERAGE,
|
||||
"ieu",
|
||||
"ebu",
|
||||
"csrwrites"
|
||||
"csrwrites",
|
||||
"priv",
|
||||
"ifu",
|
||||
"fpu"
|
||||
};
|
||||
|
||||
string coremark[] = '{
|
||||
@ -1852,7 +1855,6 @@ string arch64zbs[] = '{
|
||||
|
||||
string wally64priv[] = '{
|
||||
`WALLYTEST,
|
||||
// "rv64i_m/privilege/src/BUG66",
|
||||
"rv64i_m/privilege/src/WALLY-csr-permission-s-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-csr-permission-u-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-mie-01.S",
|
||||
@ -1863,15 +1865,15 @@ string arch64zbs[] = '{
|
||||
"rv64i_m/privilege/src/WALLY-mtvec-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-pma-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-pmp-01.S",
|
||||
// "rv64i_m/privilege/src/WALLY-sie-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-sie-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-status-mie-01.S",
|
||||
// "rv64i_m/privilege/src/WALLY-status-sie-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-status-sie-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-status-tw-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-status-tvm-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-status-fp-enabled-01.S",
|
||||
// "rv64i_m/privilege/src/WALLY-stvec-01.S",
|
||||
// "rv64i_m/privilege/src/WALLY-trap-01.S",
|
||||
// "rv64i_m/privilege/src/WALLY-trap-s-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-stvec-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-trap-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-trap-s-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-trap-sret-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-trap-u-01.S",
|
||||
"rv64i_m/privilege/src/WALLY-wfi-01.S",
|
||||
@ -1951,30 +1953,32 @@ string arch64zbs[] = '{
|
||||
"rv32i_m/privilege/src/WALLY-mtvec-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-pma-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-pmp-01.S",
|
||||
// "rv32i_m/privilege/src/WALLY-sie-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-sie-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-status-mie-01.S",
|
||||
// "rv32i_m/privilege/src/WALLY-status-sie-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-status-sie-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-status-tw-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-status-tvm-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-status-fp-enabled-01.S",
|
||||
// "rv32i_m/privilege/src/WALLY-stvec-01.S",
|
||||
// "rv32i_m/privilege/src/WALLY-trap-01.S",
|
||||
// "rv32i_m/privilege/src/WALLY-trap-s-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-stvec-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-trap-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-trap-s-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-trap-sret-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-trap-u-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-wfi-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-endianness-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-satp-invalid-01.S"
|
||||
};
|
||||
|
||||
string wally32periph[] = '{
|
||||
`WALLYTEST,
|
||||
"rv32i_m/privilege/src/WALLY-periph-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-satp-invalid-01.S",
|
||||
// These peripherals are here instead of wally32periph because they don't work on rv32imc, which lacks a PMP register to configure
|
||||
"rv32i_m/privilege/src/WALLY-gpio-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-clint-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-uart-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-plic-01.S",
|
||||
"rv32i_m/privilege/src/WALLY-plic-s-01.S"
|
||||
|
||||
};
|
||||
|
||||
string wally32periph[] = '{
|
||||
`WALLYTEST,
|
||||
"rv32i_m/privilege/src/WALLY-periph-01.S"
|
||||
};
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ all: $(OBJECTS)
|
||||
|
||||
# Change many things if bit width isn't 64
|
||||
%.elf: $(SRCDIR)/%.$(SEXT) WALLY-init-lib.h Makefile
|
||||
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gc_zba_zbb_zbc_zbs -mabi=lp64 -mcmodel=medany \
|
||||
riscv64-unknown-elf-gcc -g -o $@ -march=rv64gqc_zba_zbb_zbc_zbs_zfh -mabi=lp64 -mcmodel=medany \
|
||||
-nostartfiles -T../../examples/link/link.ld $<
|
||||
riscv64-unknown-elf-objdump -S $@ > $@.objdump
|
||||
riscv64-unknown-elf-elf2hex --bit-width 64 --input $@ --output $@.memfile
|
||||
|
@ -40,6 +40,10 @@ rvtest_entry_point:
|
||||
la t0, topoftrapstack
|
||||
csrw mscratch, t0 # MSCRATCH holds trap stack pointer
|
||||
csrsi mstatus, 0x8 # Turn on mstatus.MIE global interrupt enable
|
||||
# set up PMP so user and supervisor mode can access full address space
|
||||
csrw pmpcfg0, 0xF # configure PMP0 to TOR RWX
|
||||
li t0, 0xFFFFFFFF
|
||||
csrw pmpaddr0, t0 # configure PMP0 top of range to 0xFFFFFFFF to allow all 32-bit addresses
|
||||
j main # Call main function in user test program
|
||||
|
||||
done:
|
||||
|
72
tests/coverage/fpu.S
Normal file
72
tests/coverage/fpu.S
Normal file
@ -0,0 +1,72 @@
|
||||
///////////////////////////////////////////
|
||||
// fpu.S
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 28 March 2023
|
||||
//
|
||||
// Purpose: Test coverage for FPU
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// load code to initalize stack, handle interrupts, terminate
|
||||
#include "WALLY-init-lib.h"
|
||||
|
||||
main:
|
||||
|
||||
bseti t0, zero, 14 # turn on FPU
|
||||
csrs mstatus, t0
|
||||
|
||||
# Test legal instructions not covered elsewhere
|
||||
flq ft0, 0(a0)
|
||||
flh ft0, 8(a0)
|
||||
fsq ft0, 0(a0)
|
||||
fsh ft0, 8(a0)
|
||||
fcvt.h.s ft1, ft0
|
||||
fcvt.q.s ft2, ft0
|
||||
fcvt.h.w ft3, a0
|
||||
fcvt.h.wu ft3, a0
|
||||
fcvt.h.l ft3, a0
|
||||
fcvt.h.lu ft3, a0
|
||||
fcvt.w.h a0, ft3
|
||||
fcvt.wu.h a0, ft3
|
||||
fcvt.l.h a0, ft3
|
||||
fcvt.lu.h a0, ft3
|
||||
fcvt.q.w ft3, a0
|
||||
fcvt.q.wu ft3, a0
|
||||
fcvt.q.l ft3, a0
|
||||
fcvt.q.lu ft3, a0
|
||||
fcvt.w.q a0, ft3
|
||||
fcvt.wu.q a0, ft3
|
||||
fcvt.l.q a0, ft3
|
||||
fcvt.lu.q a0, ft3
|
||||
|
||||
|
||||
# Test illegal instructions are detected
|
||||
.word 0x00000007 // illegal floating-point load (bad Funct3)
|
||||
.word 0x00000027 // illegal floating-point store (bad Funct3)
|
||||
.word 0x58F00053 // illegal fsqrt (bad Rs2D)
|
||||
.word 0x20007053 // illegal fsgnj (bad Funct3)
|
||||
.word 0x28007053 // illegal fmin/max (bad Funct3)
|
||||
.word 0xA0007053 // illegal fcmp (bad Funct3)
|
||||
.word 0xE0007053 // illegal fclass/fmv (bad Funct3)
|
||||
.word 0xF0007053 // illegal fmv (bad Funct3)
|
||||
.word 0x43007053 // illegal fcvt.d.* (bad Rs2D)
|
||||
.word 0x42207053 // illegal fcvt.d.* (bad Rs2D[1])
|
||||
|
||||
j done
|
||||
|
40
tests/coverage/ifu.S
Normal file
40
tests/coverage/ifu.S
Normal file
@ -0,0 +1,40 @@
|
||||
///////////////////////////////////////////
|
||||
// ifu.S
|
||||
//
|
||||
// Written: sriley@g.hmc.edu 28 March 2023
|
||||
//
|
||||
// Purpose: Test coverage for IFU
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// load code to initalize stack, handle interrupts, terminate
|
||||
#include "WALLY-init-lib.h"
|
||||
|
||||
main:
|
||||
# turn floating point on
|
||||
li t0, 0x2000
|
||||
csrs mstatus, t0
|
||||
|
||||
# calling compressed floating point load double instruction
|
||||
//.halfword 0x2000 // CL type compressed floating-point ld-->funct3,imm,rs1',imm,rd',op
|
||||
// binary version 0000 0000 0000 0000 0010 0000 0000 0000
|
||||
mv s0, sp
|
||||
c.fld fs0, 0(s0)
|
||||
|
||||
j done
|
39
tests/coverage/priv.S
Normal file
39
tests/coverage/priv.S
Normal file
@ -0,0 +1,39 @@
|
||||
///////////////////////////////////////////
|
||||
// priv.S
|
||||
//
|
||||
// Written: David_Harris@hmc.edu 23 March 2023
|
||||
//
|
||||
// Purpose: Test coverage for EBU
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// load code to initalize stack, handle interrupts, terminate
|
||||
#include "WALLY-init-lib.h"
|
||||
|
||||
main:
|
||||
|
||||
# switch to supervisor mode
|
||||
li a0, 1
|
||||
ecall
|
||||
|
||||
# Test read to stimecmp fails when MCOUNTEREN_TM is not set
|
||||
addi t0, zero, 0
|
||||
csrr t0, stimecmp
|
||||
|
||||
j done
|
@ -6,16 +6,16 @@
|
||||
00000000 # mtval of faulting instruction (0x0)
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000003 # mcause from Breakpoint
|
||||
8000015c # mtval of breakpoint instruction adress
|
||||
80000168 # mtval of breakpoint instruction adress
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000004 # mcause from load address misaligned
|
||||
80000165 # mtval of misaligned address
|
||||
80000171 # mtval of misaligned address
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000005 # mcause from load access
|
||||
00000000 # mtval of accessed adress (0x0)
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000006 # mcause from store misaligned
|
||||
8000017d # mtval of address with misaligned store instr
|
||||
80000189 # mtval of address with misaligned store instr
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000007 # mcause from store access
|
||||
00000000 # mtval of accessed address (0x0)
|
||||
@ -53,7 +53,7 @@
|
||||
8000000b # mcause value from m ext interrupt
|
||||
00000000 # mtval for mext interrupt (0x0)
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable) # skipping instruction address fault since they're impossible with compressed instrs enabled
|
||||
00000001 # mcause from an instruction access fault
|
||||
00000000 # mtval of faulting instruction address (0x0)
|
||||
@ -62,16 +62,16 @@ fffff7ff # medeleg after attempted write of all 1's (only some bits are writeabl
|
||||
00000000 # mtval of faulting instruction (0x0)
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000003 # mcause from Breakpoint
|
||||
8000015c # mtval of breakpoint instruction adress
|
||||
80000168 # mtval of breakpoint instruction adress
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000004 # mcause from load address misaligned
|
||||
80000165 # mtval of misaligned address
|
||||
80000171 # mtval of misaligned address
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000005 # mcause from load access
|
||||
00000000 # mtval of accessed adress (0x0)
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000006 # mcause from store misaligned
|
||||
8000017d # mtval of address with misaligned store instr
|
||||
80000189 # mtval of address with misaligned store instr
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000007 # mcause from store access
|
||||
00000000 # mtval of accessed address (0x0)
|
||||
|
@ -9,16 +9,16 @@
|
||||
00000000 # stval of faulting instruction (0x0)
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000003 # scause from Breakpoint
|
||||
8000015c # stval of breakpoint instruction adress
|
||||
80000168 # stval of breakpoint instruction adress
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000004 # scause from load address misaligned
|
||||
80000165 # stval of misaligned address
|
||||
80000171 # stval of misaligned address
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000005 # scause from load access
|
||||
00000000 # stval of accessed adress (0x0)
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000006 # scause from store misaligned
|
||||
8000017d # stval of address with misaligned store instr
|
||||
80000189 # stval of address with misaligned store instr
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000007 # scause from store access
|
||||
00000000 # stval of accessed address (0x0)
|
||||
@ -29,10 +29,6 @@
|
||||
00000008 # scause from U mode ecall
|
||||
00000000 # stval of ecall (*** defined to be zero for now)
|
||||
00000000 # masked out mstatus.mpp = 0 (from U mode), mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
0007ec01 # value to indicate successful vectoring on s soft interrupt
|
||||
80000001 # scause value from s soft interrupt
|
||||
00000000 # stval for ssoft interrupt (0x0)
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
0007ec03 # value to indicate successful vectoring on m soft interrupt
|
||||
80000003 # scause value from m soft interrupt
|
||||
00000000 # stval for msoft interrupt (0x0)
|
||||
@ -52,7 +48,7 @@
|
||||
00000009 # scause from S mode ecall
|
||||
00000000 # stval of ecall (*** defined to be zero for now)
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
|
||||
0000000b # scause from M mode ecall
|
||||
00000000 # stval of ecall (*** defined to be zero for now)
|
||||
@ -64,16 +60,16 @@ fffff7ff # medeleg after attempted write of all 1's (only some bits are writeabl
|
||||
00000000 # stval of faulting instruction (0x0)
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000003 # scause from Breakpoint
|
||||
8000015c # stval of breakpoint instruction adress
|
||||
80000168 # stval of breakpoint instruction adress
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000004 # scause from load address misaligned
|
||||
80000165 # stval of misaligned address
|
||||
80000171 # stval of misaligned address
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000005 # scause from load access
|
||||
00000000 # stval of accessed adress (0x0)
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000006 # scause from store misaligned
|
||||
8000017d # stval of address with misaligned store instr
|
||||
80000189 # stval of address with misaligned store instr
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000007 # scause from store access
|
||||
00000000 # stval of accessed address (0x0)
|
||||
|
@ -9,16 +9,16 @@
|
||||
00000000 # stval of faulting instruction (0x0)
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000003 # scause from Breakpoint
|
||||
8000015c # stval of breakpoint instruction adress
|
||||
80000168 # stval of breakpoint instruction adress
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000004 # scause from load address misaligned
|
||||
80000165 # stval of misaligned address
|
||||
80000171 # stval of misaligned address
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000005 # scause from load access
|
||||
00000000 # stval of accessed adress (0x0)
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000006 # scause from store misaligned
|
||||
8000017d # stval of address with misaligned store instr
|
||||
80000189 # stval of address with misaligned store instr
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000007 # scause from store access
|
||||
00000000 # stval of accessed address (0x0)
|
||||
@ -45,7 +45,7 @@
|
||||
00000008 # scause from U mode ecall
|
||||
00000000 # stval of ecall (*** defined to be zero for now)
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
|
||||
0000000b # scause from M mode ecall
|
||||
00000000 # stval of ecall (*** defined to be zero for now)
|
||||
@ -57,16 +57,16 @@ fffff7ff # medeleg after attempted write of all 1's (only some bits are writeabl
|
||||
00000000 # stval of faulting instruction (0x0)
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000003 # scause from Breakpoint
|
||||
8000015c # stval of breakpoint instruction adress
|
||||
80000168 # stval of breakpoint instruction adress
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000004 # scause from load address misaligned
|
||||
80000165 # stval of misaligned address
|
||||
80000171 # stval of misaligned address
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000005 # scause from load access
|
||||
00000000 # stval of accessed adress (0x0)
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000006 # scause from store misaligned
|
||||
8000017d # stval of address with misaligned store instr
|
||||
80000189 # stval of address with misaligned store instr
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000007 # scause from store access
|
||||
00000000 # stval of accessed address (0x0)
|
||||
|
@ -55,6 +55,12 @@ RVTEST_CODE_BEGIN
|
||||
csrw sscratch, sp
|
||||
la sp, stack_top
|
||||
|
||||
// set up PMP so user and supervisor mode can access full address space
|
||||
csrw pmpcfg0, 0xF # configure PMP0 to TOR RWX
|
||||
li t0, 0xFFFFFFFF
|
||||
csrw pmpaddr0, t0 # configure PMP0 top of range to 0xFFFFFFFF to allow all 32-bit addresses
|
||||
|
||||
|
||||
.endm
|
||||
|
||||
// Code to trigger traps goes here so we have consistent mtvals for instruction adresses
|
||||
|
@ -57,12 +57,12 @@ GOTO_U_MODE // Causes S mode ecall
|
||||
GOTO_S_MODE // Causes U mode ecall
|
||||
|
||||
|
||||
// some interrupts excluded becaus writing MIP is illegal from S mode
|
||||
jal cause_s_soft_interrupt
|
||||
// some interrupts excluded because writing MIP is illegal from S mode and writing SIP is only possible when delegated, which is tested below (priv spec 3.1.9)
|
||||
//jal cause_s_soft_interrupt
|
||||
jal cause_m_soft_interrupt
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // this interrupt involves a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled,
|
||||
// since interrupts are not always enabled, we need to make it stop after a certain number of loops, which is the number in a3
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
li a3, 0x40
|
||||
jal cause_m_ext_interrupt
|
||||
|
@ -14,13 +14,13 @@
|
||||
00000000
|
||||
00000003 # mcause from Breakpoint
|
||||
00000000
|
||||
800003f4 # mtval of breakpoint instruction adress (0x80000400)
|
||||
80000408 # mtval of breakpoint instruction adress (0x80000400)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000004 # mcause from load address misaligned
|
||||
00000000
|
||||
800003fd # mtval of misaligned address (0x80000409)
|
||||
80000411 # mtval of misaligned address (0x80000409)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -32,7 +32,7 @@
|
||||
00000000
|
||||
00000006 # mcause from store misaligned
|
||||
00000000
|
||||
80000415 # mtval of address with misaligned store instr (0x80000421)
|
||||
80000429 # mtval of address with misaligned store instr (0x80000421)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -108,8 +108,8 @@
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
ffffffff
|
||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000
|
||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled
|
||||
00000001 # mcause from an instruction access fault
|
||||
@ -126,13 +126,13 @@ ffffffff
|
||||
00000000
|
||||
00000003 # mcause from Breakpoint
|
||||
00000000
|
||||
800003f4 # mtval of breakpoint instruction adress (0x80000400)
|
||||
80000408 # mtval of breakpoint instruction adress (0x80000400)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000004 # mcause from load address misaligned
|
||||
00000000
|
||||
800003fd # mtval of misaligned address (0x80000409)
|
||||
80000411 # mtval of misaligned address (0x80000409)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -144,7 +144,7 @@ ffffffff
|
||||
00000000
|
||||
00000006 # mcause from store misaligned
|
||||
00000000
|
||||
80000415 # mtval of address with misaligned store instr (0x80000421)
|
||||
80000429 # mtval of address with misaligned store instr (0x80000421)
|
||||
00000000
|
||||
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
|
||||
00000000
|
||||
|
@ -20,13 +20,13 @@
|
||||
00000000
|
||||
00000003 # scause from Breakpoint
|
||||
00000000
|
||||
800003f4 # stval of breakpoint instruction adress (0x80000400)
|
||||
80000408 # stval of breakpoint instruction adress (0x80000400)
|
||||
00000000
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000004 # scause from load address misaligned
|
||||
00000000
|
||||
800003fd # stval of misaligned address (0x80000409)
|
||||
80000411 # stval of misaligned address (0x80000409)
|
||||
00000000
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -38,7 +38,7 @@
|
||||
00000000
|
||||
00000006 # scause from store misaligned
|
||||
00000000
|
||||
80000415 # stval of address with misaligned store instr (0x80000421)
|
||||
80000429 # stval of address with misaligned store instr (0x80000421)
|
||||
00000000
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -60,14 +60,6 @@
|
||||
00000000
|
||||
00000000 # masked out mstatus.mpp = 0 (from U mode), mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
0007ec01 # value to indicate successful vectoring on s soft interrupt
|
||||
00000000
|
||||
00000001 # scause value from s soft interrupt
|
||||
80000000
|
||||
00000000 # stval for ssoft interrupt (0x0)
|
||||
00000000
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
0007ec03 # value to indicate successful vectoring on m soft interrupt
|
||||
00000000
|
||||
00000003 # scause value from m soft interrupt
|
||||
@ -106,8 +98,8 @@
|
||||
00000000
|
||||
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
ffffffff
|
||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000
|
||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000
|
||||
0000000b # scause from M mode ecall
|
||||
@ -130,13 +122,13 @@ ffffffff
|
||||
00000000
|
||||
00000003 # scause from Breakpoint
|
||||
00000000
|
||||
800003f4 # stval of breakpoint instruction adress (0x80000400)
|
||||
80000408 # stval of breakpoint instruction adress (0x80000400)
|
||||
00000000
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000000
|
||||
00000004 # scause from load address misaligned
|
||||
00000000
|
||||
800003fd # stval of misaligned address (0x80000409)
|
||||
80000411 # stval of misaligned address (0x80000409)
|
||||
00000000
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000000
|
||||
@ -148,7 +140,7 @@ ffffffff
|
||||
00000000
|
||||
00000006 # scause from store misaligned
|
||||
00000000
|
||||
80000415 # stval of address with misaligned store instr (0x80000421)
|
||||
80000429 # stval of address with misaligned store instr (0x80000421)
|
||||
00000000
|
||||
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000000
|
||||
|
@ -20,13 +20,13 @@
|
||||
00000000
|
||||
00000003 # scause from Breakpoint
|
||||
00000000
|
||||
800003f4 # stval of breakpoint instruction adress (0x80000400)
|
||||
80000408 # stval of breakpoint instruction adress (0x80000400)
|
||||
00000000
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
00000004 # scause from load address misaligned
|
||||
00000000
|
||||
800003fd # stval of misaligned address (0x80000409)
|
||||
80000411 # stval of misaligned address (0x80000409)
|
||||
00000000
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -38,7 +38,7 @@
|
||||
00000000
|
||||
00000006 # scause from store misaligned
|
||||
00000000
|
||||
80000415 # stval of address with misaligned store instr (0x80000421)
|
||||
80000429 # stval of address with misaligned store instr (0x80000421)
|
||||
00000000
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
@ -92,8 +92,8 @@
|
||||
00000000
|
||||
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
|
||||
00000000
|
||||
fffff7ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
ffffffff
|
||||
0000b3ff # medeleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000
|
||||
00000222 # mideleg after attempted write of all 1's (only some bits are writeable)
|
||||
00000000
|
||||
0000000b # scause from M mode ecall
|
||||
@ -116,13 +116,13 @@ ffffffff
|
||||
00000000
|
||||
00000003 # scause from Breakpoint
|
||||
00000000
|
||||
800003f4 # stval of breakpoint instruction adress (0x80000400)
|
||||
80000408 # stval of breakpoint instruction adress (0x80000400)
|
||||
00000000
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000000
|
||||
00000004 # scause from load address misaligned
|
||||
00000000
|
||||
800003fd # stval of misaligned address (0x80000409)
|
||||
80000411 # stval of misaligned address (0x80000409)
|
||||
00000000
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000000
|
||||
@ -134,7 +134,7 @@ ffffffff
|
||||
00000000
|
||||
00000006 # scause from store misaligned
|
||||
00000000
|
||||
80000415 # stval of address with misaligned store instr (0x80000421)
|
||||
80000429 # stval of address with misaligned store instr (0x80000421)
|
||||
00000000
|
||||
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
|
||||
00000000
|
||||
|
@ -57,6 +57,11 @@ RVTEST_CODE_BEGIN
|
||||
csrw sscratch, sp
|
||||
la sp, stack_top
|
||||
|
||||
// set up PMP so user and supervisor mode can access full address space
|
||||
csrw pmpcfg0, 0xF # configure PMP0 to TOR RWX
|
||||
li t0, 0xFFFFFFFF
|
||||
csrw pmpaddr0, t0 # configure PMP0 top of range to 0xFFFFFFFF to allow all 32-bit addresses
|
||||
|
||||
.endm
|
||||
|
||||
// Code to trigger traps goes here so we have consistent mtvals for instruction adresses
|
||||
@ -162,6 +167,11 @@ cause_s_soft_interrupt:
|
||||
csrs sip, t3 // set supervisor software interrupt pending. SIP is a subset of MIP, so writing this should also change MIP.
|
||||
ret
|
||||
|
||||
cause_s_soft_from_m_interrupt:
|
||||
li t3, 0x2
|
||||
csrs mip, t3 // set supervisor software interrupt pending. SIP is a subset of MIP, so writing this should also change MIP.
|
||||
ret
|
||||
|
||||
cause_m_ext_interrupt:
|
||||
// ========== Configure PLIC ==========
|
||||
li a3, 0x40
|
||||
|
@ -49,7 +49,7 @@ jal cause_s_soft_interrupt // only cause one interrupt since we just want to tes
|
||||
|
||||
GOTO_M_MODE
|
||||
|
||||
jal cause_s_soft_interrupt // set software interrupt pending without it firing so we can make it fire in U mode
|
||||
jal cause_s_soft_from_m_interrupt // set software interrupt pending without it firing so we can make it fire in U mode
|
||||
|
||||
GOTO_U_MODE // Should cause software interrupt to fire off.
|
||||
|
||||
|
@ -50,7 +50,7 @@ GOTO_S_MODE // Causes U mode ecall
|
||||
GOTO_M_MODE // Causes S mode ecall
|
||||
|
||||
|
||||
jal cause_s_soft_interrupt
|
||||
jal cause_s_soft_from_m_interrupt
|
||||
jal cause_m_soft_interrupt
|
||||
jal cause_s_time_interrupt
|
||||
jal cause_m_time_interrupt
|
||||
@ -72,7 +72,7 @@ jal cause_store_addr_misaligned
|
||||
jal cause_store_acc
|
||||
jal cause_ecall // M mode ecall
|
||||
|
||||
jal cause_s_soft_interrupt // The delegated S mode interrupts should not fire since we're running in M mode.
|
||||
jal cause_s_soft_interrupt // S Mode Interrupts Ignored in M mode. sip writeable when mideleg = 1
|
||||
jal cause_m_soft_interrupt
|
||||
jal cause_s_time_interrupt
|
||||
jal cause_m_time_interrupt
|
||||
|
@ -56,12 +56,12 @@ GOTO_U_MODE // Causes S mode ecall
|
||||
GOTO_S_MODE // Causes U mode ecall
|
||||
|
||||
|
||||
// some interrupts excluded becaus writing MIP is illegal from S mode
|
||||
jal cause_s_soft_interrupt
|
||||
// some interrupts excluded because writing MIP is illegal from S mode and writing SIP is only possible when delegated, which is tested below (priv spec 3.1.9)
|
||||
//jal cause_s_soft_interrupt
|
||||
jal cause_m_soft_interrupt
|
||||
jal cause_m_time_interrupt
|
||||
li a3, 0x40 // this interrupt involves a time loop waiting for the interrupt to go off.
|
||||
// since interrupts are not always enabled,
|
||||
// since interrupts are not always enabled, we need to make it stop after a certain number of loops, which is the number in a3
|
||||
jal cause_s_ext_interrupt_GPIO
|
||||
li a3, 0x40
|
||||
jal cause_m_ext_interrupt
|
||||
|
Loading…
Reference in New Issue
Block a user