Merge pull request #135 from pulp-platform/fpga_dev

WIP: Merge FPGA changes
This commit is contained in:
msfschaffner 2018-11-20 21:03:21 +01:00 committed by GitHub
commit f8692af1a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
117 changed files with 10018 additions and 2828 deletions

View file

@ -6,8 +6,8 @@ root = true
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = off
max_line_length = 100
# 4 space indentation
[*.{sv, svh, v, vhd}]
indent_style = space
indent_size = 4
indent_size = 2

8
.gitignore vendored
View file

@ -22,4 +22,12 @@ build/
*.vcd
*.log
*.out
*.jou
*.o
uart
work-ver/*
fpga/work-fpga
stdout/
work-dpi/
tb/riscv-isa-sim/
work-*/*

15
.gitmodules vendored
View file

@ -13,6 +13,21 @@
[submodule "src/axi"]
path = src/axi
url = https://github.com/pulp-platform/axi.git
[submodule "src/register_interface"]
path = src/register_interface
url = https://github.com/pulp-platform/register_interface.git
[submodule "fpga/src/apb_uart"]
path = fpga/src/apb_uart
url = https://github.com/pulp-platform/apb_uart.git
[submodule "fpga/src/apb_node"]
path = fpga/src/apb_node
url = https://github.com/pulp-platform/apb_node.git
[submodule "fpga/src/axi2apb"]
path = fpga/src/axi2apb
url = https://github.com/pulp-platform/axi2apb.git
[submodule "fpga/src/axi_slice"]
path = fpga/src/axi_slice
url = https://github.com/pulp-platform/axi_slice.git
[submodule "src/fpu_div_sqrt_mvp"]
path = src/fpu_div_sqrt_mvp
url = https://github.com/pulp-platform/fpu_div_sqrt_mvp.git

106
Makefile Executable file → Normal file
View file

@ -28,7 +28,9 @@ test-location ?= output/test
torture-logs :=
# custom elf bin to run with sim or sim-verilator
elf-bin ?= tmp/riscv-tests/build/benchmarks/dhrystone.riscv
# root path
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
root-dir := $(dir $(mkfile_path))
# Sources
# Package files -> compile first
@ -37,13 +39,16 @@ ariane_pkg := include/riscv_pkg.sv \
include/ariane_pkg.sv \
include/std_cache_pkg.sv \
src/axi/src/axi_pkg.sv \
src/register_interface/src/reg_intf.sv \
include/axi_intf.sv \
tb/ariane_soc_pkg.sv \
include/ariane_axi_pkg.sv \
src/fpu/src/pkg/fpnew_pkg.vhd \
src/fpu/src/pkg/fpnew_fmts_pkg.vhd \
src/fpu/src/pkg/fpnew_comps_pkg.vhd \
src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv \
src/fpu/src/pkg/fpnew_pkg_constants.vhd
ariane_pkg := $(addprefix $(root-dir), $(ariane_pkg))
# utility modules
util := $(wildcard src/util/*.svh) \
@ -51,13 +56,18 @@ util := $(wildcard src/util/*.svh) \
src/util/instruction_tracer_if.sv \
src/tech_cells_generic/src/cluster_clock_gating.sv \
src/util/sram.sv
util := $(addprefix $(root-dir), $(util))
# Test packages
test_pkg := $(wildcard tb/test/*/*sequence_pkg.sv*) \
$(wildcard tb/test/*/*_pkg.sv*)
# DPI
dpi := $(patsubst tb/dpi/%.cc,${dpi-library}/%.o,$(wildcard tb/dpi/*.cc))
dpi_hdr := $(wildcard tb/dpi/*.h)
dpi_hdr := $(addprefix $(root-dir), $(dpi_hdr))
CFLAGS := -I$(QUESTASIM_HOME)/include \
-Itb/riscv-isa-sim/install/include/spike \
-std=c++11 -I../tb/dpi
# this list contains the standalone components
src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
$(wildcard src/fpu/src/utils/*.vhd) \
@ -66,13 +76,19 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
$(filter-out src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv, \
$(wildcard src/fpu_div_sqrt_mvp/hdl/*.sv)) \
$(wildcard src/frontend/*.sv) \
$(wildcard src/cache_subsystem/*.sv) \
$(filter-out src/cache_subsystem/std_no_dcache.sv, \
$(wildcard src/cache_subsystem/*.sv)) \
$(wildcard bootrom/*.sv) \
$(wildcard src/clint/*.sv) \
$(wildcard fpga/src/axi2apb/src/*.sv) \
$(wildcard fpga/src/axi_slice/src/*.sv) \
$(wildcard src/plic/*.sv) \
$(wildcard src/axi_node/src/*.sv) \
$(wildcard src/axi_mem_if/src/*.sv) \
$(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) \
$(wildcard src/debug/debug_rom/*.sv) \
src/register_interface/src/apb_to_reg.sv \
src/axi/src/axi_multicut.sv \
src/fpu/src/fpnew.vhd \
src/fpu/src/fpnew_top.vhd \
src/common_cells/src/deprecated/generic_fifo.sv \
@ -84,26 +100,40 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
src/util/axi_connect.sv \
src/axi/src/axi_cut.sv \
src/axi/src/axi_join.sv \
src/axi/src/axi_delayer.sv \
src/axi/src/axi_to_axi_lite.sv \
src/fpga-support/rtl/SyncSpRamBeNx64.sv \
src/common_cells/src/sync.sv \
src/common_cells/src/cdc_2phase.sv \
src/common_cells/src/spill_register.sv \
src/common_cells/src/sync_wedge.sv \
src/common_cells/src/edge_detect.sv \
src/common_cells/src/fifo_v3.sv \
src/common_cells/src/fifo_v2.sv \
src/common_cells/src/fifo_v1.sv \
src/common_cells/src/lzc.sv \
src/common_cells/src/rrarbiter.sv \
src/common_cells/src/pipe_reg_simple.sv \
src/common_cells/src/ready_valid_delay.sv \
src/common_cells/src/lfsr_8bit.sv \
src/common_cells/src/lfsr_16bit.sv \
src/common_cells/src/counter.sv \
src/common_cells/src/pipe_reg_simple.sv \
src/tech_cells_generic/src/cluster_clock_inverter.sv \
src/tech_cells_generic/src/pulp_clock_mux2.sv \
tb/ariane_testharness.sv \
tb/ariane_peripherals.sv \
tb/common/uart.sv \
tb/common/SimDTM.sv \
tb/common/SimJTAG.sv
# root path
root-dir := $(shell pwd)
src := $(addprefix $(root-dir), $(src))
uart_src := $(wildcard fpga/src/apb_uart/src/*.vhd)
uart_src := $(addprefix $(root-dir), $(uart_src))
fpga_src := $(wildcard fpga/src/*.sv) $(wildcard fpga/src/bootrom/*.sv)
fpga_src := $(addprefix $(root-dir), $(fpga_src))
# look for testbenches
tbs := tb/ariane_tb.sv tb/ariane_testharness.sv
# RISCV asm tests and benchmark setup (used for CI)
@ -121,16 +151,10 @@ riscv-benchmarks := $(shell xargs printf '\n%s' < $(riscv-benchmarks-li
incdir :=
# Compile and sim flags
compile_flag += +cover=bcfst+/dut -incr -64 -nologo -quiet -suppress 13262 -permissive +define+$(defines)
compile_flag_vhd += -64 -nologo -quiet -2008
uvm-flags += +UVM_NO_RELNOTES +UVM_VERBOSITY=LOW
questa-flags += -t 1ns -64 -coverage -classdebug $(gui-sim) $(QUESTASIM_FLAGS)
# if defined, calls the questa targets in batch mode
ifdef batch-mode
questa-flags += -c
questa-cmd := -do "coverage save -onexit tmp/$@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]"
else
questa-cmd := -do " log -r /*; run -all;"
endif
# Iterate over all include directories and write them with +incdir+ prefixed
# +incdir+ works for Verilator and QuestaSim
@ -140,17 +164,43 @@ list_incdir := $(foreach dir, ${incdir}, +incdir+$(dir))
riscv-torture-dir := tmp/riscv-torture
riscv-torture-bin := java -Xmx1G -Xss8M -XX:MaxPermSize=128M -jar sbt-launch.jar
# if defined, calls the questa targets in batch mode
ifdef batch-mode
questa-flags += -c
questa-cmd := -do "coverage save -onexit tmp/$@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]"
questa-cmd += -do " log -r /*; run -all;"
else
questa-cmd := -do " log -r /*; run -all;"
endif
# we want to preload the memories
ifdef preload
questa-cmd += +PRELOAD=$(preload)
elf-bin = none
# tandem verify with spike, this requires pre-loading
ifdef tandem
compile_flag += +define+TANDEM
questa-cmd += -gblso tb/riscv-isa-sim/install/lib/libriscv.so
endif
endif
# remote bitbang is enabled
ifdef rbb
questa-cmd += +jtag_rbb_enable=1
else
questa-cmd += +jtag_rbb_enable=0
endif
# Build the TB and module using QuestaSim
build: $(library) $(library)/.build-srcs $(library)/.build-tb $(dpi-library)/ariane_dpi.so
# Optimize top level
vopt$(questa_version) $(compile_flag) -work $(library) $(top_level) -o $(top_level)_optimized +acc -check_synthesis
# src files
$(library)/.build-srcs: $(ariane_pkg) $(util) $(src) $(library)
$(library)/.build-srcs: $(ariane_pkg) $(util) $(src) $(library) $(uart_src)
vlog$(questa_version) $(compile_flag) -work $(library) $(filter %.sv,$(ariane_pkg)) $(list_incdir) -suppress 2583
vcom$(questa_version) $(compile_flag_vhd) -work $(library) -pedanticerrors $(filter %.vhd,$(ariane_pkg))
vlog$(questa_version) $(compile_flag) -work $(library) $(filter %.sv,$(util)) $(list_incdir) -suppress 2583
# Suppress message that always_latch may not be checked thoroughly by QuestaSim.
vcom$(questa_version) $(compile_flag_vhd) -work $(library) -pedanticerrors $(filter %.vhd,$(uart_src))
vcom$(questa_version) $(compile_flag_vhd) -work $(library) -pedanticerrors $(filter %.vhd,$(src))
vlog$(questa_version) $(compile_flag) -work $(library) -pedanticerrors $(filter %.sv,$(src)) $(list_incdir) -suppress 2583
touch $(library)/.build-srcs
@ -167,7 +217,7 @@ $(library):
# compile DPIs
$(dpi-library)/%.o: tb/dpi/%.cc $(dpi_hdr)
mkdir -p $(dpi-library)
$(CXX) -shared -fPIC -std=c++0x -Bsymbolic -I$(QUESTASIM_HOME)/include -o $@ $<
$(CXX) -shared -fPIC -std=c++0x -Bsymbolic $(CFLAGS) -c $< -o $@
$(dpi-library)/ariane_dpi.so: $(dpi)
mkdir -p $(dpi-library)
@ -179,24 +229,24 @@ $(dpi-library)/ariane_dpi.so: $(dpi)
# if you want to run in batch mode, use make <testname> batch-mode=1
# alternatively you can call make sim elf-bin=<path/to/elf-bin> in order to load an arbitrary binary
sim: build
vsim${questa_version} +permissive $(questa-flags) $(questa-cmd) -lib $(library) +max-cycles=$(max_cycles) +UVM_TESTNAME=$(test_case) \
+BASEDIR=$(riscv-test-dir) $(uvm-flags) +jtag_rbb_enable=0 -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
vsim${questa_version} +permissive $(questa-flags) $(questa-cmd) -lib $(library) +MAX_CYCLES=$(max_cycles) +UVM_TESTNAME=$(test_case) \
+BASEDIR=$(riscv-test-dir) $(uvm-flags) $(QUESTASIM_FLAGS) -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
${top_level}_optimized +permissive-off ++$(elf-bin) ++$(target-options) | tee sim.log
$(riscv-asm-tests): build
vsim${questa_version} +permissive $(questa-flags) $(questa-cmd) -lib $(library) +max-cycles=$(max_cycles) +UVM_TESTNAME=$(test_case) \
+BASEDIR=$(riscv-test-dir) $(uvm-flags) +jtag_rbb_enable=0 -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$@ ++$(target-options) | tee tmp/riscv-asm-tests-$@.log
${top_level}_optimized $(QUESTASIM_FLAGS) +permissive-off ++$(riscv-test-dir)/$@ ++$(target-options) | tee tmp/riscv-asm-tests-$@.log
$(riscv-amo-tests): build
vsim${questa_version} +permissive $(questa-flags) $(questa-cmd) -lib $(library) +max-cycles=$(max_cycles) +UVM_TESTNAME=$(test_case) \
+BASEDIR=$(riscv-test-dir) $(uvm-flags) +jtag_rbb_enable=0 -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$@ ++$(target-options) | tee tmp/riscv-amo-tests-$@.log
${top_level}_optimized $(QUESTASIM_FLAGS) +permissive-off ++$(riscv-test-dir)/$@ ++$(target-options) | tee tmp/riscv-amo-tests-$@.log
$(riscv-benchmarks): build
vsim${questa_version} +permissive $(questa-flags) $(questa-cmd) -lib $(library) +max-cycles=$(max_cycles) +UVM_TESTNAME=$(test_case) \
+BASEDIR=$(riscv-benchmarks-dir) $(uvm-flags) +jtag_rbb_enable=0 -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \
${top_level}_optimized +permissive-off ++$(riscv-benchmarks-dir)/$@ ++$(target-options) | tee tmp/riscv-benchmarks-$@.log
${top_level}_optimized $(QUESTASIM_FLAGS) +permissive-off ++$(riscv-benchmarks-dir)/$@ ++$(target-options) | tee tmp/riscv-benchmarks-$@.log
# can use -jX to run ci tests in parallel using X processes
run-asm-tests: $(riscv-asm-tests)
@ -237,13 +287,15 @@ verilate_command := $(verilator)
-Wno-style \
-Wno-lint \
$(if $(DEBUG),--trace-structs --trace,) \
-LDFLAGS "-lfesvr" -CFLAGS "-std=c++11 -I../tb/dpi" -Wall --cc --vpi \
-LDFLAGS "-lfesvr" -CFLAGS "$(CFLAGS)" -Wall --cc --vpi \
$(list_incdir) --top-module ariane_testharness \
--Mdir $(ver-library) -O3 \
--exe tb/ariane_tb.cpp tb/dpi/SimDTM.cc tb/dpi/SimJTAG.cc tb/dpi/remote_bitbang.cc
--exe tb/ariane_tb.cpp tb/dpi/SimDTM.cc tb/dpi/SimJTAG.cc \
tb/dpi/remote_bitbang.cc tb/dpi/msim_helper.cc
# User Verilator, at some point in the future this will be auto-generated
verilate:
@echo "[Verilator] Building Model"
$(verilate_command)
cd $(ver-library) && $(MAKE) -j${NUM_JOBS} -f Variane_testharness.mk
@ -319,6 +371,16 @@ check-torture:
grep 'All signatures match for $(test-location)' $(riscv-torture-dir)/$(test-location).log
diff -s $(riscv-torture-dir)/$(test-location).spike.sig $(riscv-torture-dir)/$(test-location).rtlsim.sig
fpga: $(ariane_pkg) $(util) $(src) $(fpga_src) $(util) $(uart_src)
@echo "[FPGA] Generate sources"
@echo read_vhdl {$(uart_src)} > fpga/scripts/add_sources.tcl
@echo read_verilog -sv {$(ariane_pkg)} >> fpga/scripts/add_sources.tcl
@echo read_verilog -sv {$(util)} >> fpga/scripts/add_sources.tcl
@echo read_verilog -sv {$(src)} >> fpga/scripts/add_sources.tcl
@echo read_verilog -sv {$(fpga_src)} >> fpga/scripts/add_sources.tcl
@echo "[FPGA] Generate Bitstream"
cd fpga && make
clean:
rm -rf $(riscv-torture-dir)/output/test*
rm -rf $(library)/ $(dpi-library)/ $(ver-library)/

116
README.md
View file

@ -76,7 +76,7 @@ $ work-ver/Variane_testharness $RISCV/riscv64-unknown-elf/bin/pk hello.elf
If you want to use QuestaSim to run it you can use the following command:
```
$ make simc riscv-test-dir=$RISCV/riscv64-unknown-elf/bin riscv-test=pk target-options=hello.elf
$ make sim elf-bin=$RISCV/riscv64-unknown-elf/bin/pk target-options=hello.elf batch-mode=1
```
> Be patient! RTL simulation is way slower than Spike. If you think that you ran into problems you can inspect the trace files.
@ -87,7 +87,89 @@ $ make simc riscv-test-dir=$RISCV/riscv64-unknown-elf/bin riscv-test=pk target-o
## FPGA Emulation
Coming.
We currently only provide support for the [Genesys 2 board](https://reference.digilentinc.com/reference/programmable-logic/genesys-2/reference-manual). Tested on Vivado 2018.2.
```
$ source fpga/sourceme.sh
$ make fpga
```
TODO(zarubaf): Add further TODOS and simplify flow
Default baudrate is `115200`:
```
$ screen /dev/ttyUSB0 115200
```
### Debugging
You can debug (and program) the FPGA using [OpenOCD](http://openocd.org/doc/html/Architecture-and-Core-Commands.html). We provide two example scripts for OpenOCD, both to be used with Olimex Debug adapter. The JTAG port ist mapped to PMOD `JC` on the Gensys 2 board. You will need to connect the following wires to your debug adapter:
![](https://reference.digilentinc.com/_media/genesys2/fig_16.png)
| Pin | Nr. |
|----------|-----|
| `tck` | JC1 |
| `tdi` | JC2 |
| `tdo` | JC3 |
| `tms` | JC4 |
| `trst_n` | JC7 |
```
$ openocd -f fpga/ariane_tiny.cfg
Open On-Chip Debugger 0.10.0+dev-00195-g933cb87 (2018-09-14-19:32)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 1000 kHz
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
Info : clock speed 1000 kHz
Info : TAP riscv.cpu does not have IDCODE
Info : datacount=2 progbufsize=12
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=64, misa=0x8000000000141105
Info : Listening on port 3333 for gdb connections
Ready for Remote Connections
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : accepting 'gdb' connection on tcp/3333
```
Then you will be able to either connect through `telnet` or with `gdb`:
```
$ riscv64-unknown-elf-gdb /path/to/elf
(gdb) target remote localhost:3333
(gdb) load
Loading section .text, size 0x6508 lma 0x80000000
Loading section .rodata, size 0x900 lma 0x80006508
(gdb) b putchar
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000080009126 in putchar (s=72) at lib/qprintf.c:69
69 uart_sendchar(s);
(gdb) si
0x000000008000912a 69 uart_sendchar(s);
(gdb) p/x $mepc
$1 = 0xfffffffffffdb5ee
```
You can read or write device memory by using:
```
(gdb) x/i 0x1000
0x1000: lui t0,0x4
(gdb) set {int} 0x1000 = 22
(gdb) set $pc = 0x1000
```
If you are on an Ubuntu based system you need to add the following udev rule to `/etc/udev/rules.d/olimex-arm-usb-tiny-h.rules`
>```
> SUBSYSTEM=="usb", ACTION=="add", ATTRS{idProduct}=="002a", ATTRS{idVendor}=="15ba", MODE="664", GROUP="plugdev"
>```
## Planned Improvements
@ -99,10 +181,10 @@ The core has been developed with a full licensed version of QuestaSim. If you ha
To specify the test to run use (e.g.: you want to run `rv64ui-p-sraw` inside the `tmp/risc-tests/build/isa` folder:
```
$ make sim riscv-test=tmp/risc-tests/build/isa/rv64ui-p-sraw
$ make sim elf-bin=path/to/rv64ui-p-sraw
```
If you call `simc` instead of `sim` it will run without the GUI. QuestaSim uses `riscv-fesvr` for communication as well.
If you call `sim` with `batch-mode=1` it will run without the GUI. QuestaSim uses `riscv-fesvr` for communication as well.
### CI Testsuites and Randomized Constrained Testing with Torture
@ -132,6 +214,7 @@ Ariane can dump a trace-log in Questa which can be easily diffed against Spike w
```verilog
localparam bit ENABLE_SPIKE_COMMIT_LOG = 1'b1;
```
This runs the randomized program on Spike and on the RTL target, and checks whether the two signatures match. The random instruction mix can be configured in the `./tmp/riscv-torture/config/default.config` file.
This will dump a file called `trace_core_*_*_commit.log`.
This can be helpful for debugging long traces (e.g.: torture traces). To compile Spike with the commit log feature do:
@ -145,7 +228,32 @@ $ make
$ [sudo] make install
```
<!-- ### Tandem Verification with Spike
```
$ make sim preload=/home/zarubaf/Downloads/riscv-tests/build/benchmarks/dhrystone.riscv tandem=1
```
There are a couple of caveats:
- Memories should be initialized to zero. Random or `x` are not supported.
- UART needs to be replaced by a mock UART which exhibits always ready behavior.
- There is no end of test signaling at the moment. You are supposed to kill the simulation when sufficiently long run.
- You need to use the modified Spike version in the `tb` subdirectory.
- The RTC clock needs to be sufficiently slow (e.g.: 32 kHz seems to work). This is needed as otherwise there will be a difference when reading the `mtime` register as the RTL simulation takes more time to propagate the information through the system.
- All traps except memory traps need to zero the `tval` register. There is a switch you can set in `ariane_pkg`.
- `mcycle` needs to be incremented with `instret` to be similar to the performance counters found in Spike (IPC = 1)
-->
### Re-generating the Bootcode (ZSBL)
The zero stage bootloader (ZSBL) for RTL simulation lives in `bootrom/` while the bootcode for the FPGA is in `fpga/src/bootrom`. The RTL bootcode simply jumps to the base of the DRAM where the FSBL takes over. For the FPGA the ZSBL performs additional housekeeping. Both bootloader pass the hartid as well as address to the device tree in argumen register `a0` and `a1` respectively.
To re-generate the bootcode you can use the existing makefile within those directories. To generate the SystemVerilog files you will need the `bitstring` python package installed on your system.
# Contributing
Check out the [contribution guide](CONTRIBUTING.md)
# Acknowledgements
Thanks to Gian Marti, Thomas Kramer and Thomas E. Benz for implementing the PLIC.

View file

@ -1,8 +1,9 @@
bootrom_img = bootrom.img
bootrom_img = bootrom.img bootrom.sv
GCC=riscv64-unknown-elf-gcc
OBJCOPY=riscv64-unknown-elf-objcopy
DTB=ariane.dtb
PYTHON=python
all: $(bootrom_img)
@ -18,5 +19,8 @@ all: $(bootrom_img)
%.dtb: %.dts
dtc -I dts $< -O dtb -o $@
%.sv: %.img
$(PYTHON) ./gen_rom.py $<
clean:
rm $(bootrom_img) $(DTB)

View file

@ -5,18 +5,23 @@
#size-cells = <2>;
compatible = "eth,ariane-bare-dev";
model = "eth,ariane-bare";
// chosen {
// stdout-path = "/soc/uart@10000000:115200";
// };
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <10000000>;
timebase-frequency = <32768>; // 32.768 kHz
CPU0: cpu@0 {
clock-frequency = <50000000>; // 50 MHz
device_type = "cpu";
reg = <0>;
status = "okay";
compatible = "riscv";
riscv,isa = "rv64imc";
compatible = "eth, ariane", "riscv";
riscv,isa = "rv64imacsu";
mmu-type = "riscv,sv39";
clock-frequency = <1000000000>;
tlb-split;
// HLIC - hart local interrupt controller
CPU0_intc: interrupt-controller {
#interrupt-cells = <1>;
interrupt-controller;
@ -26,7 +31,7 @@
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x1000000>;
reg = <0x0 0x80000000 0x0 0x1800000>;
};
soc {
#address-cells = <2>;
@ -35,11 +40,35 @@
ranges;
clint@2000000 {
compatible = "riscv,clint0";
interrupts-extended = <&CPU0_intc 3 &CPU0_intc 7 >;
interrupts-extended = <&CPU0_intc 3 &CPU0_intc 7>;
reg = <0x0 0x2000000 0x0 0xc0000>;
reg-names = "control";
};
PLIC0: interrupt-controller@c000000 {
#address-cells = <0>;
#interrupt-cells = <1>;
compatible = "sifive,plic-1.0.0", "riscv,plic0";
interrupt-controller;
interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
reg = <0x0 0xc000000 0x0 0x4000000>;
riscv,max-priority = <7>;
riscv,ndev = <2>;
};
debug-controller@0 {
compatible = "riscv,debug-013";
interrupts-extended = <&CPU0_intc 65535>;
reg = <0x0 0x0 0x0 0x1000>;
reg-names = "control";
};
uart@10000000 {
compatible = "ns16750";
reg = <0x0 0x10000000 0x0 0x1000>;
clock-frequency = <50000000>;
current-speed = <115200>;
interrupt-parent = <&PLIC0>;
interrupts = <1>;
reg-shift = <2>; // regs are spaced on 32 bit boundary
reg-io-width = <4>; // only 32-bit access are supported
};
};
htif {
compatible = "ucb,htif0";
};
};

374
bootrom/bootrom.h Normal file
View file

@ -0,0 +1,374 @@
// Auto-generated code
const int reset_vec_size = 368;
uint32_t reset_vec[reset_vec_size] = {
0x0010041b,
0x01f41413,
0xf1402573,
0x00000597,
0x07458593,
0x00008402,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0xf1402573,
0x00000597,
0x03c58593,
0x10500073,
0x0000bff5,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0xedfe0dd0,
0x3d050000,
0x38000000,
0x3c040000,
0x28000000,
0x11000000,
0x10000000,
0x00000000,
0x01010000,
0x04040000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x01000000,
0x00000000,
0x03000000,
0x04000000,
0x00000000,
0x02000000,
0x03000000,
0x04000000,
0x0f000000,
0x02000000,
0x03000000,
0x14000000,
0x1b000000,
0x2c687465,
0x61697261,
0x622d656e,
0x2d657261,
0x00766564,
0x03000000,
0x10000000,
0x26000000,
0x2c687465,
0x61697261,
0x622d656e,
0x00657261,
0x01000000,
0x73757063,
0x00000000,
0x03000000,
0x04000000,
0x00000000,
0x01000000,
0x03000000,
0x04000000,
0x0f000000,
0x00000000,
0x03000000,
0x04000000,
0x2c000000,
0x00800000,
0x01000000,
0x40757063,
0x00000030,
0x03000000,
0x04000000,
0x3f000000,
0x80f0fa02,
0x03000000,
0x04000000,
0x4f000000,
0x00757063,
0x03000000,
0x04000000,
0x5b000000,
0x00000000,
0x03000000,
0x05000000,
0x5f000000,
0x79616b6f,
0x00000000,
0x03000000,
0x12000000,
0x1b000000,
0x2c687465,
0x69726120,
0x00656e61,
0x63736972,
0x00000076,
0x03000000,
0x0b000000,
0x66000000,
0x34367672,
0x63616d69,
0x00007573,
0x03000000,
0x0b000000,
0x70000000,
0x63736972,
0x76732c76,
0x00003933,
0x03000000,
0x00000000,
0x79000000,
0x01000000,
0x65746e69,
0x70757272,
0x6f632d74,
0x6f72746e,
0x72656c6c,
0x00000000,
0x03000000,
0x04000000,
0x83000000,
0x01000000,
0x03000000,
0x00000000,
0x94000000,
0x03000000,
0x0f000000,
0x1b000000,
0x63736972,
0x70632c76,
0x6e692d75,
0x00006374,
0x03000000,
0x04000000,
0xa9000000,
0x01000000,
0x03000000,
0x04000000,
0xaf000000,
0x01000000,
0x02000000,
0x02000000,
0x02000000,
0x01000000,
0x6f6d656d,
0x38407972,
0x30303030,
0x00303030,
0x03000000,
0x07000000,
0x4f000000,
0x6f6d656d,
0x00007972,
0x03000000,
0x10000000,
0x5b000000,
0x00000000,
0x00000080,
0x00000000,
0x00008001,
0x02000000,
0x01000000,
0x00636f73,
0x03000000,
0x04000000,
0x00000000,
0x02000000,
0x03000000,
0x04000000,
0x0f000000,
0x02000000,
0x03000000,
0x1f000000,
0x1b000000,
0x2c687465,
0x61697261,
0x622d656e,
0x2d657261,
0x00636f73,
0x706d6973,
0x622d656c,
0x00007375,
0x03000000,
0x00000000,
0xb7000000,
0x01000000,
0x6e696c63,
0x30324074,
0x30303030,
0x00000030,
0x03000000,
0x0d000000,
0x1b000000,
0x63736972,
0x6c632c76,
0x30746e69,
0x00000000,
0x03000000,
0x10000000,
0xbe000000,
0x01000000,
0x03000000,
0x01000000,
0x07000000,
0x03000000,
0x10000000,
0x5b000000,
0x00000000,
0x00000002,
0x00000000,
0x00000c00,
0x03000000,
0x08000000,
0xd2000000,
0x746e6f63,
0x006c6f72,
0x02000000,
0x01000000,
0x75626564,
0x6f632d67,
0x6f72746e,
0x72656c6c,
0x00003040,
0x03000000,
0x10000000,
0x1b000000,
0x63736972,
0x65642c76,
0x2d677562,
0x00333130,
0x03000000,
0x08000000,
0xbe000000,
0x01000000,
0xffff0000,
0x03000000,
0x10000000,
0x5b000000,
0x00000000,
0x00000000,
0x00000000,
0x00100000,
0x03000000,
0x08000000,
0xd2000000,
0x746e6f63,
0x006c6f72,
0x02000000,
0x01000000,
0x74726175,
0x30303140,
0x30303030,
0x00000030,
0x03000000,
0x08000000,
0x1b000000,
0x3631736e,
0x00303537,
0x03000000,
0x10000000,
0x5b000000,
0x00000000,
0x00000010,
0x00000000,
0x00100000,
0x03000000,
0x04000000,
0x3f000000,
0x80f0fa02,
0x03000000,
0x04000000,
0xdc000000,
0x00c20100,
0x03000000,
0x04000000,
0xea000000,
0x02000000,
0x03000000,
0x04000000,
0xf4000000,
0x04000000,
0x02000000,
0x02000000,
0x02000000,
0x09000000,
0x64646123,
0x73736572,
0x6c65632d,
0x2300736c,
0x657a6973,
0x6c65632d,
0x6300736c,
0x61706d6f,
0x6c626974,
0x6f6d0065,
0x006c6564,
0x656d6974,
0x65736162,
0x6572662d,
0x6e657571,
0x63007963,
0x6b636f6c,
0x6572662d,
0x6e657571,
0x64007963,
0x63697665,
0x79745f65,
0x72006570,
0x73006765,
0x75746174,
0x69720073,
0x2c766373,
0x00617369,
0x2d756d6d,
0x65707974,
0x626c7400,
0x6c70732d,
0x23007469,
0x65746e69,
0x70757272,
0x65632d74,
0x00736c6c,
0x65746e69,
0x70757272,
0x6f632d74,
0x6f72746e,
0x72656c6c,
0x6e696c00,
0x702c7875,
0x646e6168,
0x7200656c,
0x65676e61,
0x6e690073,
0x72726574,
0x73747075,
0x7478652d,
0x65646e65,
0x65720064,
0x616e2d67,
0x0073656d,
0x72727563,
0x2d746e65,
0x65657073,
0x65720064,
0x68732d67,
0x00746669,
0x2d676572,
0x772d6f69,
0x68746469,
0x00000000
};

Binary file not shown.

View file

@ -20,150 +20,193 @@ module bootrom (
input logic [63:0] addr_i,
output logic [63:0] rdata_o
);
localparam int RomSize = 141;
localparam int RomSize = 184;
const logic [RomSize-1:0][63:0] mem = {
64'h00000000_00000064,
64'h65646E65_7478652D,
64'h73747075_72726574,
64'h6E690073_65676E61,
64'h7200656C_646E6168,
64'h70007265_6C6C6F72,
64'h746E6F63_2D747075,
64'h72726574_6E690073,
64'h6C6C6563_2D747075,
64'h72726574_6E692300,
64'h79636E65_75716572,
64'h662D6B63_6F6C6300,
64'h65707974_2D756D6D,
64'h00617369_2C766373,
64'h69720073_75746174,
64'h73006765_72006570,
64'h79745F65_63697665,
64'h64007963_6E657571,
64'h6572662D_65736162,
64'h656D6974_006C6564,
64'h6F6D0065_6C626974,
64'h61706D6F_6300736C,
64'h6C65632D_657A6973,
64'h2300736C_6C65632D,
64'h73736572_64646123,
64'h09000000_02000000,
64'h02000000_00000030,
64'h66697468_2C626375,
64'h1B000000_0A000000,
64'h03000000_00000000,
64'h66697468_01000000,
64'h00000000_68746469,
64'h772d6f69_2d676572,
64'h00746669_68732d67,
64'h65720064_65657073,
64'h2d746e65_72727563,
64'h0073656d_616e2d67,
64'h65720064_65646e65,
64'h7478652d_73747075,
64'h72726574_6e690073,
64'h65676e61_7200656c,
64'h646e6168_702c7875,
64'h6e696c00_72656c6c,
64'h6f72746e_6f632d74,
64'h70757272_65746e69,
64'h00736c6c_65632d74,
64'h70757272_65746e69,
64'h23007469_6c70732d,
64'h626c7400_65707974,
64'h2d756d6d_00617369,
64'h2c766373_69720073,
64'h75746174_73006765,
64'h72006570_79745f65,
64'h63697665_64007963,
64'h6e657571_6572662d,
64'h6b636f6c_63007963,
64'h6e657571_6572662d,
64'h65736162_656d6974,
64'h006c6564_6f6d0065,
64'h6c626974_61706d6f,
64'h6300736c_6c65632d,
64'h657a6973_2300736c,
64'h6c65632d_73736572,
64'h64646123_09000000,
64'h02000000_02000000,
64'h00000C00_00000000,
64'h00000002_00000000,
64'h4B000000_10000000,
64'h03000000_07000000,
64'h01000000_03000000,
64'h01000000_AE000000,
64'h02000000_04000000,
64'hf4000000_04000000,
64'h03000000_02000000,
64'hea000000_04000000,
64'h03000000_00c20100,
64'hdc000000_04000000,
64'h03000000_80f0fa02,
64'h3f000000_04000000,
64'h03000000_00100000,
64'h00000000_00000010,
64'h00000000_5b000000,
64'h10000000_03000000,
64'h00000000_30746E69,
64'h6C632C76_63736972,
64'h1B000000_0D000000,
64'h00303537_3631736e,
64'h1b000000_08000000,
64'h03000000_00000030,
64'h30303030_30324074,
64'h6E696C63_01000000,
64'hA7000000_00000000,
64'h03000000_00007375,
64'h622D656C_706D6973,
64'h00636F73_2D657261,
64'h622D656E_61697261,
64'h2C687465_1B000000,
64'h1F000000_03000000,
64'h02000000_0F000000,
64'h04000000_03000000,
64'h02000000_00000000,
64'h04000000_03000000,
64'h00636F73_01000000,
64'h02000000_00000001,
64'h00000000_00000080,
64'h00000000_4B000000,
64'h30303030_30303140,
64'h74726175_01000000,
64'h02000000_006c6f72,
64'h746e6f63_d2000000,
64'h08000000_03000000,
64'h00100000_00000000,
64'h00000000_00000000,
64'h5b000000_10000000,
64'h03000000_ffff0000,
64'h01000000_be000000,
64'h08000000_03000000,
64'h00333130_2d677562,
64'h65642c76_63736972,
64'h1b000000_10000000,
64'h03000000_00003040,
64'h72656c6c_6f72746e,
64'h6f632d67_75626564,
64'h01000000_02000000,
64'h006c6f72_746e6f63,
64'hd2000000_08000000,
64'h03000000_00000c00,
64'h00000000_00000002,
64'h00000000_5b000000,
64'h10000000_03000000,
64'h00007972_6F6D656D,
64'h3F000000_07000000,
64'h03000000_00303030,
64'h30303030_38407972,
64'h6F6D656D_01000000,
64'h02000000_02000000,
64'h02000000_01000000,
64'h9F000000_04000000,
64'h03000000_00006374,
64'h6E692D75_70632C76,
64'h63736972_1B000000,
64'h0F000000_03000000,
64'h8A000000_00000000,
64'h07000000_01000000,
64'h03000000_01000000,
64'h79000000_04000000,
64'hbe000000_10000000,
64'h03000000_00000000,
64'h72656C6C_6F72746E,
64'h6F632D74_70757272,
64'h65746E69_01000000,
64'h00CA9A3B_69000000,
64'h30746e69_6c632c76,
64'h63736972_1b000000,
64'h0d000000_03000000,
64'h00000030_30303030,
64'h30324074_6e696c63,
64'h01000000_b7000000,
64'h00000000_03000000,
64'h00007375_622d656c,
64'h706d6973_00636f73,
64'h2d657261_622d656e,
64'h61697261_2c687465,
64'h1b000000_1f000000,
64'h03000000_02000000,
64'h0f000000_04000000,
64'h03000000_02000000,
64'h00000000_04000000,
64'h03000000_00636f73,
64'h01000000_02000000,
64'h00008001_00000000,
64'h00000080_00000000,
64'h5b000000_10000000,
64'h03000000_00007972,
64'h6f6d656d_4f000000,
64'h07000000_03000000,
64'h00303030_30303030,
64'h38407972_6f6d656d,
64'h01000000_02000000,
64'h02000000_02000000,
64'h01000000_af000000,
64'h04000000_03000000,
64'h00003933_76732C76,
64'h63736972_60000000,
64'h0B000000_03000000,
64'h00636D69_34367672,
64'h56000000_08000000,
64'h03000000_00000076,
64'h63736972_1B000000,
64'h06000000_03000000,
64'h00000000_79616B6F,
64'h4F000000_05000000,
64'h01000000_a9000000,
64'h04000000_03000000,
64'h00006374_6e692d75,
64'h70632c76_63736972,
64'h1b000000_0f000000,
64'h03000000_94000000,
64'h00000000_03000000,
64'h01000000_83000000,
64'h04000000_03000000,
64'h00000000_72656c6c,
64'h6f72746e_6f632d74,
64'h70757272_65746e69,
64'h01000000_79000000,
64'h00000000_03000000,
64'h00003933_76732c76,
64'h63736972_70000000,
64'h0b000000_03000000,
64'h00007573_63616d69,
64'h34367672_66000000,
64'h0b000000_03000000,
64'h00000076_63736972,
64'h00656e61_69726120,
64'h2c687465_1b000000,
64'h12000000_03000000,
64'h00000000_79616b6f,
64'h5f000000_05000000,
64'h03000000_00000000,
64'h4B000000_04000000,
64'h5b000000_04000000,
64'h03000000_00757063,
64'h3F000000_04000000,
64'h4f000000_04000000,
64'h03000000_80f0fa02,
64'h3f000000_04000000,
64'h03000000_00000030,
64'h40757063_01000000,
64'h80969800_2C000000,
64'h00800000_2c000000,
64'h04000000_03000000,
64'h00000000_0F000000,
64'h00000000_0f000000,
64'h04000000_03000000,
64'h01000000_00000000,
64'h04000000_03000000,
64'h00000000_73757063,
64'h01000000_00657261,
64'h622D656E_61697261,
64'h2C687465_26000000,
64'h622d656e_61697261,
64'h2c687465_26000000,
64'h10000000_03000000,
64'h00766564_2D657261,
64'h622D656E_61697261,
64'h2C687465_1B000000,
64'h00766564_2d657261,
64'h622d656e_61697261,
64'h2c687465_1b000000,
64'h14000000_03000000,
64'h02000000_0F000000,
64'h02000000_0f000000,
64'h04000000_03000000,
64'h02000000_00000000,
64'h04000000_03000000,
64'h00000000_01000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'hE8020000_C2000000,
64'h04040000_01010000,
64'h00000000_10000000,
64'h11000000_28000000,
64'h20030000_38000000,
64'hE2030000_EDFE0DD0,
64'h3c040000_38000000,
64'h3d050000_edfe0dd0,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_0000BFF5,
64'h10500073_03C58593,
64'h00000597_F1402573,
64'h00000000_0000bff5,
64'h10500073_03c58593,
64'h00000597_f1402573,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00008402_07458593,
64'h00000597_F1402573,
64'h01F41413_0010041B
64'h00000597_f1402573,
64'h01f41413_0010041b
};
logic [$clog2(RomSize)-1:0] addr_q;
@ -174,7 +217,7 @@ module bootrom (
end
end
// this prevents spurious Xes from propagating into
// this prevents spurious Xes from propagating into
// the speculative fetch stage of the core
assign rdata_o = (addr_q<RomSize) ? mem[addr_q] : '0;
assign rdata_o = (addr_q < RomSize) ? mem[addr_q] : '0;
endmodule

View file

@ -4,6 +4,7 @@ from string import Template
import argparse
import os.path
import sys
from bitstring import ConstBitStream, BitArray, BitStream
parser = argparse.ArgumentParser(description='Convert binary file to verilog rom')
parser.add_argument('filename', metavar='filename', nargs=1,
@ -48,7 +49,7 @@ module $filename (
localparam int RomSize = $size;
const logic [RomSize-1:0][63:0] mem = {
$content
$content
};
logic [$$clog2(RomSize)-1:0] addr_q;
@ -59,56 +60,69 @@ module $filename (
end
end
// this prevents spurious Xes from propagating into
// this prevents spurious Xes from propagating into
// the speculative fetch stage of the core
assign rdata_o = (addr_q<RomSize) ? mem[addr_q] : '0;
assign rdata_o = (addr_q < RomSize) ? mem[addr_q] : '0;
endmodule
"""
rom = []
c_var = """\
// Auto-generated code
with open(filename + ".img", "rb") as f:
byte = True;
while byte:
word = ""
# read 64-bit a.k.a 8 byte
for i in range(0, 8):
byte = f.read(1)
if i == 4:
word = "_" + word
if byte:
word = ("%02X" % int.from_bytes(byte, "little")) + word
# fill up with zeros if unaligned
else:
pass
word = "00" + word;
const int reset_vec_size = $size;
uint32_t reset_vec[reset_vec_size] = {
$content
};
"""
def read_bin():
s = ConstBitStream(filename=filename + ".img")
rom = []
try:
while True:
rom.append(s.read("hex:8"))
except Exception as e:
pass
# align to 64 bit
align = (int(len(rom) / 8) + 1) * 8;
for i in range(len(rom), align):
rom.append("00")
return rom
rom = read_bin()
""" Generate C header file for simulator
"""
with open(filename + ".h", "w") as f:
rom_str = ""
# process in junks of 32 bit (4 byte)
for i in range(0, int(len(rom)/4)):
rom_str += " 0x" + "".join(rom[i*4:i*4+4][::-1]) + ",\n"
# remove the trailing comma
rom_str = rom_str[:-2]
s = Template(c_var)
f.write(s.substitute(filename=filename, size=int(len(rom)/4), content=rom_str))
if word != "_":
word = "64'h" + word
# print(word)
rom.append(word)
f.close()
rom.reverse()
# open file for writing
""" Generate SystemVerilog bootcode for FPGA and ASIC
"""
with open(filename + ".sv", "w") as f:
# some string preparations
rom_str = ""
i = 0
for r in rom:
i += 1
rom_str += r + ",\n ";
# process in junks of 64 bit (8 byte)
for i in reversed(range(int(len(rom)/8))):
rom_str += " 64'h" + "".join(rom[i*8+4:i*8+8][::-1]) + "_" + "".join(rom[i*8:i*8+4][::-1]) + ",\n"
rom_str.rstrip()
# strip the last whitespace
rom_str = rom_str[:-10]
# remove the trailing comma
rom_str = rom_str[:-2]
# write files
f.write(license)
s = Template(module)
f.write(s.substitute(filename=filename, size=i, content=rom_str))
f.write(s.substitute(filename=filename, size=int(len(rom)/8), content=rom_str))
f.close()

View file

@ -1,7 +1,7 @@
#!/bin/bash
set -e
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
VERSION="294bfce8a1ca2fc501b8939292146e44f813a2b8"
VERSION="7cc76ea83b4f827596158c8ba0763e93da65de8f"
cd $ROOT/tmp

View file

@ -46,7 +46,7 @@ torture.testrun.dump false
torture.testrun.vec false
torture.overnight.errors 1
torture.overnight.minutes 1
torture.overnight.minutes 100000
torture.overnight.outdir output/failedtests
torture.overnight.email your@email.address

View file

@ -1,10 +0,0 @@
# Ignore all
*
# Unignore all with extensions
!*.*
# Ignore files with specific extension
*.hex
*.dump
*.sig
*.stats
*.dasm

View file

@ -1,72 +0,0 @@
#=======================================================================
# UCB VLSI FLOW: Makefile for riscv-tests
#-----------------------------------------------------------------------
# Yunsup Lee (yunsup@cs.berkeley.edu)
#
default: all
#--------------------------------------------------------------------
# Sources
#--------------------------------------------------------------------
asm_tests = $(wildcard *.S)
extra_files =
#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------
RISCV_GCC = riscv64-unknown-elf-gcc
RISCV_GCC_OPTS = -nostdlib -nostartfiles -Wa,-march=rv64i
RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy
RISCV_OBJDUMP = riscv64-unknown-elf-objdump --disassemble-all --section=.text --section=.data --section=.bss
RISCV_SIM = spike
#------------------------------------------------------------
# Build assembly tests
asm_tests_bin = $(patsubst %.S, %, $(asm_tests))
asm_tests_verilog = $(addsuffix .v, $(asm_tests_bin))
asm_tests_dump = $(addsuffix .dump, $(asm_tests_bin))
asm_tests_sig = $(addsuffix .sig, $(asm_tests_bin))
asm_tests_hex = $(addsuffix .hex, $(asm_tests_bin))
$(asm_tests_dump): %.dump: %
$(RISCV_OBJDUMP) $< > $@
$(asm_tests_verilog): %.v: %
$(RISCV_OBJCOPY) -O verilog $< $@
$(asm_tests_bin): %: %.S $(extra_files)
$(RISCV_GCC) $(RISCV_GCC_OPTS) -I../riscv-torture/env/p -T../riscv-torture/env/p/link.ld $< -o $@
$(asm_tests_hex): %.hex: % $(extra_files)
elf2hex 8 16384 $< 2147483648 > $@
$(asm_tests_sig): %.sig: %
$(RISCV_SIM) +signature=$@ $<
new:
cd ..; make gen
run: $(asm_tests_sig)
echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \
$(asm_tests_sig); echo;
junk += $(asm_tests_bin) $(asm_tests_dump) $(asm_tests_sig) $(asm_tests_hex)
#------------------------------------------------------------
# Default
all: $(asm_tests_dump) $(asm_tests_hex)
#------------------------------------------------------------
# Clean up
clean:
rm -rf $(junk)
clean-all: clean
rm -rf test*.S test*.stats test*.hex test*.out test*.dump test test_1* test_pseg_* schad* failedtests/*

View file

@ -1,10 +0,0 @@
# Failed Test Report
## VMA Tests
* test_1498676631701:
* Found bug in misaligned exception of half word access when another LSU request was incoming
* test_1498880354372:
* Found bug in `sfence.vma`, pipeline wasn't flushing due to wrong assignment on the no store pending signal, coming from the store buffer
* Found bug in accidental exception taken in the MMU: Even though the LSU didn't place a request on the MMU the MMU was propagating a misaligned exception signal. The solution was masking it by the `lsu_req` signal.

View file

@ -1,742 +0,0 @@
// random assembly code generated by RISC-V torture test generator
// nseqs = 200
// memsize = 1024
#include "riscv_test.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
j test_start
crash_backward:
RVTEST_FAIL
test_start:
xreg_init:
la x31, xreg_init_data
ld x0, 0(x31)
ld x1, 8(x31)
ld x2, 16(x31)
ld x3, 24(x31)
ld x4, 32(x31)
ld x5, 40(x31)
ld x6, 48(x31)
ld x7, 56(x31)
ld x8, 64(x31)
ld x9, 72(x31)
ld x10, 80(x31)
ld x11, 88(x31)
ld x12, 96(x31)
ld x13, 104(x31)
ld x14, 112(x31)
ld x15, 120(x31)
ld x16, 128(x31)
ld x17, 136(x31)
ld x18, 144(x31)
ld x19, 152(x31)
ld x20, 160(x31)
ld x21, 168(x31)
ld x22, 176(x31)
ld x23, 184(x31)
ld x24, 192(x31)
ld x25, 200(x31)
ld x26, 208(x31)
ld x27, 216(x31)
ld x28, 224(x31)
ld x29, 232(x31)
ld x30, 240(x31)
ld x31, 248(x31)
j pseg_0
pseg_0:
addi x3, x0, 1
addi x2, x0, 1
subw x15, x5, x31
sll x2, x2, 63
addi x19, x0, 2015
addi x26, x0, 1527
sllw x1, x15, x15
addi x25, x0, 1492
addi x17, x0, 1
addi x9, x0, -946
addi x12, x26, 1211
addi x8, x0, -315
sra x18, x9, x9
sll x17, x17, 63
addi x14, x0, 1825
srlw x30, x25, x8
lui x31, 955643
addi x7, x0, -1
srlw x13, x14, x14
or x21, x19, x19
xor x7, x7, x17
addi x29, x0, -1
addi x11, x0, 1
xor x29, x29, x2
bge x26, x12, crash_forward
and x20, x15, x7
sll x3, x3, 63
or x6, x30, x17
addi x10, x0, -1
and x5, x16, x29
or x23, x24, x2
xor x10, x10, x3
and x4, x2, x10
sll x11, x11, 63
addi x22, x0, -1
xor x22, x22, x11
and x28, x31, x22
or x16, x22, x11
or x27, x24, x3
addi x13, x0, 1
srl x24, x23, x11
addi x7, x0, 792
sltiu x15, x15, 1387
la x9, test_memory-969
addi x8, x0, -893
addi x26, x8, -920
sll x13, x13, 63
addi x12, x0, -1
xor x12, x12, x13
la x11, test_memory+2198
lbu x29, -1285(x11)
la x6, test_memory+348
xori x31, x31, 1641
and x17, x31, x12
la x2, test_memory+2555
addi x25, x0, -199
addi x24, x0, -456
addi x1, x25, -1246
xor x27, x10, x17
lwu x19, 1949(x9)
addw x15, x4, x4
addi x23, x0, 259
or x20, x3, x13
sltu x10, x23, x23
sw x26, -1759(x2)
addi x18, x0, -335
addi x3, x0, 1
sra x28, x24, x24
addi x4, x0, -1896
sll x3, x3, 63
addi x5, x0, -1
addi x11, x0, -1058
sra x30, x7, x18
sltu x31, x4, x4
srlw x29, x11, x11
xor x5, x5, x3
and x16, x9, x5
xori x29, x30, -1166
sltiu x10, x29, 1519
srl x31, x27, x18
or x24, x13, x13
slli x15, x15, 60
addi x23, x0, -1478
addi x18, x0, -1056
la x9, test_memory-1460
la x11, test_memory+1562
or x22, x16, x3
la x7, test_memory+2339
sltu x2, x18, x18
and x8, x18, x14
la x27, test_memory+1707
la x19, test_memory+1427
la x12, test_memory+2473
sb x25, -1915(x12)
addi x28, x26, -1654
ld x26, -1155(x27)
slt x30, x23, x23
sw x15, 1472(x9)
slt x13, x4, x4
addi x29, x0, 1325
lwu x17, -1354(x11)
addi x10, x0, -697
lw x20, -1807(x7)
sltu x4, x29, x10
sw x8, -1219(x19)
la x14, test_memory+986
sllw x1, x17, x17
sh x17, -610(x14)
addi x18, x0, 1
addi x28, x0, 1891
addi x9, x0, 1
addi x17, x0, -563
addi x27, x0, 1
addi x2, x0, 61
addi x19, x2, 391
sll x18, x18, 63
addw x12, x14, x14
la x20, test_memory+2801
sll x9, x9, 63
addi x5, x0, 0
sub x7, x28, x17
srlw x12, x28, x22
addi x10, x0, 0
addi x30, x0, -1
lwu x29, -1861(x20)
addi x4, x0, -1
blt x5, x10, crash_forward
xor x30, x30, x18
slliw x11, x6, 7
addi x26, x0, -1336
addw x23, x26, x26
bgeu x2, x19, crash_forward
and x31, x26, x30
la x10, test_memory+1884
lbu x21, 29(x6)
addi x5, x0, 1389
sll x27, x27, 63
lui x2, 647240
sltiu x26, x30, 623
addi x19, x0, 1799
addi x20, x19, 1856
add x11, x24, x20
subw x7, x6, x23
addi x21, x0, 1
la x16, test_memory+2554
sll x21, x21, 63
addi x17, x0, -1548
addi x29, x17, -1821
lw x23, -1804(x10)
addi x24, x0, -1
or x22, x14, x18
xor x4, x4, x9
la x8, test_memory+2269
addi x11, x0, -662
blt x31, x22, crash_backward
xor x24, x24, x27
addi x6, x0, -1
xor x6, x6, x21
addi x20, x0, -1309
and x1, x28, x4
addi x26, x0, 643
or x3, x0, x9
and x14, x5, x6
or x12, x5, x5
addi x29, x0, 1
blt x1, x3, crash_forward
sll x29, x29, 63
sra x23, x6, x5
sll x7, x11, x26
addi x17, x0, -1
xor x17, x17, x29
and x12, x16, x17
addi x2, x0, 204
or x28, x14, x21
lui x5, 598486
srlw x19, x20, x2
and x15, x12, x24
or x30, x6, x29
lbu x25, -1917(x16)
beq x14, x28, crash_backward
addi x4, x0, -971
sw x2, -1633(x8)
addi x9, x0, 1
la x18, test_memory-1534
or x13, x3, x27
sra x6, x29, x28
addw x31, x30, x30
addi x22, x0, 1855
addi x21, x0, 1
la x25, test_memory+1201
addi x20, x0, -1341
lb x10, 1765(x18)
sll x9, x9, 63
la x30, test_memory+451
addi x7, x0, -1
sll x21, x21, 63
la x8, test_memory+378
addi x11, x0, 1810
addi x14, x0, 1736
or x26, x4, x11
addi x19, x14, 1505
addi x16, x0, -1
sw x24, -78(x8)
addi x31, x0, 663
sb x1, 186(x30)
bge x14, x19, crash_forward
subw x12, x31, x31
xor x7, x7, x9
xor x16, x16, x21
addi x23, x22, 38
lbu x5, -899(x25)
and x28, x26, x16
or x2, x28, x21
and x3, x10, x7
addi x11, x0, 1
addi x19, x0, 1301
addi x27, x0, 1
addi x8, x0, 1877
sltiu x22, x21, -1343
sll x11, x11, 63
la x12, test_memory+155
or x1, x20, x9
lw x26, -15(x12)
sll x27, x27, 63
addi x5, x0, 1917
addi x18, x8, 1755
la x3, test_memory-584
bltu x10, x10, crash_forward
add x14, x19, x5
addi x4, x0, -1
la x9, test_memory+2152
xor x4, x4, x27
addi x10, x0, -1
addi x13, x0, 706
lh x12, -1984(x9)
and x31, x27, x4
or x25, x22, x27
xor x17, x20, x13
addi x7, x0, -714
addi x1, x0, -827
ld x22, 760(x3)
addi x22, x0, 1
la x13, test_memory+181
la x3, test_memory-1079
bltu x0, x0, crash_backward
xor x10, x10, x11
bltu x7, x7, crash_forward
addi x24, x0, 1
sll x22, x22, 63
addi x5, x0, 1364
lb x16, 720(x13)
addi x8, x0, 574
la x20, test_memory-620
addi x19, x0, 1959
srlw x21, x8, x19
lhu x28, 692(x20)
sd x5, 1975(x3)
sll x24, x24, 63
sraw x26, x7, x1
addi x6, x0, -1
xor x6, x6, x24
and x30, x8, x10
and x29, x19, x6
la x18, test_memory-540
sd x21, 924(x18)
or x15, x22, x24
addi x1, x0, -721
bgeu x29, x15, crash_forward
addi x31, x0, 2038
addi x27, x0, -1504
or x23, x1, x11
sll x18, x15, x24
addi x14, x0, -1
sllw x12, x5, x5
srlw x26, x31, x27
addi x4, x0, 1
xor x14, x14, x22
la x20, test_memory-1039
sll x4, x4, 63
addi x3, x0, -1472
la x10, test_memory-353
lw x11, 969(x10)
addi x6, x0, 1
sll x6, x6, 63
lhu x28, 1635(x20)
and x2, x3, x14
addi x23, x0, 823
addi x12, x0, 909
slt x18, x23, x12
addw x27, x30, x30
addi x31, x0, -1
addi x21, x1, -1950
addi x29, x0, -1478
addi x7, x0, -880
xor x31, x31, x6
addi x25, x0, -1
addi x26, x29, -527
or x17, x9, x22
and x24, x19, x31
bge x26, x29, crash_forward
xor x25, x25, x4
addi x9, x0, -1695
and x13, x3, x7
sllw x8, x9, x9
or x15, x24, x6
and x19, x0, x25
or x16, x18, x4
bltu x16, x19, crash_backward
andi x9, x18, 1474
addi x12, x0, 1
la x29, test_memory+1837
sll x12, x12, 63
addi x8, x0, 1892
la x21, test_memory+1241
addi x14, x0, 1
addi x11, x0, -1745
addi x26, x0, 1675
subw x19, x28, x28
addi x22, x0, -640
lwu x1, -889(x21)
addi x20, x0, -1
sltu x30, x8, x22
slliw x31, x23, 28
la x4, test_memory-1760
xor x20, x20, x12
addi x27, x26, 565
and x16, x18, x20
addi x2, x0, 216
addi x25, x2, 197
bgeu x2, x25, crash_backward
addi x19, x3, 0
or x23, x16, x12
addi x28, x0, 54
addi x31, x19, 0
addi x7, x0, 248
addi x21, x0, -821
add x1, x3, x3
sra x18, x21, x21
addi x10, x0, -1105
addi x2, x0, -1367
addi x25, x0, -378
addi x22, x0, 27
la x13, test_memory+779
or x24, x10, x10
or x6, x11, x28
sh x0, 1836(x4)
sll x14, x14, 63
sw x24, -327(x13)
lh x15, -1761(x29)
addw x9, x21, x21
srlw x30, x7, x25
subw x8, x2, x22
addi x5, x0, -1
xor x5, x5, x14
and x3, x16, x5
or x17, x23, x14
addi x4, x0, 1269
la x8, test_memory+1864
addi x16, x0, -1644
sltiu x1, x5, -375
la x10, test_memory+1496
slt x31, x0, x26
sra x25, x4, x4
addi x15, x0, 0
addi x3, x0, -734
la x20, test_memory+589
addi x12, x0, 686
addi x26, x0, -813
srl x14, x3, x3
addi x9, x0, -1191
slli x13, x16, 13
lwu x29, 123(x20)
sllw x5, x12, x12
addi x23, x0, 0
sraw x24, x12, x12
addi x6, x29, 0
addw x3, x29, x29
slt x27, x14, x0
addi x1, x0, -1372
sw x16, -1512(x8)
addi x21, x6, 0
addw x18, x9, x9
addi x31, x0, -1326
addi x29, x0, -494
bne x15, x23, crash_backward
bne x6, x21, crash_forward
add x12, x0, x30
addi x28, x16, -380
la x2, test_memory+394
la x9, test_memory-518
and x4, x31, x31
xor x30, x26, x26
la x25, test_memory+139
addi x31, x0, 2009
addi x7, x0, 1892
la x17, test_memory+1714
addi x27, x0, -1318
lh x22, -356(x2)
ld x18, 958(x9)
sra x5, x1, x29
lb x20, 406(x25)
addi x14, x14, 0
addi x4, x0, -581
sub x15, x31, x31
srl x12, x4, x4
sh x15, -1260(x17)
lh x19, -1068(x10)
addi x13, x15, 0
sra x11, x7, x7
addi x2, x0, -745
addi x26, x0, -1309
sllw x6, x4, x26
andi x30, x10, -293
sraiw x29, x19, 17
la x1, test_memory+2545
lui x21, 506506
addi x7, x0, -399
addi x8, x0, -464
addi x3, x13, 0
addi x25, x0, -26
ld x15, -1745(x1)
srl x24, x27, x8
addi x23, x14, 0
la x5, test_memory+945
addi x4, x0, 1427
blt x13, x3, crash_backward
addw x18, x2, x2
addi x21, x0, 383
addi x13, x0, 1428
addi x30, x0, -1564
sll x11, x27, x27
bne x14, x23, crash_forward
ld x20, -657(x5)
or x19, x30, x30
srlw x3, x13, x13
addi x3, x0, 1
bgeu x28, x16, crash_forward
addi x1, x0, 2045
addi x24, x0, -1897
addi x29, x0, 0
addi x27, x1, 1619
sll x9, x26, x4
addi x15, x0, 1
addi x17, x0, -187
addi x6, x0, 0
addi x19, x0, 57
sub x18, x21, x24
addi x22, x25, -1450
sra x16, x4, x10
sra x10, x7, x17
addi x12, x0, 2021
sll x15, x15, 63
addi x14, x0, -1
addi x13, x0, 1464
xor x14, x14, x15
bltu x29, x6, crash_forward
blt x27, x1, crash_forward
and x11, x29, x14
xor x9, x19, x19
sllw x31, x12, x12
bltu x0, x0, crash_forward
sll x3, x3, 63
addi x12, x0, 1454
or x8, x18, x15
addi x6, x0, -740
xor x21, x6, x6
sraw x2, x13, x13
addi x26, x0, 1
addi x20, x0, -1
add x16, x12, x12
blt x0, x0, crash_backward
addi x22, x0, 1
blt x11, x8, crash_forward
xor x20, x20, x3
la x24, test_memory+1896
sll x26, x26, 63
and x30, x13, x20
addi x28, x0, -1
sll x22, x22, 63
addi x7, x0, -1
or x23, x15, x3
xor x28, x28, x26
and x5, x15, x28
addi x25, x0, 1022
or x4, x13, x26
xor x7, x7, x22
lwu x9, -1468(x24)
addi x10, x0, -1821
and x29, x25, x10
and x31, x31, x7
or x17, x29, x22
bge x17, x31, crash_forward
j reg_dump
reg_dump:
la x1, loop_count
lw x2, 0(x1)
addi x3, x2, -1
sw x3, 0(x1)
bnez x2, pseg_0
la x1, xreg_output_data
sd x0, 0(x1)
sd x2, 16(x1)
sd x3, 24(x1)
sd x4, 32(x1)
sd x5, 40(x1)
sd x6, 48(x1)
sd x7, 56(x1)
sd x8, 64(x1)
sd x9, 72(x1)
sd x10, 80(x1)
sd x11, 88(x1)
sd x12, 96(x1)
sd x13, 104(x1)
sd x14, 112(x1)
sd x15, 120(x1)
sd x16, 128(x1)
sd x17, 136(x1)
sd x18, 144(x1)
sd x20, 160(x1)
sd x21, 168(x1)
sd x22, 176(x1)
sd x23, 184(x1)
sd x25, 200(x1)
sd x26, 208(x1)
sd x28, 224(x1)
sd x29, 232(x1)
sd x30, 240(x1)
sd x31, 248(x1)
j test_end
crash_forward:
RVTEST_FAIL
test_end:
RVTEST_PASS
RVTEST_CODE_END
.data
hidden_data:
.align 8
xreg_init_data:
reg_x0_init: .dword 0xffffffffffffff82
reg_x1_init: .dword 0x75b609608964d156
reg_x2_init: .dword 0xb9c3da7ac1e3eb8f
reg_x3_init: .dword 0x7f6377f979066dad
reg_x4_init: .dword 0x0800000000000009
reg_x5_init: .dword 0xffffffffffffff88
reg_x6_init: .dword 0xa2e849dd61710192
reg_x7_init: .dword 0xc7c98485479382e1
reg_x8_init: .dword 0xffffffffffffff86
reg_x9_init: .dword 0xffffffffffffff80
reg_x10_init: .dword 0xffffffff80000005
reg_x11_init: .dword 0x610ae01c2c1cf73a
reg_x12_init: .dword 0xffffffffffffff80
reg_x13_init: .dword 0x302e8a6544a5321f
reg_x14_init: .dword 0xffffffffffffff83
reg_x15_init: .dword 0xba90dd1ff64de384
reg_x16_init: .dword 0xffffffffffffffff
reg_x17_init: .dword 0xffffffff80000005
reg_x18_init: .dword 0x7ce461945846c309
reg_x19_init: .dword 0x5dfac35f6bc1748e
reg_x20_init: .dword 0x0000000000000000
reg_x21_init: .dword 0x0800000000000008
reg_x22_init: .dword 0xb096e5f42905a093
reg_x23_init: .dword 0xffffffffffff8000
reg_x24_init: .dword 0xbf1cd3b072a79670
reg_x25_init: .dword 0x7bf96f3fca9e5f04
reg_x26_init: .dword 0x0000000000000000
reg_x27_init: .dword 0xd1abc73f98de4801
reg_x28_init: .dword 0xffffffffffffffff
reg_x29_init: .dword 0x115d26a2d75ac58f
reg_x30_init: .dword 0x0000000000000000
reg_x31_init: .dword 0x1befeebed3a1b5cb
RVTEST_DATA_BEGIN
.align 8
xreg_output_data:
reg_x0_output: .dword 0xf9da5fc85f384e60
reg_x1_output: .dword 0x2362df40e3520391
reg_x2_output: .dword 0xdf9395839d811f14
reg_x3_output: .dword 0x6529213c2dfa1a96
reg_x4_output: .dword 0xf9a276d7d8faf165
reg_x5_output: .dword 0xf898dfad009dd12f
reg_x6_output: .dword 0xa67afea29b66a252
reg_x7_output: .dword 0xe2fc4a60b03f4b3b
reg_x8_output: .dword 0xe2004060d78d0476
reg_x9_output: .dword 0x765cb95084946f58
reg_x10_output: .dword 0x7c068ea018257769
reg_x11_output: .dword 0xbde4fa370c04e6f2
reg_x12_output: .dword 0x8b2d14abb0841165
reg_x13_output: .dword 0x4ca26363ce399a7b
reg_x14_output: .dword 0xe44ad78bfdce3f2c
reg_x15_output: .dword 0x66c3bfd05e712dfb
reg_x16_output: .dword 0x11f65231b9fefe29
reg_x17_output: .dword 0xf7d26872b00141cb
reg_x18_output: .dword 0x1c6e20eccaf214d5
reg_x19_output: .dword 0x83531ed1e7a47b9c
reg_x20_output: .dword 0x8b9c7021593fed5c
reg_x21_output: .dword 0x2e017cdb9fb19bbe
reg_x22_output: .dword 0x82562239bb29f67f
reg_x23_output: .dword 0x2db20df62458229f
reg_x24_output: .dword 0xee91e0de6971aebc
reg_x25_output: .dword 0xba146552c3c34a91
reg_x26_output: .dword 0x4d628d60b4f2bdab
reg_x27_output: .dword 0xf24fc58924cc59cf
reg_x28_output: .dword 0xde43c47cde7abfaa
reg_x29_output: .dword 0xd80a2d6129f190c1
reg_x30_output: .dword 0xbefe6941fcdfa7bc
reg_x31_output: .dword 0x5912ddee35d7387e
// Memory Blocks
.align 8
test_memory:
.dword 0xe3566b4b61ffdbae, 0x92e6ade076ec9593
.dword 0x41123c31ec656e7b, 0xc7d5be18f926c302
.dword 0x9cffa8448af81cf1, 0x79f7637fab5fb98d
.dword 0xdfa10678b0bff093, 0x75925a14da080733
.dword 0xa368f39e3a74acc1, 0x406c95462ebdfafb
.dword 0x2a1a0cd464b46a16, 0xf6d74180644548ef
.dword 0x26435d3c9a7e0411, 0x7f80cb082c866a6b
.dword 0xd02972f2ae323cf6, 0xa55ffe0a62ed3e97
.dword 0xcdf74f3c3628bbf6, 0xe0a893f274f2af31
.dword 0x3d11a5fc6714498d, 0xc5eac1f9d5155d8f
.dword 0x091a2069a443ee2b, 0x6a849d037e419be4
.dword 0x0bd79705be84d716, 0xd8a566a7b6e936c1
.dword 0xbb1376ca4843258e, 0x8890178fd80fd2df
.dword 0x6dcbc59eaec60c31, 0xf1cbbb045598e31b
.dword 0x341c7a11bf45dea0, 0xaac56fc15e707ac1
.dword 0x843a1a469960f763, 0x5151220e64f8800c
.dword 0x7602d62ca95e9809, 0x07b3530ebeb802ed
.dword 0x3d4a90f359fd2793, 0xb1af815b55e2bc0b
.dword 0x0c598db9a17b7312, 0x20bc06cd6c2af80b
.dword 0x7b5cb38b2662d48f, 0xef357f977cb07310
.dword 0x2a019c8a6092642a, 0x25790e9bf702e885
.dword 0x2d67e46c20699785, 0xba6e12fd6f575b19
.dword 0x51346a253af2f362, 0x387d22f3d47b590b
.dword 0x862a78e594d5b38a, 0x017b5fe0a301c0a7
.dword 0x867a0c4660df8cf0, 0xe4ee77a20ad8c90f
.dword 0xaf31a3bd8065ee16, 0x9d7ee726b931533e
.dword 0xf235595a8dd061b0, 0xc9b35243e09bc74a
.dword 0x2c042fae1a93f786, 0x9a6904c91cbf01e9
.dword 0xdfafcb061c01d79e, 0x9c2af0cea2521635
.dword 0xa0fa09e0d3c96399, 0x20c9be538749e7b3
.dword 0x3bcf309dc4308a5d, 0x29acc009ceb7e091
.dword 0xd88a9c776b0b31f4, 0xa27ce16ac7e7482e
.dword 0x10df31aeaba4dbb3, 0xec47e2107d1afde0
.dword 0xb11bf9077d5de69e, 0x6c4b7242ac259bf0
.dword 0x0018a075c4f0140b, 0x1c7d04d19e3246e9
.dword 0x149cd31837643284, 0x27dc6a263cb4ad12
.dword 0x64d09c64f1fd12f1, 0xe6ec8892cbdafa38
.dword 0x3a734aa59ffa2bf6, 0x2a8ec5ef9744c3b0
.dword 0xa07984a4c8568f9a, 0x9232f669b86e309b
.dword 0x3b8a86a448cf1728, 0xa716e4948f6ee26b
.dword 0x09dfba8f52c4e959, 0xee6dc6c2f2a061a6
.dword 0x6f891f74103fbeb2, 0xf8f93598e8b812ea
.dword 0x1d4c3431ada5882b, 0x5d2277dd9f1cf830
.dword 0x217a597005f35c11, 0x4a3c37966c01c254
.dword 0xd676ded0e59dcd2c, 0x1d81f44efd4ff6d4
.dword 0xe9742f6571fd1024, 0xc4ebc6ba52f92dd7
.dword 0x9072d162128b9320, 0x4e42497c090fac71
.dword 0x60042d137483ebaf, 0x5b47bb458457df25
.dword 0x62fe4f0f42d53eeb, 0x4388ae224f1878aa
.dword 0xef6d19adb23387db, 0xf2b7d80fe40738f2
.dword 0xb7e099b96d7b6019, 0x649dd8d1168ca067
.dword 0x3dff726007f72eb4, 0x66df09018a791377
.dword 0xbe3f94704b8de157, 0xc266a66b55ea3252
.dword 0x0c16b4c54ec193aa, 0x6b67f1980ec768f2
.dword 0x751735fbabe6c8f8, 0xfcdb10a88628fb5b
.dword 0x6785796cce631c11, 0xcc64cb662f6d1224
.dword 0x413ccb578e4c8971, 0xdaf574964af28b35
.dword 0xc57a5e5d1cb0b7a1, 0xee5c94900da992d1
.dword 0x66980a31155de1dc, 0x2dd42912132648d6
.dword 0xeb27c18dcc7d48f6, 0xb85f8e50dfe1f643
.dword 0x477bf36b28e94e79, 0x35076550491b96fb
.dword 0x8cb84b6d7e279e11, 0x43bd0b747790bbc8
.dword 0x0049859c74920929, 0xbf457758665408a2
.dword 0x315a495899bef8d5, 0xc6348ede3796d330
.align 8
loop_count: .word 0x40
RVTEST_DATA_END

View file

@ -1,678 +0,0 @@
// random assembly code generated by RISC-V torture test generator
// nseqs = 200
// memsize = 1024
#include "riscv_test.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
j test_start
crash_backward:
RVTEST_FAIL
test_start:
xreg_init:
la x31, xreg_init_data
ld x0, 0(x31)
ld x1, 8(x31)
ld x2, 16(x31)
ld x3, 24(x31)
ld x4, 32(x31)
ld x5, 40(x31)
ld x6, 48(x31)
ld x7, 56(x31)
ld x8, 64(x31)
ld x9, 72(x31)
ld x10, 80(x31)
ld x11, 88(x31)
ld x12, 96(x31)
ld x13, 104(x31)
ld x14, 112(x31)
ld x15, 120(x31)
ld x16, 128(x31)
ld x17, 136(x31)
ld x18, 144(x31)
ld x19, 152(x31)
ld x20, 160(x31)
ld x21, 168(x31)
ld x22, 176(x31)
ld x23, 184(x31)
ld x24, 192(x31)
ld x25, 200(x31)
ld x26, 208(x31)
ld x27, 216(x31)
ld x28, 224(x31)
ld x29, 232(x31)
ld x30, 240(x31)
ld x31, 248(x31)
j pseg_0
pseg_0:
addi x24, x0, -441
blt x22, x22, crash_backward
la x14, test_memory+1548
or x27, x7, x6
xor x18, x24, x2
sub x21, x18, x18
addi x15, x0, -1015
addi x26, x0, -792
xor x30, x25, x8
la x12, test_memory-1349
addi x20, x0, 1
sll x20, x20, 63
addi x23, x0, 1
sra x25, x26, x26
addi x8, x0, -1535
addi x9, x0, -1298
sraiw x19, x23, 19
addi x3, x0, 1
sll x3, x3, 63
sll x23, x23, 63
lhu x4, 1355(x12)
addi x1, x24, -774
addi x7, x0, -1
sllw x26, x8, x8
bne x0, x0, crash_forward
sra x22, x15, x9
xori x25, x14, 1318
add x13, x8, x8
xor x7, x7, x3
and x16, x20, x7
slli x29, x28, 7
addi x21, x0, -42
addi x2, x0, -1
addi x26, x0, 1
sra x27, x9, x0
lh x6, -722(x14)
xor x2, x2, x23
addi x10, x0, -1
sll x26, x26, 63
or x5, x13, x3
addi x9, x0, 1697
addi x18, x0, -1754
xor x10, x10, x20
and x28, x4, x2
and x17, x3, x10
or x11, x28, x23
addi x12, x0, 1783
blt x16, x5, crash_forward
addi x15, x0, -1
la x1, test_memory+2168
addi x5, x0, -786
sltu x25, x9, x28
lw x13, -1828(x1)
srlw x30, x21, x18
addi x16, x0, 1139
addi x19, x0, 753
addi x27, x0, 0
sub x14, x10, x7
subw x29, x9, x9
or x31, x13, x20
slt x4, x12, x19
sllw x7, x5, x16
addi x6, x0, 0
slt x5, x6, x1
addi x19, x0, -202
addi x7, x0, -623
and x24, x4, x14
la x23, test_memory+2884
addi x18, x0, 0
sra x5, x2, x2
addi x13, x0, 0
la x17, test_memory+772
addi x16, x4, 0
xor x15, x15, x26
and x8, x22, x15
slt x3, x11, x12
or x22, x8, x26
sraw x12, x7, x7
addi x31, x0, 0
addi x10, x0, 940
addi x1, x16, 0
addi x29, x0, 100
bltu x16, x1, crash_forward
la x28, test_memory+362
la x5, test_memory+1494
addi x14, x0, 539
addi x2, x10, 1554
slt x30, x19, x19
srliw x26, x20, 9
or x18, x22, x28
addi x7, x0, 1569
addi x8, x0, -1120
sll x4, x19, x24
sh x12, -1106(x5)
addi x22, x0, 1271
addi x6, x0, -1232
add x13, x1, x1
subw x2, x0, x0
addi x25, x0, 628
addi x10, x8, -1580
ori x13, x5, -2000
bgeu x10, x8, crash_forward
addi x13, x0, 439
addw x4, x4, x9
xor x21, x29, x29
lwu x24, -384(x17)
addi x26, x0, 1903
addi x18, x13, 649
sub x15, x6, x6
slt x16, x22, x22
bltu x18, x13, crash_forward
xor x9, x14, x25
addi x19, x0, 1509
addi x3, x0, -360
addi x10, x0, -1325
sltu x2, x26, x26
addi x8, x10, -756
and x12, x21, x2
addi x4, x0, 186
sb x9, 557(x28)
addi x20, x0, 0
addi x14, x0, 1210
la x18, test_memory+906
sll x27, x19, x3
xor x9, x14, x14
addi x16, x0, -474
blt x3, x3, crash_backward
lb x11, -1969(x23)
ld x22, -274(x18)
addi x27, x0, -821
la x24, test_memory+1776
addi x17, x16, -1119
addw x2, x11, x11
srli x6, x31, 22
addi x8, x0, -1236
addi x5, x0, -1905
la x25, test_memory-641
addi x1, x0, 501
addi x13, x5, -1118
bge x17, x16, crash_backward
sb x6, 1591(x25)
addi x19, x0, 1
sll x19, x19, 63
subw x3, x18, x0
srl x15, x19, x15
sltiu x12, x20, 885
slt x28, x27, x8
blt x5, x13, crash_backward
sltu x29, x14, x17
lhu x26, -1716(x24)
sub x21, x4, x4
la x10, test_memory+682
slt x30, x7, x1
sb x26, -40(x10)
addi x9, x0, -1
xor x9, x9, x19
la x7, test_memory+1982
and x18, x31, x9
sltu x27, x20, x16
addi x28, x0, 1
addi x1, x3, 0
la x4, test_memory-640
sraw x31, x19, x19
lui x5, 187465
addi x15, x0, 1934
srl x11, x14, x17
srl x23, x15, x15
addi x8, x1, 0
addi x10, x0, -73
srlw x3, x10, x10
addi x23, x0, 1
or x14, x30, x19
addi x29, x0, 0
la x12, test_memory-1333
lbu x2, -1285(x7)
lh x25, 1172(x4)
addi x22, x0, 1373
sh x15, 1861(x12)
addi x20, x0, 0
sll x28, x28, 63
sll x23, x23, 63
addi x31, x0, -1
addi x17, x0, 1325
addi x6, x0, -366
srl x26, x6, x6
xor x31, x31, x23
addi x2, x0, -867
addi x24, x0, 1
addi x26, x29, 0
addi x15, x2, -1208
addi x20, x26, 0
slti x6, x19, -537
beq x2, x15, crash_forward
addi x13, x0, -1
sub x21, x22, x17
srlw x5, x30, x30
bltu x26, x20, crash_forward
addi x8, x0, 374
xor x13, x13, x28
and x30, x2, x13
sll x3, x8, x8
addw x11, x30, x30
sll x24, x24, 63
and x14, x17, x17
or x16, x30, x28
la x20, test_memory+940
sb x27, -753(x20)
and x27, x1, x31
addi x18, x0, 1373
blt x24, x24, crash_forward
addi x4, x18, 915
bltu x25, x25, crash_forward
la x15, test_memory-1197
addi x7, x0, -1
xor x7, x7, x24
addi x5, x0, -1960
sb x18, 2029(x15)
addi x6, x0, 1
and x29, x27, x7
addi x26, x5, -1919
or x10, x30, x23
sltu x22, x20, x20
addi x9, x0, 735
addi x17, x0, 1
addi x8, x0, -388
or x12, x17, x24
sll x17, x17, 63
sll x6, x6, 63
la x15, test_memory-1613
sltu x10, x20, x7
sllw x28, x0, x25
addi x1, x0, -1
addi x20, x0, 983
addi x31, x0, -594
slliw x26, x13, 11
addi x4, x0, 1582
sra x5, x20, x4
xor x1, x1, x6
lwu x22, 1793(x15)
la x16, test_memory+423
sllw x2, x9, x8
addi x27, x0, -1211
addi x11, x0, -1
and x19, x20, x1
la x30, test_memory-1140
slt x23, x31, x27
lhu x14, 27(x16)
or x21, x24, x6
addi x24, x15, 0
sll x22, x3, x1
addi x9, x0, -261
bltu x0, x0, crash_backward
addw x15, x29, x29
addi x19, x0, -1403
addi x12, x24, 0
addi x14, x0, -1979
addi x18, x0, 1821
srl x15, x7, x7
sltu x28, x9, x9
addi x29, x0, 1442
la x16, test_memory+379
lh x2, -367(x16)
addi x6, x0, 1892
addi x4, x0, -640
slli x27, x12, 31
addi x20, x6, 642
lh x13, 1658(x30)
addi x1, x0, -1456
la x16, test_memory+494
addi x2, x22, 1049
addi x7, x0, -449
subw x21, x19, x18
sll x10, x4, x7
xori x9, x16, 1035
addi x5, x29, 0
slti x28, x0, -1164
srl x15, x31, x15
xori x31, x28, 67
sh x29, -220(x16)
addi x9, x0, -931
addi x21, x0, 237
srl x19, x9, x19
la x2, test_memory-1139
add x22, x29, x1
addi x28, x0, -2032
srl x6, x15, x15
addi x23, x5, 0
srl x24, x9, x21
la x30, test_memory-570
subw x5, x11, x20
addi x27, x0, -1649
lbu x20, 1545(x30)
addi x18, x0, -1125
addi x7, x0, -988
or x4, x18, x18
addi x26, x0, 1915
la x31, test_memory+1869
addi x24, x0, 110
sll x13, x28, x27
subw x8, x14, x26
slt x16, x22, x22
xor x11, x11, x17
lwu x10, 1379(x2)
addi x23, x0, 1214
lwu x1, -1729(x31)
sraw x5, x28, x28
addi x31, x0, 1
sll x22, x23, x23
addi x28, x0, 1849
xor x12, x7, x7
sll x31, x31, 63
addi x19, x0, -667
addi x6, x19, -952
and x25, x6, x11
addi x9, x0, 1753
addi x8, x0, -247
slti x15, x24, 844
addiw x2, x29, -505
bne x0, x0, crash_backward
addi x27, x0, -1
blt x19, x6, crash_forward
addi x10, x0, 1
addi x14, x0, 1
la x4, test_memory+1223
sll x10, x10, 63
addi x22, x0, -1
sll x14, x14, 63
xor x27, x27, x31
sraw x7, x27, x20
or x21, x24, x9
lbu x16, -289(x4)
addw x30, x28, x8
and x13, x9, x27
or x3, x25, x17
addi x26, x0, -1
sltu x29, x15, x3
xor x22, x22, x10
srli x5, x1, 17
xor x26, x26, x14
bgeu x25, x3, crash_forward
or x1, x13, x31
and x20, x28, x26
or x18, x20, x14
and x15, x24, x22
blt x20, x18, crash_forward
or x12, x15, x10
addi x13, x0, -956
srl x1, x12, x12
addi x31, x0, 1998
sll x29, x13, x31
addi x25, x0, 0
la x5, test_memory+1974
sub x11, x8, x29
addi x7, x0, 1083
addi x3, x0, 1
addi x13, x0, 0
addi x12, x0, 1
sll x12, x12, 63
la x18, test_memory+1514
sd x16, -1346(x18)
or x8, x26, x26
sraw x16, x7, x7
addi x10, x0, 547
lwu x15, -1802(x5)
add x19, x22, x22
srl x17, x19, x19
addi x30, x0, -1
xor x30, x30, x12
addi x8, x0, 1139
la x20, test_memory+1047
sll x3, x3, 63
addi x27, x0, -757
addi x29, x0, -1
addi x7, x0, 1
bltu x25, x13, crash_forward
addi x21, x0, -1493
addi x23, x10, 1036
addi x14, x0, -738
bne x0, x0, crash_forward
la x6, test_memory+2381
and x2, x27, x14
and x11, x24, x30
addi x16, x0, 0
xor x29, x29, x3
ld x26, -191(x20)
addi x9, x0, 1927
addi x15, x0, 0
blt x23, x10, crash_forward
xor x19, x8, x8
srlw x4, x21, x9
addi x25, x0, -1105
and x28, x26, x29
or x22, x23, x12
bltu x22, x11, crash_forward
bltu x16, x15, crash_forward
addi x1, x0, 1126
and x13, x25, x1
sll x7, x7, 63
and x11, x8, x9
addw x21, x27, x27
and x8, x23, x4
xor x19, x2, x2
sub x2, x23, x3
addi x13, x0, 1905
addi x5, x0, -1
lw x24, -1777(x6)
xor x23, x22, x22
addi x12, x0, 1
addi x25, x0, -1455
xor x5, x5, x7
and x17, x27, x5
or x31, x28, x3
sub x20, x25, x25
or x18, x17, x7
addi x26, x0, -854
beq x28, x31, crash_backward
sll x12, x12, 63
bltu x18, x17, crash_backward
srl x15, x13, x26
addi x22, x0, -1
addi x30, x0, 304
addi x16, x0, 1624
xor x22, x22, x12
slt x10, x30, x16
and x9, x27, x22
or x14, x9, x12
j reg_dump
reg_dump:
la x1, loop_count
lw x2, 0(x1)
addi x3, x2, -1
sw x3, 0(x1)
bnez x2, pseg_0
la x1, xreg_output_data
sd x0, 0(x1)
sd x2, 16(x1)
sd x3, 24(x1)
sd x4, 32(x1)
sd x5, 40(x1)
sd x7, 56(x1)
sd x8, 64(x1)
sd x9, 72(x1)
sd x10, 80(x1)
sd x11, 88(x1)
sd x12, 96(x1)
sd x13, 104(x1)
sd x14, 112(x1)
sd x15, 120(x1)
sd x16, 128(x1)
sd x17, 136(x1)
sd x18, 144(x1)
sd x19, 152(x1)
sd x20, 160(x1)
sd x21, 168(x1)
sd x22, 176(x1)
sd x23, 184(x1)
sd x24, 192(x1)
sd x25, 200(x1)
sd x26, 208(x1)
sd x27, 216(x1)
sd x28, 224(x1)
sd x29, 232(x1)
sd x30, 240(x1)
sd x31, 248(x1)
j test_end
crash_forward:
RVTEST_FAIL
test_end:
RVTEST_PASS
RVTEST_CODE_END
.data
hidden_data:
.align 8
xreg_init_data:
reg_x0_init: .dword 0xff92ffc2ca0bbe7b
reg_x1_init: .dword 0x166649dc02ff3f4f
reg_x2_init: .dword 0xffffffffffffffff
reg_x3_init: .dword 0xe0ae5d9fdd4809b8
reg_x4_init: .dword 0x11309b6128ec1610
reg_x5_init: .dword 0x0000000000000000
reg_x6_init: .dword 0xeb59007640bc57dc
reg_x7_init: .dword 0xedb999fdec848259
reg_x8_init: .dword 0x81e0012642fd86f9
reg_x9_init: .dword 0x0000000000000000
reg_x10_init: .dword 0x1b803d493f09b644
reg_x11_init: .dword 0x0000000000000005
reg_x12_init: .dword 0x0000000000000000
reg_x13_init: .dword 0x118963d6f1549a11
reg_x14_init: .dword 0xb3ab4dc53714316c
reg_x15_init: .dword 0x0000000000000000
reg_x16_init: .dword 0x409e57b75f96bfc8
reg_x17_init: .dword 0x2846e77e62c716da
reg_x18_init: .dword 0x2b16f36ebe2875d0
reg_x19_init: .dword 0xffffffffffffff80
reg_x20_init: .dword 0x0000000000000000
reg_x21_init: .dword 0x1ed4f77fb27dd3dc
reg_x22_init: .dword 0x0000000000000001
reg_x23_init: .dword 0xe5973f36dbfb7072
reg_x24_init: .dword 0x93f22207eeadece8
reg_x25_init: .dword 0x4c54a10a1fb7c234
reg_x26_init: .dword 0x12b9c4f9efee6177
reg_x27_init: .dword 0x39f6a8aabab7b7b8
reg_x28_init: .dword 0xffffffff80000003
reg_x29_init: .dword 0x0800000000000007
reg_x30_init: .dword 0x027bd1a95f66eb34
reg_x31_init: .dword 0xffffffffffffffff
RVTEST_DATA_BEGIN
.align 8
xreg_output_data:
reg_x0_output: .dword 0xd08d4f4137a984b9
reg_x1_output: .dword 0xdf827c90a30532bc
reg_x2_output: .dword 0xaa13f8047e432244
reg_x3_output: .dword 0x2319744405965cfc
reg_x4_output: .dword 0x9a821ea2984f0e6b
reg_x5_output: .dword 0xc5fc6106a4903a5a
reg_x6_output: .dword 0x2043d910ce73b8d1
reg_x7_output: .dword 0x888f3402d080648b
reg_x8_output: .dword 0x18e23e25962fb70d
reg_x9_output: .dword 0x3fdc45bd116fa5c3
reg_x10_output: .dword 0xdca844d6538585d1
reg_x11_output: .dword 0xe06bea68095f987a
reg_x12_output: .dword 0xcc59e2a4e03fb84d
reg_x13_output: .dword 0xc1107773ae9bff73
reg_x14_output: .dword 0xd69a1d5a763e39d5
reg_x15_output: .dword 0x81f48e6a577b19f9
reg_x16_output: .dword 0xeb3403f26e2385c0
reg_x17_output: .dword 0x1ac2c0faf918786b
reg_x18_output: .dword 0xed45c2d6c7c2f993
reg_x19_output: .dword 0x009ae254894a14fb
reg_x20_output: .dword 0x698c4751041fa55f
reg_x21_output: .dword 0xbafa99b7d1c7b4b2
reg_x22_output: .dword 0xc701263c7bdd3e67
reg_x23_output: .dword 0x13040a489b78d4b6
reg_x24_output: .dword 0x6ce3b9faf6fb1805
reg_x25_output: .dword 0xd3e6a425dd5da7cf
reg_x26_output: .dword 0x3d61ababe5cb46cd
reg_x27_output: .dword 0xb2db72b93ecbe827
reg_x28_output: .dword 0x06a25b9ca59651f2
reg_x29_output: .dword 0xda677c5179008151
reg_x30_output: .dword 0x203bdcfcc77e16e8
reg_x31_output: .dword 0x04ac06edf493568c
// Memory Blocks
.align 8
test_memory:
.dword 0x384f78d65438c34b, 0x64b5d65be46aa947
.dword 0x74f6ec399d6708ff, 0x8439b7825d9fe3e8
.dword 0x138ad5bbd3d6f097, 0xf33decfaca9fccc8
.dword 0xdade06227336edfa, 0x471550e523ec6582
.dword 0x3f10a857a5d31b43, 0x970a3ff8a286fa6d
.dword 0x685974a63830bde9, 0xe464a1dbfb6d2666
.dword 0x495263251afa7a1f, 0xba57a2b478fbced2
.dword 0x2839916dfbf1d87d, 0xb618f1fc92b75be2
.dword 0xf86e4f9542c101e0, 0x892c9a9b9628b119
.dword 0x597d8854f6d1d58d, 0xb50dc832f072aa0b
.dword 0x368ff88c5dfdbd9c, 0x990e0db7183c1f66
.dword 0xb73fe9e8c33be593, 0x26ca013fa6c6b836
.dword 0x510364e2eea9b751, 0x782b41200dcb0b64
.dword 0x59b30debb7a3c22d, 0xb0dd36367a36d57f
.dword 0xff8521e66c63705e, 0xbd9b2782d27246be
.dword 0x345745d5e2f82e9c, 0x2b1372fc959dad45
.dword 0x10991dd61bb8ea07, 0x0d84ffa37088ffa7
.dword 0xd0d4df4fc7b50848, 0xb6f93cd1293b0bac
.dword 0xa6f25267847a3df5, 0x454e42d492f64d53
.dword 0xa923f6b993f6e739, 0x3869e8c15f05b219
.dword 0xab353f448996c6b4, 0xad27e382227bcc7b
.dword 0x6eec19a63f324ea0, 0x48224230e2b33bba
.dword 0x749f34883346d834, 0x9d94dba902074bdd
.dword 0xa145b959a8706d4c, 0x1e918158d82811fc
.dword 0xb25c6d42d2840849, 0x80c40b5a7ddd88ba
.dword 0x0d476d518a336e36, 0xc26291c2ff417113
.dword 0x4e96f9fa4312072b, 0x78d7673be9affb57
.dword 0x390905bcdb6458f6, 0xfb77a8d0f02b7c75
.dword 0x5b887b25b79a07f7, 0x3d72770799efb37c
.dword 0x44066dfafeec824a, 0x28522c33cfb5635f
.dword 0x1a18abb2a99ab92b, 0xf42a240adcef44f8
.dword 0x7b0c5f24f5dc8c96, 0x1920e8759755954f
.dword 0xd0d2bb823d2ecd2e, 0xe0afd7a7d8a5c41b
.dword 0xb918e284a242f85f, 0x80ee977210d00688
.dword 0x793b79e7a6ec12c6, 0xcad1e9d43a24d23a
.dword 0xb1d9a4190b1444cf, 0x62aab6d5f1b08491
.dword 0x40d2502ce85d1d9f, 0xe1ab5f987413ba2e
.dword 0x6db215157bc6a035, 0x1d06aea8170b1ab6
.dword 0x7a470c0d85d77ecb, 0xb49cf992e1c19cd5
.dword 0x92735e5e4c832881, 0x5d6147bdbe348685
.dword 0xe2ae7a3baeb08d3d, 0x93e9927584a0ad90
.dword 0x8f30230f1a0ebbcc, 0x4f3a7243bb64bc53
.dword 0x0dbfd0daaf12be4d, 0x4c0fcd853a3c7ec4
.dword 0x64d612f836cc58ce, 0xd2e95c3a1b757bb5
.dword 0x6364ea0468f58e37, 0xb83b151d38fd5e59
.dword 0x90774d1a287b0f66, 0x638ed7f4522ef407
.dword 0x58274e42fff9f89b, 0x1965e9285a4ac23e
.dword 0x8f6d922c18918116, 0x997e129812d478e8
.dword 0x71440f18da2d80fe, 0x79077daa38dec4e2
.dword 0x90c147193758f185, 0xe3959aa334e346bc
.dword 0x3470717a95f5cb48, 0x9f66a938725cb1bd
.dword 0x2a7e47803429e6fb, 0x2742b66493355729
.dword 0x5a9968509ba6c445, 0x4eec237c6b7ca1c5
.dword 0x54e08833176c5ae8, 0x74290a7fa7fa459a
.dword 0x7c27def87f855a24, 0x870e13b2ce5e27f9
.dword 0x808289b7fd3d7a5d, 0xdda8906cc43843bf
.dword 0xf493d3c17f38c4fb, 0x8aaeef2d9ad40dda
.dword 0x57f79acb69dcf691, 0xd9bbdcf625c71e0b
.dword 0xea50426f03ec5f40, 0x4709a7d408bb1fed
.dword 0xa07beada3343e55d, 0x39e8b6bcdaf75035
.dword 0x3f59debd38a40e51, 0x81852a9eacae0a3a
.dword 0xb8a46c87458731c1, 0xf03cfcb4575729b8
.dword 0xadf29ed672853aee, 0xe4092e1b47a844d0
.dword 0x67388829d9e79c5d, 0x5791dca2d9480252
.align 8
loop_count: .word 0x40
RVTEST_DATA_END

6
fpga/.gitignore vendored
View file

@ -1,9 +1,13 @@
.*
!.gitignore
/reports
scripts/add_sources.tcl
vivado*
*.cache
*.hw
*.ip_user_files
*.sim
*.runs
*.srcs
*.xpr
*.xpr
*.mif

10
fpga/Makefile Normal file
View file

@ -0,0 +1,10 @@
all:
vivado-2018.2 vivado -mode batch -source scripts/run.tcl
# ips: mig
clean:
rm -rf *.log *.jou *.str
.PHONY:
clean

29
fpga/ariane.cfg Normal file
View file

@ -0,0 +1,29 @@
adapter_khz 1000
interface ftdi
# ftdi_device_desc "Olimex Ltd. ARM-USB-OCD-H JTAG+RS232"
ftdi_vid_pid 0x15ba 0x002b
ftdi_layout_init 0x0808 0x0a1b
ftdi_layout_signal nSRST -oe 0x0200
ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
ftdi_layout_signal LED -data 0x0800
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
gdb_report_data_abort enable
gdb_report_register_access_error enable
riscv set_reset_timeout_sec 120
riscv set_command_timeout_sec 120
# prefer to use sba for system bus access
riscv set_prefer_sba off
init
halt
echo "Ready for Remote Connections"

View file

@ -1,33 +0,0 @@
set_property PACKAGE_PIN AM13 [get_ports sys_rst]
set_property IOSTANDARD LVCMOS33 [get_ports sys_rst]
set_property PACKAGE_PIN A20 [get_ports tck]
set_property IOSTANDARD LVCMOS33 [get_ports tck]
set_property PACKAGE_PIN B20 [get_ports tdi]
set_property PACKAGE_PIN A22 [get_ports tdo]
set_property PACKAGE_PIN A21 [get_ports tms]
set_property PACKAGE_PIN B21 [get_ports trst_n]
set_property IOSTANDARD LVCMOS33 [get_ports tdi]
set_property IOSTANDARD LVCMOS33 [get_ports tdo]
set_property IOSTANDARD LVCMOS33 [get_ports tms]
set_property IOSTANDARD LVCMOS33 [get_ports trst_n]
# accept sub-optimal placement
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_IBUF_inst/O]
create_clock -period 100.000 -name tck -waveform {0.000 50.000} [get_ports tck]
set_input_jitter tck 15.000
####################################################################################
# Constraints from file : 'axi_clock_converter_0_clocks.xdc'
####################################################################################
set_max_delay -datapath_only -from [get_clocks tck] -to [get_clocks mmcm_clkout0] 5.000
set_max_delay -datapath_only -from [get_clocks mmcm_clkout0] -to [get_clocks tck] 5.000
set_max_delay -datapath_only -from [get_clocks tck] -to [get_clocks c0_sys_clk_p] 5.000
set_max_delay -datapath_only -from [get_clocks c0_sys_clk_p] -to [get_clocks tck] 5.000
set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub]
set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub]
set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub]
connect_debug_port dbg_hub/clk [get_nets clk_1]

29
fpga/ariane_tiny.cfg Normal file
View file

@ -0,0 +1,29 @@
adapter_khz 1000
interface ftdi
ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
ftdi_vid_pid 0x15ba 0x002a
ftdi_layout_init 0x0808 0x0a1b
ftdi_layout_signal nSRST -oe 0x0200
ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
ftdi_layout_signal LED -data 0x0800
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
gdb_report_data_abort enable
gdb_report_register_access_error enable
riscv set_reset_timeout_sec 120
riscv set_command_timeout_sec 120
# prefer to use sba for system bus access
riscv set_prefer_sba off
init
halt
echo "Ready for Remote Connections"

View file

@ -1,543 +0,0 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
module ariane_xilinx (
input logic c0_sys_clk_p, // Clock
input logic c0_sys_clk_n, // Clock
input logic sys_rst, // active high reset
output logic c0_ddr4_act_n,
output logic [16:0] c0_ddr4_adr,
output logic [1:0] c0_ddr4_ba,
output logic [0:0] c0_ddr4_bg,
output logic [0:0] c0_ddr4_cke,
output logic [0:0] c0_ddr4_odt,
output logic [0:0] c0_ddr4_cs_n,
output logic [0:0] c0_ddr4_ck_t,
output logic [0:0] c0_ddr4_ck_c,
output logic c0_ddr4_reset_n,
inout logic [1:0] c0_ddr4_dm_dbi_n,
inout logic [15:0] c0_ddr4_dq,
inout logic [1:0] c0_ddr4_dqs_c,
inout logic [1:0] c0_ddr4_dqs_t,
input logic tck,
input logic tms,
input logic trst_n,
input logic tdi,
output logic tdo
);
localparam logic [63:0] RomBase = 64'h10000;
localparam NBSlave = 4; // debug, Instruction fetch, data bypass, data
localparam NBMaster = 3; // debug, ROM, RAM
localparam logic [63:0] CacheStartAddr = 64'h8000_0000;
localparam AxiAddrWidth = 64;
localparam AxiDataWidth = 64;
localparam AxiIdWidthMaster = 2;
localparam AxiIdWidthSlaves = AxiIdWidthMaster + $clog2(NBSlave); // 4
localparam AxiUserWidth = 1;
AXI_BUS #(
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
.AXI_DATA_WIDTH ( AxiDataWidth ),
.AXI_ID_WIDTH ( AxiIdWidthMaster ),
.AXI_USER_WIDTH ( AxiUserWidth )
) slave[NBSlave-1:0]();
AXI_BUS #(
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
.AXI_DATA_WIDTH ( AxiDataWidth ),
.AXI_ID_WIDTH ( AxiIdWidthMaster ),
.AXI_USER_WIDTH ( AxiUserWidth )
) slave_slice[NBSlave-1:0]();
AXI_BUS #(
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
.AXI_DATA_WIDTH ( AxiDataWidth ),
.AXI_ID_WIDTH ( AxiIdWidthSlaves ),
.AXI_USER_WIDTH ( AxiUserWidth )
) master[NBMaster-1:0]();
// disable test-enable
logic test_en;
logic ndmreset;
logic ndmreset_n;
logic debug_req;
logic clk;
logic rst_n;
// DDR
logic c0_ddr4_ui_clk;
logic c0_init_calib_complete; // left open
logic c0_ddr4_ui_clk_sync_rst;
logic addn_ui_clkout1;
logic [3:0] s_axi_awid;
logic [31:0] s_axi_awaddr;
logic [7:0] s_axi_awlen;
logic [2:0] s_axi_awsize;
logic [1:0] s_axi_awburst;
logic [0:0] s_axi_awlock;
logic [3:0] s_axi_awcache;
logic [2:0] s_axi_awprot;
logic [3:0] s_axi_awregion;
logic [3:0] s_axi_awqos;
logic s_axi_awvalid;
logic s_axi_awready;
logic [63:0] s_axi_wdata;
logic [7:0] s_axi_wstrb;
logic s_axi_wlast;
logic s_axi_wvalid;
logic s_axi_wready;
logic [3:0] s_axi_bid;
logic [1:0] s_axi_bresp;
logic s_axi_bvalid;
logic s_axi_bready;
logic [3:0] s_axi_arid;
logic [31:0] s_axi_araddr;
logic [7:0] s_axi_arlen;
logic [2:0] s_axi_arsize;
logic [1:0] s_axi_arburst;
logic [0:0] s_axi_arlock;
logic [3:0] s_axi_arcache;
logic [2:0] s_axi_arprot;
logic [3:0] s_axi_arregion;
logic [3:0] s_axi_arqos;
logic s_axi_arvalid;
logic s_axi_arready;
logic [3:0] s_axi_rid;
logic [63:0] s_axi_rdata;
logic [1:0] s_axi_rresp;
logic s_axi_rlast;
logic s_axi_rvalid;
logic s_axi_rready;
logic [31:0] m_axi_awaddr;
logic [7:0] m_axi_awlen;
logic [2:0] m_axi_awsize;
logic [1:0] m_axi_awburst;
logic [0:0] m_axi_awlock;
logic [3:0] m_axi_awcache;
logic [2:0] m_axi_awprot;
logic [3:0] m_axi_awregion;
logic [3:0] m_axi_awqos;
logic m_axi_awvalid;
logic m_axi_awready;
logic [127:0] m_axi_wdata;
logic [15:0] m_axi_wstrb;
logic m_axi_wlast;
logic m_axi_wvalid;
logic m_axi_wready;
logic [1:0] m_axi_bresp;
logic m_axi_bvalid;
logic m_axi_bready;
logic [31:0] m_axi_araddr;
logic [7:0] m_axi_arlen;
logic [2:0] m_axi_arsize;
logic [1:0] m_axi_arburst;
logic [0:0] m_axi_arlock;
logic [3:0] m_axi_arcache;
logic [2:0] m_axi_arprot;
logic [3:0] m_axi_arregion;
logic [3:0] m_axi_arqos;
logic m_axi_arvalid;
logic m_axi_arready;
logic [127:0] m_axi_rdata;
logic [1:0] m_axi_rresp;
logic m_axi_rlast;
logic m_axi_rvalid;
logic m_axi_rready;
logic debug_req_valid;
logic debug_req_ready;
logic [6:0] debug_req_bits_addr;
logic [1:0] debug_req_bits_op;
logic [31:0] debug_req_bits_data;
logic debug_resp_valid;
logic debug_resp_ready;
logic [1:0] debug_resp_bits_resp;
logic [31:0] debug_resp_bits_data;
assign clk = addn_ui_clkout1;
assign rst_n = ~c0_ddr4_ui_clk_sync_rst;
assign test_en = 1'b0;
assign ndmreset_n = ~ndmreset ;
// Slice the AXI Masters (slave ports on the XBar)
for (genvar i = 0; i < NBSlave; i++) begin : slave_cut_gen
axi_cut #(
.ADDR_WIDTH ( AxiAddrWidth ),
.DATA_WIDTH ( AxiDataWidth ),
.ID_WIDTH ( AxiIdWidthMaster ),
.USER_WIDTH ( AxiUserWidth )
) i_axi_cut (
.clk_i ( clk ),
.rst_ni ( ndmreset_n ),
.in ( slave_slice[i] ),
.out ( slave[i] )
);
end
// ---------------
// AXI Xbar
// ---------------
axi_node_intf_wrap #(
// three ports from Ariane (instruction, data and bypass)
.NB_SLAVE ( NBSlave ),
.NB_MASTER ( NBMaster ), // debug unit, memory unit
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
.AXI_DATA_WIDTH ( AxiDataWidth ),
.AXI_USER_WIDTH ( AxiUserWidth ),
.AXI_ID_WIDTH ( AxiIdWidthMaster )
) i_axi_xbar (
.clk ( clk ),
.rst_n ( ndmreset_n ),
.test_en_i ( test_en ),
.slave ( slave ),
.master ( master ),
.start_addr_i ( {64'h0, RomBase, CacheStartAddr} ),
.end_addr_i ( {64'hFFF, RomBase + 64'hFFFF, CacheStartAddr + 2**24} )
);
dm::dmi_req_t debug_req;;
dm::dmi_resp_t debug_resp;
// ---------------
// Debug Module
// ---------------
dmi_jtag i_dmi_jtag (
.clk_i ( clk ),
.rst_ni ( rst_n ),
.dmi_rst_no ( ), // keep open
.dmi_req_valid_o ( debug_req_valid ),
.dmi_req_ready_i ( debug_req_ready ),
.dmi_req_o ( debug_req ),
.dmi_resp_valid_i ( debug_resp_valid ),
.dmi_resp_ready_o ( debug_resp_ready ),
.dmi_resp_i ( debug_resp ),
.tck_i ( tck ),
.tms_i ( tms ),
.trst_ni ( trst_n ),
.td_i ( tdi ),
.td_o ( tdo ),
.tdo_oe_o ( )
);
// debug module
dm_top #(
// current implementation only supports 1 hart
.NrHarts ( 1 ),
.AxiIdWidth ( AxiIdWidthSlaves ),
.AxiAddrWidth ( AxiAddrWidth ),
.AxiDataWidth ( AxiDataWidth ),
.AxiUserWidth ( AxiUserWidth )
) i_dm_top (
.clk_i ( clk ),
.rst_ni ( rst_n ), // PoR
.testmode_i ( test_en ),
.ndmreset_o ( ndmreset ),
.dmactive_o ( ), // active debug session
.debug_req_o ( debug_req ),
.unavailable_i ( '0 ),
.axi_master ( slave_slice[3] ),
.axi_slave ( master[2] ),
.dmi_rst_ni ( rst_n ),
.dmi_req_valid_i ( debug_req_valid ),
.dmi_req_ready_o ( debug_req_ready ),
.dmi_req_i ( debug_req ),
.dmi_resp_valid_o ( debug_resp_valid ),
.dmi_resp_ready_i ( debug_resp_ready ),
.dmi_resp_o ( debug_resp )
);
// ---------------
// Core
// ---------------
ariane #(
.CACHE_START_ADDR ( CacheStartAddr ),
.AXI_ID_WIDTH ( AxiIdWidthMaster ),
.AXI_USER_WIDTH ( AxiUserWidth )
) i_ariane (
.clk_i ( clk ),
.rst_ni ( ndmreset_n ),
.boot_addr_i ( RomBase ), // start fetching from ROM
.core_id_i ( '0 ),
.cluster_id_i ( '0 ),
.irq_i ( '0 ),
.ipi_i ( '0 ),
.time_irq_i ( '0 ),
.debug_req_i ( debug_req ),
.data_if ( slave_slice[2] ),
.bypass_if ( slave_slice[1] ),
.instr_if ( slave_slice[0] )
);
// ---------------
// ROM
// ---------------
logic rom_req;
logic [AxiAddrWidth-1:0] rom_addr;
logic [AxiDataWidth-1:0] rom_rdata;
axi2mem #(
.AXI_ID_WIDTH ( AxiIdWidthSlaves ),
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
.AXI_DATA_WIDTH ( AxiDataWidth ),
.AXI_USER_WIDTH ( AxiUserWidth )
) i_axi2rom (
.clk_i ( clk ),
.rst_ni ( ndmreset_n ),
.slave ( master[1] ),
.req_o ( rom_req ),
.we_o ( ),
.addr_o ( rom_addr ),
.be_o ( ),
.data_o ( ),
.data_i ( rom_rdata )
);
bootrom i_bootrom (
.clk_i ( clk ),
.req_i ( rom_req ),
.addr_i ( rom_addr ),
.rdata_o ( rom_rdata )
);
// DDR 4 Subsystem
axi_clock_converter_0 axi_clock_converter (
.s_axi_aclk(clk),
.s_axi_aresetn(ndmreset_n),
.s_axi_awid(master[0].aw_id),
.s_axi_awaddr(master[0].aw_addr),
.s_axi_awlen(master[0].aw_len),
.s_axi_awsize(master[0].aw_size),
.s_axi_awburst(master[0].aw_burst),
.s_axi_awlock(master[0].aw_lock),
.s_axi_awcache(master[0].aw_cache),
.s_axi_awprot(master[0].aw_prot),
.s_axi_awregion(master[0].aw_region),
.s_axi_awqos(master[0].aw_qos),
.s_axi_awvalid(master[0].aw_valid),
.s_axi_awready(master[0].aw_ready),
.s_axi_wdata(master[0].w_data),
.s_axi_wstrb(master[0].w_strb),
.s_axi_wlast(master[0].w_last),
.s_axi_wvalid(master[0].w_valid),
.s_axi_wready(master[0].w_ready),
.s_axi_bid(master[0].b_id),
.s_axi_bresp(master[0].b_resp),
.s_axi_bvalid(master[0].b_valid),
.s_axi_bready(master[0].b_ready),
.s_axi_arid(master[0].ar_id),
.s_axi_araddr(master[0].ar_addr[31:0]),
.s_axi_arlen(master[0].ar_len),
.s_axi_arsize(master[0].ar_size),
.s_axi_arburst(master[0].ar_burst),
.s_axi_arlock(master[0].ar_lock),
.s_axi_arcache(master[0].ar_cache),
.s_axi_arprot(master[0].ar_prot),
.s_axi_arregion(master[0].ar_region),
.s_axi_arqos(master[0].ar_qos),
.s_axi_arvalid(master[0].ar_valid),
.s_axi_arready(master[0].ar_ready),
.s_axi_rid(master[0].r_id),
.s_axi_rdata(master[0].r_data),
.s_axi_rresp(master[0].r_resp),
.s_axi_rlast(master[0].r_last),
.s_axi_rvalid(master[0].r_valid),
.s_axi_rready(master[0].r_ready),
// to size converter
.m_axi_aclk(c0_ddr4_ui_clk),
.m_axi_aresetn(ndmreset_n),
.m_axi_awid(s_axi_awid),
.m_axi_awaddr(s_axi_awaddr),
.m_axi_awlen(s_axi_awlen),
.m_axi_awsize(s_axi_awsize),
.m_axi_awburst(s_axi_awburst),
.m_axi_awlock(s_axi_awlock),
.m_axi_awcache(s_axi_awcache),
.m_axi_awprot(s_axi_awprot),
.m_axi_awregion(s_axi_awregion),
.m_axi_awqos(s_axi_awqos),
.m_axi_awvalid(s_axi_awvalid),
.m_axi_awready(s_axi_awready),
.m_axi_wdata(s_axi_wdata),
.m_axi_wstrb(s_axi_wstrb),
.m_axi_wlast(s_axi_wlast),
.m_axi_wvalid(s_axi_wvalid),
.m_axi_wready(s_axi_wready),
.m_axi_bid(s_axi_bid),
.m_axi_bresp(s_axi_bresp),
.m_axi_bvalid(s_axi_bvalid),
.m_axi_bready(s_axi_bready),
.m_axi_arid(s_axi_arid),
.m_axi_araddr(s_axi_araddr),
.m_axi_arlen(s_axi_arlen),
.m_axi_arsize(s_axi_arsize),
.m_axi_arburst(s_axi_arburst),
.m_axi_arlock(s_axi_arlock),
.m_axi_arcache(s_axi_arcache),
.m_axi_arprot(s_axi_arprot),
.m_axi_arregion(s_axi_arregion),
.m_axi_arqos(s_axi_arqos),
.m_axi_arvalid(s_axi_arvalid),
.m_axi_arready(s_axi_arready),
.m_axi_rid(s_axi_rid),
.m_axi_rdata(s_axi_rdata),
.m_axi_rresp(s_axi_rresp),
.m_axi_rlast(s_axi_rlast),
.m_axi_rvalid(s_axi_rvalid),
.m_axi_rready(s_axi_rready)
);
axi_dwidth_converter_0 axi_size_converter (
.s_axi_aclk(c0_ddr4_ui_clk),
.s_axi_aresetn(ndmreset_n),
.s_axi_awid,
.s_axi_awaddr,
.s_axi_awlen,
.s_axi_awsize,
.s_axi_awburst,
.s_axi_awlock,
.s_axi_awcache,
.s_axi_awprot,
.s_axi_awregion,
.s_axi_awqos,
.s_axi_awvalid,
.s_axi_awready,
.s_axi_wdata,
.s_axi_wstrb,
.s_axi_wlast,
.s_axi_wvalid,
.s_axi_wready,
.s_axi_bid,
.s_axi_bresp,
.s_axi_bvalid,
.s_axi_bready,
.s_axi_arid,
.s_axi_araddr,
.s_axi_arlen,
.s_axi_arsize,
.s_axi_arburst,
.s_axi_arlock,
.s_axi_arcache,
.s_axi_arprot,
.s_axi_arregion,
.s_axi_arqos,
.s_axi_arvalid,
.s_axi_arready,
.s_axi_rid,
.s_axi_rdata,
.s_axi_rresp,
.s_axi_rlast,
.s_axi_rvalid,
.s_axi_rready,
.m_axi_awaddr,
.m_axi_awlen,
.m_axi_awsize,
.m_axi_awburst,
.m_axi_awlock,
.m_axi_awcache,
.m_axi_awprot,
.m_axi_awregion,
.m_axi_awqos,
.m_axi_awvalid,
.m_axi_awready,
.m_axi_wdata,
.m_axi_wstrb,
.m_axi_wlast,
.m_axi_wvalid,
.m_axi_wready,
.m_axi_bresp,
.m_axi_bvalid,
.m_axi_bready,
.m_axi_araddr,
.m_axi_arlen,
.m_axi_arsize,
.m_axi_arburst,
.m_axi_arlock,
.m_axi_arcache,
.m_axi_arprot,
.m_axi_arregion,
.m_axi_arqos,
.m_axi_arvalid,
.m_axi_arready,
.m_axi_rdata,
.m_axi_rresp,
.m_axi_rlast,
.m_axi_rvalid,
.m_axi_rready
);
ddr4_0 ddr_i (
.sys_rst, // input
.c0_sys_clk_p,
.c0_sys_clk_n,
.c0_ddr4_act_n,
.c0_ddr4_adr,
.c0_ddr4_ba,
.c0_ddr4_bg,
.c0_ddr4_cke,
.c0_ddr4_odt,
.c0_ddr4_cs_n,
.c0_ddr4_ck_t,
.c0_ddr4_ck_c,
.c0_ddr4_reset_n,
.c0_ddr4_dm_dbi_n,
.c0_ddr4_dq,
.c0_ddr4_dqs_c,
.c0_ddr4_dqs_t,
.c0_init_calib_complete,
.c0_ddr4_ui_clk, // 1/4 of PHY clock, 300/4 = 75 MHz
.c0_ddr4_ui_clk_sync_rst,
.addn_ui_clkout1,
.dbg_clk(), // output
.c0_ddr4_aresetn(ndmreset_n),
.c0_ddr4_s_axi_awid('0),
.c0_ddr4_s_axi_awaddr(m_axi_awaddr),
.c0_ddr4_s_axi_awlen(m_axi_awlen),
.c0_ddr4_s_axi_awsize(m_axi_awsize),
.c0_ddr4_s_axi_awburst(m_axi_awburst),
.c0_ddr4_s_axi_awlock(m_axi_awlock),
.c0_ddr4_s_axi_awcache(m_axi_awcache),
.c0_ddr4_s_axi_awprot(m_axi_awprot),
.c0_ddr4_s_axi_awqos(m_axi_awqos),
.c0_ddr4_s_axi_awvalid(m_axi_awvalid),
.c0_ddr4_s_axi_awready(m_axi_awready),
.c0_ddr4_s_axi_wdata(m_axi_wdata),
.c0_ddr4_s_axi_wstrb(m_axi_wstrb),
.c0_ddr4_s_axi_wlast(m_axi_wlast),
.c0_ddr4_s_axi_wvalid(m_axi_wvalid),
.c0_ddr4_s_axi_wready(m_axi_wready),
.c0_ddr4_s_axi_bready(m_axi_bready),
.c0_ddr4_s_axi_bid(),
.c0_ddr4_s_axi_bresp(m_axi_bresp),
.c0_ddr4_s_axi_bvalid(m_axi_bvalid),
.c0_ddr4_s_axi_arid('0),
.c0_ddr4_s_axi_araddr(m_axi_araddr),
.c0_ddr4_s_axi_arlen(m_axi_arlen),
.c0_ddr4_s_axi_arsize(m_axi_arsize),
.c0_ddr4_s_axi_arburst(m_axi_arburst),
.c0_ddr4_s_axi_arlock(m_axi_arlock),
.c0_ddr4_s_axi_arcache(m_axi_arcache),
.c0_ddr4_s_axi_arprot(m_axi_arprot),
.c0_ddr4_s_axi_arqos(m_axi_arqos),
.c0_ddr4_s_axi_arvalid(m_axi_arvalid),
.c0_ddr4_s_axi_arready(m_axi_arready),
.c0_ddr4_s_axi_rready(m_axi_rready),
.c0_ddr4_s_axi_rid(),
.c0_ddr4_s_axi_rdata(m_axi_rdata),
.c0_ddr4_s_axi_rresp(m_axi_rresp),
.c0_ddr4_s_axi_rlast(m_axi_rlast),
.c0_ddr4_s_axi_rvalid(m_axi_rvalid),
.dbg_bus()
);
endmodule

View file

@ -0,0 +1,12 @@
## Common Ariane XDCs
create_clock -period 100.000 -name tck -waveform {0.000 50.000} [get_ports tck]
set_input_jitter tck 1.000
set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/data_src_q_reg*/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/data_dst_q_reg*/D] 10.000
set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_src/req_src_q_reg/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_resp/i_dst/req_dst_q_reg/D] 10.000
set_max_delay -datapath_only -from [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_dst/ack_dst_q_reg/C] -to [get_pins i_dmi_jtag/i_dmi_cdc/i_cdc_req/i_src/ack_src_q_reg/D] 10.000

View file

@ -0,0 +1,71 @@
## Buttons
set_property -dict {PACKAGE_PIN R19 IOSTANDARD LVCMOS33} [get_ports cpu_resetn]
## PMOD Header JC
set_property -dict {PACKAGE_PIN AC26 IOSTANDARD LVCMOS33} [get_ports tck]
set_property -dict {PACKAGE_PIN AJ27 IOSTANDARD LVCMOS33} [get_ports tdi]
set_property -dict {PACKAGE_PIN AH30 IOSTANDARD LVCMOS33} [get_ports tdo]
set_property -dict {PACKAGE_PIN AK29 IOSTANDARD LVCMOS33} [get_ports tms]
set_property -dict {PACKAGE_PIN AD26 IOSTANDARD LVCMOS33} [get_ports trst_n]
## UART
set_property -dict {PACKAGE_PIN Y23 IOSTANDARD LVCMOS33} [get_ports tx]
set_property -dict {PACKAGE_PIN Y20 IOSTANDARD LVCMOS33} [get_ports rx]
# accept sub-optimal placement
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets tck_IBUF]
## LEDs
set_property -dict {PACKAGE_PIN T28 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN V19 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN U30 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN U29 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN V26 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN W24 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
set_property -dict {PACKAGE_PIN W23 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
## Switches
set_property -dict {PACKAGE_PIN G19 IOSTANDARD LVCMOS12} [get_ports {sw[0]}]
set_property -dict {PACKAGE_PIN G25 IOSTANDARD LVCMOS12} [get_ports {sw[1]}]
set_property -dict {PACKAGE_PIN H24 IOSTANDARD LVCMOS12} [get_ports {sw[2]}]
set_property -dict {PACKAGE_PIN K19 IOSTANDARD LVCMOS12} [get_ports {sw[3]}]
set_property -dict {PACKAGE_PIN N19 IOSTANDARD LVCMOS12} [get_ports {sw[4]}]
set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS12} [get_ports {sw[5]}]
set_property -dict {PACKAGE_PIN P26 IOSTANDARD LVCMOS33} [get_ports {sw[6]}]
set_property -dict {PACKAGE_PIN P27 IOSTANDARD LVCMOS33} [get_ports {sw[7]}]
## Fan Control
set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS33} [get_ports fan_pwm]
#set_property -dict { PACKAGE_PIN V21 IOSTANDARD LVCMOS33 } [get_ports { FAN_TACH }]; #IO_L22P_T3_A05_D21_14 Sch=fan_tac
## Ethernet
set_property -dict {PACKAGE_PIN AH24 IOSTANDARD LVCMOS33} [get_ports { eth_rst_n }]; #IO_L14N_T2_SRCC_12 Sch=eth_phyrst_n
set_property -dict {PACKAGE_PIN AK14 IOSTANDARD LVCMOS15} [get_ports { eth_tx_en }]; #IO_L20P_T3_33 Sch=eth_tx_en
set_property -dict {PACKAGE_PIN AG10 IOSTANDARD LVCMOS15} [get_ports { eth_rxck }]; #IO_L13P_T2_MRCC_33 Sch=eth_rx_clk
set_property -dict {PACKAGE_PIN AJ12 IOSTANDARD LVCMOS15} [get_ports { eth_txd[0] }]; #IO_L22N_T3_33 Sch=eth_tx_d[0]
set_property -dict {PACKAGE_PIN AK11 IOSTANDARD LVCMOS15} [get_ports { eth_txd[1] }]; #IO_L17P_T2_33 Sch=eth_tx_d[1]
set_property -dict {PACKAGE_PIN AJ11 IOSTANDARD LVCMOS15} [get_ports { eth_txd[2] }]; #IO_L18N_T2_33 Sch=eth_tx_d[2]
set_property -dict {PACKAGE_PIN AK10 IOSTANDARD LVCMOS15} [get_ports { eth_txd[3] }]; #IO_L17N_T2_33 Sch=eth_tx_d[3]
set_property -dict {PACKAGE_PIN AJ14 IOSTANDARD LVCMOS15} [get_ports { eth_rxd[0] }]; #IO_L21N_T3_DQS_33 Sch=eth_rx_d[0]
set_property -dict {PACKAGE_PIN AH14 IOSTANDARD LVCMOS15} [get_ports { eth_rxd[1] }]; #IO_L21P_T3_DQS_33 Sch=eth_rx_d[1]
set_property -dict {PACKAGE_PIN AK13 IOSTANDARD LVCMOS15} [get_ports { eth_rxd[2] }]; #IO_L20N_T3_33 Sch=eth_rx_d[2]
set_property -dict {PACKAGE_PIN AJ13 IOSTANDARD LVCMOS15} [get_ports { eth_rxd[3] }]; #IO_L22P_T3_33 Sch=eth_rx_d[3]
set_property -dict {PACKAGE_PIN AE10 IOSTANDARD LVCMOS15} [get_ports { eth_txck }]; #IO_L14P_T2_SRCC_33 Sch=eth_tx_clk
set_property -dict {PACKAGE_PIN AF12 IOSTANDARD LVCMOS15} [get_ports { eth_mdc }]; #IO_L23P_T3_33 Sch=eth_mdc
set_property -dict {PACKAGE_PIN AG12 IOSTANDARD LVCMOS15} [get_ports { eth_mdio }]; #IO_L23N_T3_33 Sch=eth_mdio
set_property -dict {PACKAGE_PIN AH11 IOSTANDARD LVCMOS15} [get_ports { eth_rxctl }]; #IO_L18P_T2_33 Sch=eth_rx_ctl
# set_property -dict {PACKAGE_PIN AK15 IOSTANDARD LVCMOS18} [get_ports { eth_pme_b }]; #IO_L1N_T0_32 Sch=eth_pmeb
# set_property -dict {PACKAGE_PIN AK16 IOSTANDARD LVCMOS18} [get_ports { eth_int_b }]; #IO_L1P_T0_32 Sch=eth_intb
## SD Card
set_property -dict {PACKAGE_PIN R28 IOSTANDARD LVCMOS33} [get_ports spi_clk_o]
set_property -dict {PACKAGE_PIN T30 IOSTANDARD LVCMOS33} [get_ports spi_ss]
set_property -dict {PACKAGE_PIN R26 IOSTANDARD LVCMOS33} [get_ports spi_miso]
set_property -dict {PACKAGE_PIN R29 IOSTANDARD LVCMOS33} [get_ports spi_mosi]
set_property -dict {PACKAGE_PIN U27 IOSTANDARD LVCMOS33} [get_ports spi_clk_o_2]
set_property -dict {PACKAGE_PIN U28 IOSTANDARD LVCMOS33} [get_ports spi_ss_2]
set_property -dict {PACKAGE_PIN T26 IOSTANDARD LVCMOS33} [get_ports spi_miso_2]
set_property -dict {PACKAGE_PIN T27 IOSTANDARD LVCMOS33} [get_ports spi_mosi_2]

1990
fpga/constraints/vcu118.xdc Normal file

File diff suppressed because it is too large Load diff

31
fpga/scripts/program.tcl Normal file
View file

@ -0,0 +1,31 @@
# Copyright 2018 ETH Zurich and University of Bologna.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# 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.
# Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
# Description: Program Genesys II
open_hw
connect_hw_server -url localhost:3121
current_hw_target [get_hw_targets */xilinx_tcf/Digilent/210203A25514A]
set_property PARAM.FREQUENCY 15000000 [get_hw_targets */xilinx_tcf/Digilent/210203A25514A]
open_hw_target
set_property PROGRAM.FILE {/home/zarubaf/kerbin/fpga/kerbin/kerbin.runs/impl_1/kerbin.bit} [get_hw_devices xc7vx485t_0]
current_hw_device [get_hw_devices xc7vx485t_0]
refresh_hw_device -update_hw_probes false [lindex [get_hw_devices xc7vx485t_0] 0]
set_property PROBES.FILE {} [get_hw_devices xc7vx485t_0]
set_property FULL_PROBES.FILE {} [get_hw_devices xc7vx485t_0]
set_property PROGRAM.FILE {/home/zarubaf/kerbin/fpga/kerbin/kerbin.runs/impl_1/kerbin.bit} [get_hw_devices xc7vx485t_0]
program_hw_devices [get_hw_devices xc7vx485t_0]

94
fpga/scripts/run.tcl Normal file
View file

@ -0,0 +1,94 @@
# Copyright 2018 ETH Zurich and University of Bologna.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# 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.
# Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
set project ariane
create_project $project . -force -part $::env(XILINX_PART)
set_property board_part $::env(XILINX_BOARD) [current_project]
# set number of threads to 8 (maximum, unfortunately)
set_param general.maxThreads 8
set_msg_config -id {[Synth 8-5858]} -new_severity "info"
# hard-coded to Genesys 2 for the moment
add_files -fileset constrs_1 -norecurse constraints/genesys-2.xdc
read_ip xilinx/xlnx_mig_7_ddr3/ip/xlnx_mig_7_ddr3.xci
read_ip xilinx/xlnx_axi_clock_converter/ip/xlnx_axi_clock_converter.xci
read_ip xilinx/xlnx_axi_dwidth_converter/ip/xlnx_axi_dwidth_converter.xci
read_ip xilinx/xlnx_axi_ethernetlite/ip/xlnx_axi_ethernetlite.xci
read_ip xilinx/xlnx_axi_quad_spi/ip/xlnx_axi_quad_spi.xci
read_ip xilinx/xlnx_clk_gen/ip/xlnx_clk_gen.xci
source scripts/add_sources.tcl
set_property top ariane_xilinx [current_fileset]
if {$::env(BOARD) eq "genesys2"} {
read_verilog -sv {src/genesysii.svh}
set file "src/genesysii.svh"
} else {
exit 1
}
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
set_property -dict { file_type {Verilog Header} is_global_include 1} -objects $file_obj
update_compile_order -fileset sources_1
update_compile_order -fileset sim_1
add_files -fileset constrs_1 -norecurse constraints/$project.xdc
# synth_design -retiming -rtl -name rtl_1 -verilog_define SYNTHESIS -verilog_define
synth_design -rtl -name rtl_1
launch_runs synth_1
wait_on_run synth_1
open_run synth_1
exec mkdir -p reports/
exec rm -rf reports/*
check_timing -file reports/$project.check_timing.rpt
report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports/$project.timing_WORST_100.rpt
report_timing -nworst 1 -delay_type max -sort_by group -file reports/$project.timing.rpt
report_utilization -hierarchical -file reports/$project.utilization.rpt
report_cdc -file reports/$project.cdc.rpt
report_clock_interaction -file reports/$project.clock_interaction.rpt
# set for RuntimeOptimized implementation
set_property "steps.place_design.args.directive" "RuntimeOptimized" [get_runs impl_1]
set_property "steps.route_design.args.directive" "RuntimeOptimized" [get_runs impl_1]
launch_runs impl_1
wait_on_run impl_1
launch_runs impl_1 -to_step write_bitstream
wait_on_run impl_1
open_run impl_1
# output Verilog netlist + SDC for timing simulation
write_verilog -force -mode funcsim work-fpga/${project}_funcsim.v
write_verilog -force -mode timesim work-fpga/${project}_timesim.v
write_sdf -force work-fpga/${project}_timesim.sdf
# reports
exec mkdir -p reports/
exec rm -rf reports/*
check_timing -file reports/${project}.check_timing.rpt
report_timing -max_paths 100 -nworst 100 -delay_type max -sort_by slack -file reports/${project}.timing_WORST_100.rpt
report_timing -nworst 1 -delay_type max -sort_by group -file reports/${project}.timing.rpt
report_utilization -hierarchical -file reports/${project}.utilization.rpt

View file

@ -0,0 +1,21 @@
# Copyright 2018 ETH Zurich and University of Bologna.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# 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.
# Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
# Description: Generate a memory configuration file from a bitstream (Genesys II only right now)
lassign $argv mcsfile bitfile
# https://scholar.princeton.edu/jbalkind/blog/programming-genesys-2-qspi-spi-x4-flash
write_cfgmem -format mcs -interface SPIx4 -size 256 -loadbit "up 0x0 $bitfile" -file $mcsfile -force

14
fpga/sourceme.sh Normal file
View file

@ -0,0 +1,14 @@
#!/bin/bash
# genesys2
if [ -z "${BOARD}" ]; then
export BOARD="genesys2"
fi
if [ "$BOARD" = "genesys2" ]; then
echo -n "Configuring for "
echo "Genesys II"
export XILINX_PART="xc7k325tffg900-2"
export XILINX_BOARD="digilentinc.com:genesys2:part0:1.1"
export CLK_PERIOD_NS="20"
fi

1
fpga/src/apb_node Submodule

@ -0,0 +1 @@
Subproject commit 157e5f00a37440d53f2e5b3aabfc9d454530e688

1
fpga/src/apb_uart Submodule

@ -0,0 +1 @@
Subproject commit ac3461ce23832e02903b9d2d7d4edd7fcb89bd92

View file

@ -0,0 +1,659 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
// Xilinx Peripehrals
module ariane_peripherals #(
parameter int AxiAddrWidth = -1,
parameter int AxiDataWidth = -1,
parameter int AxiIdWidth = -1,
parameter int AxiUserWidth = 1,
parameter bit InclUART = 1,
parameter bit InclSPI = 0,
parameter bit InclEthernet = 0
) (
input logic clk_i , // Clock
input logic rst_ni , // Asynchronous reset active low
AXI_BUS.in plic ,
AXI_BUS.in uart ,
AXI_BUS.in spi ,
AXI_BUS.in ethernet ,
output logic [1:0] irq_o ,
// UART
input logic rx_i ,
output logic tx_o ,
// Ethernet
input wire eth_txck ,
input wire eth_rxck ,
input wire eth_rxctl ,
input wire [3:0] eth_rxd ,
output wire eth_rst_n ,
output wire eth_tx_en ,
output wire [3:0] eth_txd ,
// MDIO Interface
inout wire eth_mdio ,
output logic eth_mdc ,
// SPI
output logic spi_clk_o ,
output logic spi_mosi ,
input logic spi_miso ,
output logic spi_ss
);
// ---------------
// 1. PLIC
// ---------------
logic [ariane_soc::NumSources-1:0] irq_sources;
REG_BUS #(
.ADDR_WIDTH ( 32 ),
.DATA_WIDTH ( 32 )
) reg_bus (clk_i);
logic plic_penable;
logic plic_pwrite;
logic [31:0] plic_paddr;
logic plic_psel;
logic [31:0] plic_pwdata;
logic [31:0] plic_prdata;
logic plic_pready;
logic plic_pslverr;
axi2apb_64_32 #(
.AXI4_ADDRESS_WIDTH ( AxiAddrWidth ),
.AXI4_RDATA_WIDTH ( AxiDataWidth ),
.AXI4_WDATA_WIDTH ( AxiDataWidth ),
.AXI4_ID_WIDTH ( AxiIdWidth ),
.AXI4_USER_WIDTH ( AxiUserWidth ),
.BUFF_DEPTH_SLAVE ( 2 ),
.APB_ADDR_WIDTH ( 32 )
) i_axi2apb_64_32_plic (
.ACLK ( clk_i ),
.ARESETn ( rst_ni ),
.test_en_i ( 1'b0 ),
.AWID_i ( plic.aw_id ),
.AWADDR_i ( plic.aw_addr ),
.AWLEN_i ( plic.aw_len ),
.AWSIZE_i ( plic.aw_size ),
.AWBURST_i ( plic.aw_burst ),
.AWLOCK_i ( plic.aw_lock ),
.AWCACHE_i ( plic.aw_cache ),
.AWPROT_i ( plic.aw_prot ),
.AWREGION_i( plic.aw_region ),
.AWUSER_i ( plic.aw_user ),
.AWQOS_i ( plic.aw_qos ),
.AWVALID_i ( plic.aw_valid ),
.AWREADY_o ( plic.aw_ready ),
.WDATA_i ( plic.w_data ),
.WSTRB_i ( plic.w_strb ),
.WLAST_i ( plic.w_last ),
.WUSER_i ( plic.w_user ),
.WVALID_i ( plic.w_valid ),
.WREADY_o ( plic.w_ready ),
.BID_o ( plic.b_id ),
.BRESP_o ( plic.b_resp ),
.BVALID_o ( plic.b_valid ),
.BUSER_o ( plic.b_user ),
.BREADY_i ( plic.b_ready ),
.ARID_i ( plic.ar_id ),
.ARADDR_i ( plic.ar_addr ),
.ARLEN_i ( plic.ar_len ),
.ARSIZE_i ( plic.ar_size ),
.ARBURST_i ( plic.ar_burst ),
.ARLOCK_i ( plic.ar_lock ),
.ARCACHE_i ( plic.ar_cache ),
.ARPROT_i ( plic.ar_prot ),
.ARREGION_i( plic.ar_region ),
.ARUSER_i ( plic.ar_user ),
.ARQOS_i ( plic.ar_qos ),
.ARVALID_i ( plic.ar_valid ),
.ARREADY_o ( plic.ar_ready ),
.RID_o ( plic.r_id ),
.RDATA_o ( plic.r_data ),
.RRESP_o ( plic.r_resp ),
.RLAST_o ( plic.r_last ),
.RUSER_o ( plic.r_user ),
.RVALID_o ( plic.r_valid ),
.RREADY_i ( plic.r_ready ),
.PENABLE ( plic_penable ),
.PWRITE ( plic_pwrite ),
.PADDR ( plic_paddr ),
.PSEL ( plic_psel ),
.PWDATA ( plic_pwdata ),
.PRDATA ( plic_prdata ),
.PREADY ( plic_pready ),
.PSLVERR ( plic_pslverr )
);
apb_to_reg i_apb_to_reg (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.penable_i ( plic_penable ),
.pwrite_i ( plic_pwrite ),
.paddr_i ( plic_paddr ),
.psel_i ( plic_psel ),
.pwdata_i ( plic_pwdata ),
.prdata_o ( plic_prdata ),
.pready_o ( plic_pready ),
.pslverr_o ( plic_pslverr ),
.reg_o ( reg_bus )
);
plic #(
.ID_BITWIDTH ( ariane_soc::PLICIdWidth ),
.PARAMETER_BITWIDTH ( ariane_soc::ParameterBitwidth ),
.NUM_TARGETS ( ariane_soc::NumTargets ),
.NUM_SOURCES ( ariane_soc::NumSources )
) i_plic (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.irq_sources_i ( irq_sources ),
.eip_targets_o ( irq_o ),
.external_bus_io ( reg_bus )
);
// ---------------
// 2. UART
// ---------------
logic uart_penable;
logic uart_pwrite;
logic [31:0] uart_paddr;
logic uart_psel;
logic [31:0] uart_pwdata;
logic [31:0] uart_prdata;
logic uart_pready;
logic uart_pslverr;
axi2apb_64_32 #(
.AXI4_ADDRESS_WIDTH ( AxiAddrWidth ),
.AXI4_RDATA_WIDTH ( AxiDataWidth ),
.AXI4_WDATA_WIDTH ( AxiDataWidth ),
.AXI4_ID_WIDTH ( AxiIdWidth ),
.AXI4_USER_WIDTH ( AxiUserWidth ),
.BUFF_DEPTH_SLAVE ( 2 ),
.APB_ADDR_WIDTH ( 32 )
) i_axi2apb_64_32_uart (
.ACLK ( clk_i ),
.ARESETn ( rst_ni ),
.test_en_i ( 1'b0 ),
.AWID_i ( uart.aw_id ),
.AWADDR_i ( uart.aw_addr ),
.AWLEN_i ( uart.aw_len ),
.AWSIZE_i ( uart.aw_size ),
.AWBURST_i ( uart.aw_burst ),
.AWLOCK_i ( uart.aw_lock ),
.AWCACHE_i ( uart.aw_cache ),
.AWPROT_i ( uart.aw_prot ),
.AWREGION_i( uart.aw_region ),
.AWUSER_i ( uart.aw_user ),
.AWQOS_i ( uart.aw_qos ),
.AWVALID_i ( uart.aw_valid ),
.AWREADY_o ( uart.aw_ready ),
.WDATA_i ( uart.w_data ),
.WSTRB_i ( uart.w_strb ),
.WLAST_i ( uart.w_last ),
.WUSER_i ( uart.w_user ),
.WVALID_i ( uart.w_valid ),
.WREADY_o ( uart.w_ready ),
.BID_o ( uart.b_id ),
.BRESP_o ( uart.b_resp ),
.BVALID_o ( uart.b_valid ),
.BUSER_o ( uart.b_user ),
.BREADY_i ( uart.b_ready ),
.ARID_i ( uart.ar_id ),
.ARADDR_i ( uart.ar_addr ),
.ARLEN_i ( uart.ar_len ),
.ARSIZE_i ( uart.ar_size ),
.ARBURST_i ( uart.ar_burst ),
.ARLOCK_i ( uart.ar_lock ),
.ARCACHE_i ( uart.ar_cache ),
.ARPROT_i ( uart.ar_prot ),
.ARREGION_i( uart.ar_region ),
.ARUSER_i ( uart.ar_user ),
.ARQOS_i ( uart.ar_qos ),
.ARVALID_i ( uart.ar_valid ),
.ARREADY_o ( uart.ar_ready ),
.RID_o ( uart.r_id ),
.RDATA_o ( uart.r_data ),
.RRESP_o ( uart.r_resp ),
.RLAST_o ( uart.r_last ),
.RUSER_o ( uart.r_user ),
.RVALID_o ( uart.r_valid ),
.RREADY_i ( uart.r_ready ),
.PENABLE ( uart_penable ),
.PWRITE ( uart_pwrite ),
.PADDR ( uart_paddr ),
.PSEL ( uart_psel ),
.PWDATA ( uart_pwdata ),
.PRDATA ( uart_prdata ),
.PREADY ( uart_pready ),
.PSLVERR ( uart_pslverr )
);
if (InclUART) begin : gen_uart
apb_uart i_apb_uart (
.CLK ( clk_i ),
.RSTN ( rst_ni ),
.PSEL ( uart_psel ),
.PENABLE ( uart_penable ),
.PWRITE ( uart_pwrite ),
.PADDR ( uart_paddr[4:2] ),
.PWDATA ( uart_pwdata ),
.PRDATA ( uart_prdata ),
.PREADY ( uart_pready ),
.PSLVERR ( uart_pslverr ),
.INT ( irq_sources[0] ),
.OUT1N ( ), // keep open
.OUT2N ( ), // keep open
.RTSN ( ), // no flow control
.DTRN ( ), // no flow control
.CTSN ( 1'b0 ),
.DSRN ( 1'b0 ),
.DCDN ( 1'b0 ),
.RIN ( 1'b0 ),
.SIN ( rx_i ),
.SOUT ( tx_o )
);
end else begin
/* pragma translate_off */
`ifndef VERILATOR
mock_uart i_mock_uart (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.penable_i ( uart_penable ),
.pwrite_i ( uart_pwrite ),
.paddr_i ( uart_paddr ),
.psel_i ( uart_psel ),
.pwdata_i ( uart_pwdata ),
.prdata_o ( uart_prdata ),
.pready_o ( uart_pready ),
.pslverr_o ( uart_pslverr )
);
`endif
/* pragma translate_on */
end
// ---------------
// 3. SPI
// ---------------
assign spi.b_user = 1'b0;
assign spi.r_user = 1'b0;
if (InclSPI) begin : gen_spi
logic [31:0] s_axi_spi_awaddr;
logic [7:0] s_axi_spi_awlen;
logic [2:0] s_axi_spi_awsize;
logic [1:0] s_axi_spi_awburst;
logic [0:0] s_axi_spi_awlock;
logic [3:0] s_axi_spi_awcache;
logic [2:0] s_axi_spi_awprot;
logic [3:0] s_axi_spi_awregion;
logic [3:0] s_axi_spi_awqos;
logic s_axi_spi_awvalid;
logic s_axi_spi_awready;
logic [31:0] s_axi_spi_wdata;
logic [3:0] s_axi_spi_wstrb;
logic s_axi_spi_wlast;
logic s_axi_spi_wvalid;
logic s_axi_spi_wready;
logic [1:0] s_axi_spi_bresp;
logic s_axi_spi_bvalid;
logic s_axi_spi_bready;
logic [31:0] s_axi_spi_araddr;
logic [7:0] s_axi_spi_arlen;
logic [2:0] s_axi_spi_arsize;
logic [1:0] s_axi_spi_arburst;
logic [0:0] s_axi_spi_arlock;
logic [3:0] s_axi_spi_arcache;
logic [2:0] s_axi_spi_arprot;
logic [3:0] s_axi_spi_arregion;
logic [3:0] s_axi_spi_arqos;
logic s_axi_spi_arvalid;
logic s_axi_spi_arready;
logic [31:0] s_axi_spi_rdata;
logic [1:0] s_axi_spi_rresp;
logic s_axi_spi_rlast;
logic s_axi_spi_rvalid;
logic s_axi_spi_rready;
xlnx_axi_dwidth_converter i_xlnx_axi_dwidth_converter_spi (
.s_axi_aclk ( clk_i ),
.s_axi_aresetn ( rst_ni ),
.s_axi_awid ( spi.aw_id ),
.s_axi_awaddr ( spi.aw_addr[31:0] ),
.s_axi_awlen ( spi.aw_len ),
.s_axi_awsize ( spi.aw_size ),
.s_axi_awburst ( spi.aw_burst ),
.s_axi_awlock ( spi.aw_lock ),
.s_axi_awcache ( spi.aw_cache ),
.s_axi_awprot ( spi.aw_prot ),
.s_axi_awregion ( spi.aw_region ),
.s_axi_awqos ( spi.aw_qos ),
.s_axi_awvalid ( spi.aw_valid ),
.s_axi_awready ( spi.aw_ready ),
.s_axi_wdata ( spi.w_data ),
.s_axi_wstrb ( spi.w_strb ),
.s_axi_wlast ( spi.w_last ),
.s_axi_wvalid ( spi.w_valid ),
.s_axi_wready ( spi.w_ready ),
.s_axi_bid ( spi.b_id ),
.s_axi_bresp ( spi.b_resp ),
.s_axi_bvalid ( spi.b_valid ),
.s_axi_bready ( spi.b_ready ),
.s_axi_arid ( spi.ar_id ),
.s_axi_araddr ( spi.ar_addr[31:0] ),
.s_axi_arlen ( spi.ar_len ),
.s_axi_arsize ( spi.ar_size ),
.s_axi_arburst ( spi.ar_burst ),
.s_axi_arlock ( spi.ar_lock ),
.s_axi_arcache ( spi.ar_cache ),
.s_axi_arprot ( spi.ar_prot ),
.s_axi_arregion ( spi.ar_region ),
.s_axi_arqos ( spi.ar_qos ),
.s_axi_arvalid ( spi.ar_valid ),
.s_axi_arready ( spi.ar_ready ),
.s_axi_rid ( spi.r_id ),
.s_axi_rdata ( spi.r_data ),
.s_axi_rresp ( spi.r_resp ),
.s_axi_rlast ( spi.r_last ),
.s_axi_rvalid ( spi.r_valid ),
.s_axi_rready ( spi.r_ready ),
.m_axi_awaddr ( s_axi_spi_awaddr ),
.m_axi_awlen ( s_axi_spi_awlen ),
.m_axi_awsize ( s_axi_spi_awsize ),
.m_axi_awburst ( s_axi_spi_awburst ),
.m_axi_awlock ( s_axi_spi_awlock ),
.m_axi_awcache ( s_axi_spi_awcache ),
.m_axi_awprot ( s_axi_spi_awprot ),
.m_axi_awregion ( s_axi_spi_awregion ),
.m_axi_awqos ( s_axi_spi_awqos ),
.m_axi_awvalid ( s_axi_spi_awvalid ),
.m_axi_awready ( s_axi_spi_awready ),
.m_axi_wdata ( s_axi_spi_wdata ),
.m_axi_wstrb ( s_axi_spi_wstrb ),
.m_axi_wlast ( s_axi_spi_wlast ),
.m_axi_wvalid ( s_axi_spi_wvalid ),
.m_axi_wready ( s_axi_spi_wready ),
.m_axi_bresp ( s_axi_spi_bresp ),
.m_axi_bvalid ( s_axi_spi_bvalid ),
.m_axi_bready ( s_axi_spi_bready ),
.m_axi_araddr ( s_axi_spi_araddr ),
.m_axi_arlen ( s_axi_spi_arlen ),
.m_axi_arsize ( s_axi_spi_arsize ),
.m_axi_arburst ( s_axi_spi_arburst ),
.m_axi_arlock ( s_axi_spi_arlock ),
.m_axi_arcache ( s_axi_spi_arcache ),
.m_axi_arprot ( s_axi_spi_arprot ),
.m_axi_arregion ( s_axi_spi_arregion ),
.m_axi_arqos ( s_axi_spi_arqos ),
.m_axi_arvalid ( s_axi_spi_arvalid ),
.m_axi_arready ( s_axi_spi_arready ),
.m_axi_rdata ( s_axi_spi_rdata ),
.m_axi_rresp ( s_axi_spi_rresp ),
.m_axi_rlast ( s_axi_spi_rlast ),
.m_axi_rvalid ( s_axi_spi_rvalid ),
.m_axi_rready ( s_axi_spi_rready )
);
xlnx_axi_quad_spi i_xlnx_axi_quad_spi (
.ext_spi_clk ( clk_i ),
.s_axi4_aclk ( clk_i ),
.s_axi4_aresetn ( rst_ni ),
.s_axi4_awaddr ( s_axi_spi_awaddr[23:0] ),
.s_axi4_awlen ( s_axi_spi_awlen ),
.s_axi4_awsize ( s_axi_spi_awsize ),
.s_axi4_awburst ( s_axi_spi_awburst ),
.s_axi4_awlock ( s_axi_spi_awlock ),
.s_axi4_awcache ( s_axi_spi_awcache ),
.s_axi4_awprot ( s_axi_spi_awprot ),
.s_axi4_awvalid ( s_axi_spi_awvalid ),
.s_axi4_awready ( s_axi_spi_awready ),
.s_axi4_wdata ( s_axi_spi_wdata ),
.s_axi4_wstrb ( s_axi_spi_wstrb ),
.s_axi4_wlast ( s_axi_spi_wlast ),
.s_axi4_wvalid ( s_axi_spi_wvalid ),
.s_axi4_wready ( s_axi_spi_wready ),
.s_axi4_bresp ( s_axi_spi_bresp ),
.s_axi4_bvalid ( s_axi_spi_bvalid ),
.s_axi4_bready ( s_axi_spi_bready ),
.s_axi4_araddr ( s_axi_spi_araddr[23:0] ),
.s_axi4_arlen ( s_axi_spi_arlen ),
.s_axi4_arsize ( s_axi_spi_arsize ),
.s_axi4_arburst ( s_axi_spi_arburst ),
.s_axi4_arlock ( s_axi_spi_arlock ),
.s_axi4_arcache ( s_axi_spi_arcache ),
.s_axi4_arprot ( s_axi_spi_arprot ),
.s_axi4_arvalid ( s_axi_spi_arvalid ),
.s_axi4_arready ( s_axi_spi_arready ),
.s_axi4_rdata ( s_axi_spi_rdata ),
.s_axi4_rresp ( s_axi_spi_rresp ),
.s_axi4_rlast ( s_axi_spi_rlast ),
.s_axi4_rvalid ( s_axi_spi_rvalid ),
.s_axi4_rready ( s_axi_spi_rready ),
.io0_i ( '0 ),
.io0_o ( spi_mosi ),
.io0_t ( ),
.io1_i ( spi_miso ),
.io1_o ( ),
.io1_t ( ),
.ss_i ( '0 ),
.ss_o ( spi_ss ),
.ss_t ( ),
.sck_o ( spi_clk_o ),
.sck_i ( '0 ),
.sck_t ( ),
.ip2intc_irpt ( irq_sources[1] )
);
end else begin
assign spi_clk_o = 1'b0;
assign spi_mosi = 1'b0;
assign spi_ss = 1'b0;
assign irq_sources [1] = 1'b0;
assign spi.aw_ready = 1'b1;
assign spi.ar_ready = 1'b1;
assign spi.w_ready = 1'b1;
assign spi.b_valid = spi.aw_valid;
assign spi.b_id = spi.aw_id;
assign spi.b_resp = axi_pkg::RESP_SLVERR;
assign spi.b_user = '0;
assign spi.r_valid = spi.ar_valid;
assign spi.r_resp = axi_pkg::RESP_SLVERR;
assign spi.r_data = 'hdeadbeef;
assign spi.r_last = 1'b1;
end
// ---------------
// 4. Ethernet
// ---------------
assign ethernet.b_user = 1'b0;
assign ethernet.r_user = 1'b0;
if (InclEthernet) begin : gen_ethernet
wire mdio_i, mdio_o, mdio_t;
logic [31:0] s_axi_eth_awaddr;
logic [7:0] s_axi_eth_awlen;
logic [2:0] s_axi_eth_awsize;
logic [1:0] s_axi_eth_awburst;
logic [3:0] s_axi_eth_awcache;
logic s_axi_eth_awvalid;
logic s_axi_eth_awready;
logic [31:0] s_axi_eth_wdata;
logic [3:0] s_axi_eth_wstrb;
logic s_axi_eth_wlast;
logic s_axi_eth_wvalid;
logic s_axi_eth_wready;
logic [1:0] s_axi_eth_bresp;
logic s_axi_eth_bvalid;
logic s_axi_eth_bready;
logic [31:0] s_axi_eth_araddr;
logic [7:0] s_axi_eth_arlen;
logic [2:0] s_axi_eth_arsize;
logic [1:0] s_axi_eth_arburst;
logic [3:0] s_axi_eth_arcache;
logic s_axi_eth_arvalid;
logic s_axi_eth_arready;
logic [31:0] s_axi_eth_rdata;
logic [1:0] s_axi_eth_rresp;
logic s_axi_eth_rlast;
logic s_axi_eth_rvalid;
// system-bus is 64-bit, convert down to 32 bit
xlnx_axi_dwidth_converter i_xlnx_axi_dwidth_converter_ethernet (
.s_axi_aclk ( clk_i ),
.s_axi_aresetn ( rst_ni ),
.s_axi_awid ( ethernet.aw_id ),
.s_axi_awaddr ( ethernet.aw_addr[31:0] ),
.s_axi_awlen ( ethernet.aw_len ),
.s_axi_awsize ( ethernet.aw_size ),
.s_axi_awburst ( ethernet.aw_burst ),
.s_axi_awlock ( ethernet.aw_lock ),
.s_axi_awcache ( ethernet.aw_cache ),
.s_axi_awprot ( ethernet.aw_prot ),
.s_axi_awregion ( ethernet.aw_region ),
.s_axi_awqos ( ethernet.aw_qos ),
.s_axi_awvalid ( ethernet.aw_valid ),
.s_axi_awready ( ethernet.aw_ready ),
.s_axi_wdata ( ethernet.w_data ),
.s_axi_wstrb ( ethernet.w_strb ),
.s_axi_wlast ( ethernet.w_last ),
.s_axi_wvalid ( ethernet.w_valid ),
.s_axi_wready ( ethernet.w_ready ),
.s_axi_bid ( ethernet.b_id ),
.s_axi_bresp ( ethernet.b_resp ),
.s_axi_bvalid ( ethernet.b_valid ),
.s_axi_bready ( ethernet.b_ready ),
.s_axi_arid ( ethernet.ar_id ),
.s_axi_araddr ( ethernet.ar_addr[31:0] ),
.s_axi_arlen ( ethernet.ar_len ),
.s_axi_arsize ( ethernet.ar_size ),
.s_axi_arburst ( ethernet.ar_burst ),
.s_axi_arlock ( ethernet.ar_lock ),
.s_axi_arcache ( ethernet.ar_cache ),
.s_axi_arprot ( ethernet.ar_prot ),
.s_axi_arregion ( ethernet.ar_region ),
.s_axi_arqos ( ethernet.ar_qos ),
.s_axi_arvalid ( ethernet.ar_valid ),
.s_axi_arready ( ethernet.ar_ready ),
.s_axi_rid ( ethernet.r_id ),
.s_axi_rdata ( ethernet.r_data ),
.s_axi_rresp ( ethernet.r_resp ),
.s_axi_rlast ( ethernet.r_last ),
.s_axi_rvalid ( ethernet.r_valid ),
.s_axi_rready ( ethernet.r_ready ),
.m_axi_awaddr ( s_axi_eth_awaddr ),
.m_axi_awlen ( s_axi_eth_awlen ),
.m_axi_awsize ( s_axi_eth_awsize ),
.m_axi_awburst ( s_axi_eth_awburst ),
.m_axi_awlock ( ),
.m_axi_awcache ( s_axi_eth_awcache ),
.m_axi_awprot ( ),
.m_axi_awregion ( ),
.m_axi_awqos ( ),
.m_axi_awvalid ( s_axi_eth_awvalid ),
.m_axi_awready ( s_axi_eth_awready ),
.m_axi_wdata ( s_axi_eth_wdata ),
.m_axi_wstrb ( s_axi_eth_wstrb ),
.m_axi_wlast ( s_axi_eth_wlast ),
.m_axi_wvalid ( s_axi_eth_wvalid ),
.m_axi_wready ( s_axi_eth_wready ),
.m_axi_bresp ( s_axi_eth_bresp ),
.m_axi_bvalid ( s_axi_eth_bvalid ),
.m_axi_bready ( s_axi_eth_bready ),
.m_axi_araddr ( s_axi_eth_araddr ),
.m_axi_arlen ( s_axi_eth_arlen ),
.m_axi_arsize ( s_axi_eth_arsize ),
.m_axi_arburst ( s_axi_eth_arburst ),
.m_axi_arlock ( ),
.m_axi_arcache ( s_axi_eth_arcache ),
.m_axi_arprot ( ),
.m_axi_arregion ( ),
.m_axi_arqos ( ),
.m_axi_arvalid ( s_axi_eth_arvalid ),
.m_axi_arready ( s_axi_eth_arready ),
.m_axi_rdata ( s_axi_eth_rdata ),
.m_axi_rresp ( s_axi_eth_rresp ),
.m_axi_rlast ( s_axi_eth_rlast ),
.m_axi_rvalid ( s_axi_eth_rvalid ),
.m_axi_rready ( s_axi_eth_rready )
);
xlnx_axi_ethernetlite i_xlnx_axi_ethernetlite (
.s_axi_aclk ( clk_i ),
.s_axi_aresetn ( rst_ni ),
.ip2intc_irpt ( irq_sources[2] ),
.s_axi_awaddr ( s_axi_eth_awaddr[12:0] ),
.s_axi_awlen ( s_axi_eth_awlen ),
.s_axi_awsize ( s_axi_eth_awsize ),
.s_axi_awburst ( s_axi_eth_awburst ),
.s_axi_awcache ( s_axi_eth_awcache ),
.s_axi_awvalid ( s_axi_eth_awvalid ),
.s_axi_awready ( s_axi_eth_awready ),
.s_axi_wdata ( s_axi_eth_wdata ),
.s_axi_wstrb ( s_axi_eth_wstrb ),
.s_axi_wlast ( s_axi_eth_wlast ),
.s_axi_wvalid ( s_axi_eth_wvalid ),
.s_axi_wready ( s_axi_eth_wready ),
.s_axi_bresp ( s_axi_eth_bresp ),
.s_axi_bvalid ( s_axi_eth_bvalid ),
.s_axi_bready ( s_axi_eth_bready ),
.s_axi_araddr ( s_axi_eth_araddr[12:0] ),
.s_axi_arlen ( s_axi_eth_arlen ),
.s_axi_arsize ( s_axi_eth_arsize ),
.s_axi_arburst ( s_axi_eth_arburst ),
.s_axi_arcache ( s_axi_eth_arcache ),
.s_axi_arvalid ( s_axi_eth_arvalid ),
.s_axi_arready ( s_axi_eth_arready ),
.s_axi_rdata ( s_axi_eth_rdata ),
.s_axi_rresp ( s_axi_eth_rresp ),
.s_axi_rlast ( s_axi_eth_rlast ),
.s_axi_rvalid ( s_axi_eth_rvalid ),
.s_axi_rready ( s_axi_eth_rready ),
.phy_tx_clk ( eth_txck ),
.phy_rx_clk ( eth_rxck ),
.phy_crs ( 1'b0 ),
.phy_dv ( eth_rxctl ),
.phy_rx_data ( eth_rxd ),
.phy_col ( 1'b0 ),
.phy_rx_er ( 1'b0 ),
.phy_rst_n ( eth_rst_n ),
.phy_tx_en ( eth_tx_en ),
.phy_tx_data ( eth_txd ),
.phy_mdio_i ( mdio_i ),
.phy_mdio_o ( mdio_o ),
.phy_mdio_t ( mdio_t ),
.phy_mdc ( eth_mdc )
);
IOBUF mdio_io_iobuf (.I (mdio_o), .IO(eth_mdio), .O (mdio_i), .T (mdio_t));
end else begin
assign irq_sources [2] = 1'b0;
assign ethernet.aw_ready = 1'b1;
assign ethernet.ar_ready = 1'b1;
assign ethernet.w_ready = 1'b1;
assign ethernet.b_valid = ethernet.aw_valid;
assign ethernet.b_id = ethernet.aw_id;
assign ethernet.b_resp = axi_pkg::RESP_SLVERR;
assign ethernet.b_user = '0;
assign ethernet.r_valid = ethernet.ar_valid;
assign ethernet.r_resp = axi_pkg::RESP_SLVERR;
assign ethernet.r_data = 'hdeadbeef;
assign ethernet.r_last = 1'b1;
end
endmodule

1118
fpga/src/ariane_xilinx.sv Normal file

File diff suppressed because it is too large Load diff

1
fpga/src/axi2apb Submodule

@ -0,0 +1 @@
Subproject commit 53e7b9f1b16e3f4d4aadc8fbf880d05879f54fe8

1
fpga/src/axi_slice Submodule

@ -0,0 +1 @@
Subproject commit aae8ca49dcfbfa8e44e1938a2e4a768db83006cb

1
fpga/src/bootrom/.gitignore vendored Symbolic link
View file

@ -0,0 +1 @@
../../bootrom/.gitignore

26
fpga/src/bootrom/Makefile Normal file
View file

@ -0,0 +1,26 @@
bootrom_img = bootrom.img bootrom.sv
GCC=riscv64-unknown-elf-gcc
OBJCOPY=riscv64-unknown-elf-objcopy
DTB=ariane.dtb
PYTHON=python
all: $(bootrom_img)
%.img: %.bin
dd if=$< of=$@ bs=128
%.bin: %.elf
$(OBJCOPY) -O binary $< $@
%.elf: %.S linker.ld bootrom.S $(DTB)
$(GCC) -Tlinker.ld $< -nostdlib -static -Wl,--no-gc-sections -o $@
%.dtb: %.dts
dtc -I dts $< -O dtb -o $@
%.sv: %.img
$(PYTHON) ./gen_rom.py $<
clean:
rm $(bootrom_img) $(DTB)

117
fpga/src/bootrom/ariane.dts Normal file
View file

@ -0,0 +1,117 @@
/dts-v1/;
/ {
#address-cells = <2>;
#size-cells = <2>;
compatible = "eth,ariane-bare-dev";
model = "eth,ariane-bare";
chosen {
stdout-path = "/soc/uart@10000000:115200";
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
timebase-frequency = <25000000>; // 25 MHz
CPU0: cpu@0 {
clock-frequency = <50000000>; // 50 MHz
device_type = "cpu";
reg = <0>;
status = "okay";
compatible = "eth, ariane", "riscv";
riscv,isa = "rv64imacsu";
mmu-type = "riscv,sv39";
tlb-split;
// HLIC - hart local interrupt controller
CPU0_intc: interrupt-controller {
#interrupt-cells = <1>;
interrupt-controller;
compatible = "riscv,cpu-intc";
};
};
};
memory@80000000 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x8000000>;
};
L26: soc {
#address-cells = <2>;
#size-cells = <2>;
compatible = "eth,ariane-bare-soc", "simple-bus";
ranges;
clint@2000000 {
compatible = "riscv,clint0";
interrupts-extended = <&CPU0_intc 3 &CPU0_intc 7>;
reg = <0x0 0x2000000 0x0 0xc0000>;
reg-names = "control";
};
PLIC0: interrupt-controller@c000000 {
#address-cells = <0>;
#interrupt-cells = <1>;
compatible = "riscv,plic0";
interrupt-controller;
interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>;
reg = <0x0 0xc000000 0x0 0x4000000>;
riscv,max-priority = <7>;
riscv,ndev = <2>;
};
debug-controller@0 {
compatible = "riscv,debug-013";
interrupts-extended = <&CPU0_intc 65535>;
reg = <0x0 0x0 0x0 0x1000>;
reg-names = "control";
};
uart@10000000 {
compatible = "ns16750";
reg = <0x0 0x10000000 0x0 0x1000>;
clock-frequency = <50000000>;
current-speed = <115200>;
interrupt-parent = <&PLIC0>;
interrupts = <1>;
reg-shift = <2>; // regs are spaced on 32 bit boundary
reg-io-width = <4>; // only 32-bit access are supported
};
xlnx_axi_ethernetlite: ethernet@30000000 {
compatible = "xlnx,axi-ethernetlite-3.0", "xlnx,xps-ethernetlite-1.00.a";
device_type = "network";
interrupt-parent = <&PLIC0>;
interrupts = <2 0>;
local-mac-address = [00 0a 35 00 01 22];
phy-handle = <&phy0>;
reg = <0x0 0x30000000 0x0 0x10000>;
xlnx,duplex = <0x1>;
xlnx,include-global-buffers = <0x1>;
xlnx,include-internal-loopback = <0x0>;
xlnx,include-mdio = <0x1>;
xlnx,instance = "i_xlnx_axi_ethernetlite";
xlnx,rx-ping-pong = <0x1>;
xlnx,s-axi-id-width = <0x4>;
xlnx,tx-ping-pong = <0x1>;
xlnx,use-internal = <0x0>;
xlnx,has-mdio = <0x1>;
// rgmii-id: combines rgmii-rxid and rgmii-txid and thus configures the
// PHY to enable the RX and TX delays. The MAC should neither add the RX
// nor TX delay in this case.
phy-mode = "rgmii-id";
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy0: ethernet-phy@0 {
compatible = "ethernet-phy-id001c.c915";
device_type = "ethernet-phy";
reg = <0x1>;
};
};
};
// axi_spi@11000000 {
// compatible = "xlnx.xps-spic-2.00.b";
// clock-names = "axi_clk", "axi4_clk", "spi_clk";
// clocks = <&clkc 71>, <&clkc 72>, <&clkc 73>;
// interrupt-parent = <&intc>;
// interrupts = <0 31 1>;
// reg = <0x41e00000 0x10000>;
// num-cs = <0x1>;
// fifo-size = <256>;
// bits-per-word = <8>;
// }
};
};

View file

@ -0,0 +1,24 @@
#define DRAM_BASE 0x80000000
.section .text.start, "ax", @progbits
.globl _start
_start:
li s0, DRAM_BASE
csrr a0, mhartid
la a1, _dtb
jr s0
.section .text.hang, "ax", @progbits
.globl _hang
_hang:
csrr a0, mhartid
la a1, _dtb
1:
wfi
j 1b
.section .rodata.dtb, "a", @progbits
.globl _dtb
.align 5, 0
_dtb:
.incbin "ariane.dtb"

BIN
fpga/src/bootrom/bootrom.elf Executable file

Binary file not shown.

680
fpga/src/bootrom/bootrom.h Normal file
View file

@ -0,0 +1,680 @@
// Auto-generated code
const int reset_vec_size = 674;
uint32_t reset_vec[reset_vec_size] = {
0x0010041b,
0x01f41413,
0xf1402573,
0x00000597,
0x07458593,
0x00008402,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0xf1402573,
0x00000597,
0x03c58593,
0x10500073,
0x0000bff5,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0xedfe0dd0,
0x040a0000,
0x38000000,
0xd8070000,
0x28000000,
0x11000000,
0x10000000,
0x00000000,
0x2c020000,
0xa0070000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x01000000,
0x00000000,
0x03000000,
0x04000000,
0x00000000,
0x02000000,
0x03000000,
0x04000000,
0x0f000000,
0x02000000,
0x03000000,
0x14000000,
0x1b000000,
0x2c687465,
0x61697261,
0x622d656e,
0x2d657261,
0x00766564,
0x03000000,
0x10000000,
0x26000000,
0x2c687465,
0x61697261,
0x622d656e,
0x00657261,
0x01000000,
0x736f6863,
0x00006e65,
0x03000000,
0x1a000000,
0x2c000000,
0x636f732f,
0x7261752f,
0x30314074,
0x30303030,
0x313a3030,
0x30323531,
0x00000030,
0x02000000,
0x01000000,
0x73757063,
0x00000000,
0x03000000,
0x04000000,
0x00000000,
0x01000000,
0x03000000,
0x04000000,
0x0f000000,
0x00000000,
0x03000000,
0x04000000,
0x38000000,
0x40787d01,
0x01000000,
0x40757063,
0x00000030,
0x03000000,
0x04000000,
0x4b000000,
0x80f0fa02,
0x03000000,
0x04000000,
0x5b000000,
0x00757063,
0x03000000,
0x04000000,
0x67000000,
0x00000000,
0x03000000,
0x05000000,
0x6b000000,
0x79616b6f,
0x00000000,
0x03000000,
0x12000000,
0x1b000000,
0x2c687465,
0x69726120,
0x00656e61,
0x63736972,
0x00000076,
0x03000000,
0x0b000000,
0x72000000,
0x34367672,
0x63616d69,
0x00007573,
0x03000000,
0x0b000000,
0x7c000000,
0x63736972,
0x76732c76,
0x00003933,
0x03000000,
0x00000000,
0x85000000,
0x01000000,
0x65746e69,
0x70757272,
0x6f632d74,
0x6f72746e,
0x72656c6c,
0x00000000,
0x03000000,
0x04000000,
0x8f000000,
0x01000000,
0x03000000,
0x00000000,
0xa0000000,
0x03000000,
0x0f000000,
0x1b000000,
0x63736972,
0x70632c76,
0x6e692d75,
0x00006374,
0x03000000,
0x04000000,
0xb5000000,
0x01000000,
0x03000000,
0x04000000,
0xbb000000,
0x01000000,
0x02000000,
0x02000000,
0x02000000,
0x01000000,
0x6f6d656d,
0x38407972,
0x30303030,
0x00303030,
0x03000000,
0x07000000,
0x5b000000,
0x6f6d656d,
0x00007972,
0x03000000,
0x10000000,
0x67000000,
0x00000000,
0x00000080,
0x00000000,
0x00000008,
0x02000000,
0x01000000,
0x00636f73,
0x03000000,
0x04000000,
0x00000000,
0x02000000,
0x03000000,
0x04000000,
0x0f000000,
0x02000000,
0x03000000,
0x1f000000,
0x1b000000,
0x2c687465,
0x61697261,
0x622d656e,
0x2d657261,
0x00636f73,
0x706d6973,
0x622d656c,
0x00007375,
0x03000000,
0x00000000,
0xc3000000,
0x01000000,
0x6e696c63,
0x30324074,
0x30303030,
0x00000030,
0x03000000,
0x0d000000,
0x1b000000,
0x63736972,
0x6c632c76,
0x30746e69,
0x00000000,
0x03000000,
0x10000000,
0xca000000,
0x01000000,
0x03000000,
0x01000000,
0x07000000,
0x03000000,
0x10000000,
0x67000000,
0x00000000,
0x00000002,
0x00000000,
0x00000c00,
0x03000000,
0x08000000,
0xde000000,
0x746e6f63,
0x006c6f72,
0x02000000,
0x01000000,
0x65746e69,
0x70757272,
0x6f632d74,
0x6f72746e,
0x72656c6c,
0x30306340,
0x30303030,
0x00000000,
0x03000000,
0x04000000,
0x00000000,
0x00000000,
0x03000000,
0x04000000,
0x8f000000,
0x01000000,
0x03000000,
0x0c000000,
0x1b000000,
0x63736972,
0x6c702c76,
0x00306369,
0x03000000,
0x00000000,
0xa0000000,
0x03000000,
0x10000000,
0xca000000,
0x01000000,
0x0b000000,
0x01000000,
0x09000000,
0x03000000,
0x10000000,
0x67000000,
0x00000000,
0x0000000c,
0x00000000,
0x00000004,
0x03000000,
0x04000000,
0xe8000000,
0x07000000,
0x03000000,
0x04000000,
0xfb000000,
0x02000000,
0x03000000,
0x04000000,
0xb5000000,
0x02000000,
0x03000000,
0x04000000,
0xbb000000,
0x02000000,
0x02000000,
0x01000000,
0x75626564,
0x6f632d67,
0x6f72746e,
0x72656c6c,
0x00003040,
0x03000000,
0x10000000,
0x1b000000,
0x63736972,
0x65642c76,
0x2d677562,
0x00333130,
0x03000000,
0x08000000,
0xca000000,
0x01000000,
0xffff0000,
0x03000000,
0x10000000,
0x67000000,
0x00000000,
0x00000000,
0x00000000,
0x00100000,
0x03000000,
0x08000000,
0xde000000,
0x746e6f63,
0x006c6f72,
0x02000000,
0x01000000,
0x74726175,
0x30303140,
0x30303030,
0x00000030,
0x03000000,
0x08000000,
0x1b000000,
0x3631736e,
0x00303537,
0x03000000,
0x10000000,
0x67000000,
0x00000000,
0x00000010,
0x00000000,
0x00100000,
0x03000000,
0x04000000,
0x4b000000,
0x80f0fa02,
0x03000000,
0x04000000,
0x06010000,
0x00c20100,
0x03000000,
0x04000000,
0x14010000,
0x02000000,
0x03000000,
0x04000000,
0x25010000,
0x01000000,
0x03000000,
0x04000000,
0x30010000,
0x02000000,
0x03000000,
0x04000000,
0x3a010000,
0x04000000,
0x02000000,
0x01000000,
0x65687465,
0x74656e72,
0x30303340,
0x30303030,
0x00000030,
0x03000000,
0x37000000,
0x1b000000,
0x786e6c78,
0x6978612c,
0x6874652d,
0x656e7265,
0x74696c74,
0x2e332d65,
0x6c780030,
0x782c786e,
0x652d7370,
0x72656874,
0x6c74656e,
0x2d657469,
0x30302e31,
0x0000612e,
0x03000000,
0x08000000,
0x5b000000,
0x7774656e,
0x006b726f,
0x03000000,
0x04000000,
0x14010000,
0x02000000,
0x03000000,
0x08000000,
0x25010000,
0x02000000,
0x00000000,
0x03000000,
0x06000000,
0x47010000,
0x00350a00,
0x00002201,
0x03000000,
0x04000000,
0x59010000,
0x03000000,
0x03000000,
0x10000000,
0x67000000,
0x00000000,
0x00000030,
0x00000000,
0x00000100,
0x03000000,
0x04000000,
0x64010000,
0x01000000,
0x03000000,
0x04000000,
0x70010000,
0x01000000,
0x03000000,
0x04000000,
0x8c010000,
0x00000000,
0x03000000,
0x04000000,
0xab010000,
0x01000000,
0x03000000,
0x18000000,
0xbd010000,
0x6c785f69,
0x615f786e,
0x655f6978,
0x72656874,
0x6c74656e,
0x00657469,
0x03000000,
0x04000000,
0xcb010000,
0x01000000,
0x03000000,
0x04000000,
0xdd010000,
0x04000000,
0x03000000,
0x04000000,
0xf1010000,
0x01000000,
0x03000000,
0x04000000,
0x03020000,
0x00000000,
0x03000000,
0x04000000,
0x15020000,
0x01000000,
0x03000000,
0x09000000,
0x23020000,
0x696d6772,
0x64692d69,
0x00000000,
0x01000000,
0x6f69646d,
0x00000000,
0x03000000,
0x04000000,
0x00000000,
0x01000000,
0x03000000,
0x04000000,
0x0f000000,
0x00000000,
0x01000000,
0x65687465,
0x74656e72,
0x7968702d,
0x00003040,
0x03000000,
0x19000000,
0x1b000000,
0x65687465,
0x74656e72,
0x7968702d,
0x3064692d,
0x2e633130,
0x35313963,
0x00000000,
0x03000000,
0x0d000000,
0x5b000000,
0x65687465,
0x74656e72,
0x7968702d,
0x00000000,
0x03000000,
0x04000000,
0x67000000,
0x01000000,
0x03000000,
0x04000000,
0xb5000000,
0x03000000,
0x03000000,
0x04000000,
0xbb000000,
0x03000000,
0x02000000,
0x02000000,
0x02000000,
0x02000000,
0x02000000,
0x09000000,
0x64646123,
0x73736572,
0x6c65632d,
0x2300736c,
0x657a6973,
0x6c65632d,
0x6300736c,
0x61706d6f,
0x6c626974,
0x6f6d0065,
0x006c6564,
0x6f647473,
0x702d7475,
0x00687461,
0x656d6974,
0x65736162,
0x6572662d,
0x6e657571,
0x63007963,
0x6b636f6c,
0x6572662d,
0x6e657571,
0x64007963,
0x63697665,
0x79745f65,
0x72006570,
0x73006765,
0x75746174,
0x69720073,
0x2c766373,
0x00617369,
0x2d756d6d,
0x65707974,
0x626c7400,
0x6c70732d,
0x23007469,
0x65746e69,
0x70757272,
0x65632d74,
0x00736c6c,
0x65746e69,
0x70757272,
0x6f632d74,
0x6f72746e,
0x72656c6c,
0x6e696c00,
0x702c7875,
0x646e6168,
0x7200656c,
0x65676e61,
0x6e690073,
0x72726574,
0x73747075,
0x7478652d,
0x65646e65,
0x65720064,
0x616e2d67,
0x0073656d,
0x63736972,
0x616d2c76,
0x72702d78,
0x69726f69,
0x72007974,
0x76637369,
0x65646e2c,
0x75630076,
0x6e657272,
0x70732d74,
0x00646565,
0x65746e69,
0x70757272,
0x61702d74,
0x746e6572,
0x746e6900,
0x75727265,
0x00737470,
0x2d676572,
0x66696873,
0x65720074,
0x6f692d67,
0x6469772d,
0x6c006874,
0x6c61636f,
0x63616d2d,
0x6464612d,
0x73736572,
0x79687000,
0x6e61682d,
0x00656c64,
0x786e6c78,
0x7075642c,
0x0078656c,
0x786e6c78,
0x636e692c,
0x6564756c,
0x6f6c672d,
0x2d6c6162,
0x66667562,
0x00737265,
0x786e6c78,
0x636e692c,
0x6564756c,
0x746e692d,
0x616e7265,
0x6f6c2d6c,
0x6162706f,
0x78006b63,
0x2c786e6c,
0x6c636e69,
0x2d656475,
0x6f69646d,
0x6e6c7800,
0x6e692c78,
0x6e617473,
0x78006563,
0x2c786e6c,
0x702d7872,
0x2d676e69,
0x676e6f70,
0x6e6c7800,
0x2d732c78,
0x2d697861,
0x772d6469,
0x68746469,
0x6e6c7800,
0x78742c78,
0x6e69702d,
0x6f702d67,
0x7800676e,
0x2c786e6c,
0x2d657375,
0x65746e69,
0x6c616e72,
0x6e6c7800,
0x61682c78,
0x646d2d73,
0x70006f69,
0x6d2d7968,
0x0065646f,
0x00000000
};

Binary file not shown.

376
fpga/src/bootrom/bootrom.sv Normal file
View file

@ -0,0 +1,376 @@
/* Copyright 2018 ETH Zurich and University of Bologna.
* Copyright and related rights are licensed under the Solderpad Hardware
* License, Version 0.51 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
* or agreed to in writing, software, hardware and materials distributed under
* this 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.
*
* File: $filename.v
*
* Description: Auto-generated bootrom
*/
// Auto-generated code
module bootrom (
input logic clk_i,
input logic req_i,
input logic [63:0] addr_i,
output logic [63:0] rdata_o
);
localparam int RomSize = 337;
const logic [RomSize-1:0][63:0] mem = {
64'h00000000_0065646f,
64'h6d2d7968_70006f69,
64'h646d2d73_61682c78,
64'h6e6c7800_6c616e72,
64'h65746e69_2d657375,
64'h2c786e6c_7800676e,
64'h6f702d67_6e69702d,
64'h78742c78_6e6c7800,
64'h68746469_772d6469,
64'h2d697861_2d732c78,
64'h6e6c7800_676e6f70,
64'h2d676e69_702d7872,
64'h2c786e6c_78006563,
64'h6e617473_6e692c78,
64'h6e6c7800_6f69646d,
64'h2d656475_6c636e69,
64'h2c786e6c_78006b63,
64'h6162706f_6f6c2d6c,
64'h616e7265_746e692d,
64'h6564756c_636e692c,
64'h786e6c78_00737265,
64'h66667562_2d6c6162,
64'h6f6c672d_6564756c,
64'h636e692c_786e6c78,
64'h0078656c_7075642c,
64'h786e6c78_00656c64,
64'h6e61682d_79687000,
64'h73736572_6464612d,
64'h63616d2d_6c61636f,
64'h6c006874_6469772d,
64'h6f692d67_65720074,
64'h66696873_2d676572,
64'h00737470_75727265,
64'h746e6900_746e6572,
64'h61702d74_70757272,
64'h65746e69_00646565,
64'h70732d74_6e657272,
64'h75630076_65646e2c,
64'h76637369_72007974,
64'h69726f69_72702d78,
64'h616d2c76_63736972,
64'h0073656d_616e2d67,
64'h65720064_65646e65,
64'h7478652d_73747075,
64'h72726574_6e690073,
64'h65676e61_7200656c,
64'h646e6168_702c7875,
64'h6e696c00_72656c6c,
64'h6f72746e_6f632d74,
64'h70757272_65746e69,
64'h00736c6c_65632d74,
64'h70757272_65746e69,
64'h23007469_6c70732d,
64'h626c7400_65707974,
64'h2d756d6d_00617369,
64'h2c766373_69720073,
64'h75746174_73006765,
64'h72006570_79745f65,
64'h63697665_64007963,
64'h6e657571_6572662d,
64'h6b636f6c_63007963,
64'h6e657571_6572662d,
64'h65736162_656d6974,
64'h00687461_702d7475,
64'h6f647473_006c6564,
64'h6f6d0065_6c626974,
64'h61706d6f_6300736c,
64'h6c65632d_657a6973,
64'h2300736c_6c65632d,
64'h73736572_64646123,
64'h09000000_02000000,
64'h02000000_02000000,
64'h02000000_02000000,
64'h03000000_bb000000,
64'h04000000_03000000,
64'h03000000_b5000000,
64'h04000000_03000000,
64'h01000000_67000000,
64'h04000000_03000000,
64'h00000000_7968702d,
64'h74656e72_65687465,
64'h5b000000_0d000000,
64'h03000000_00000000,
64'h35313963_2e633130,
64'h3064692d_7968702d,
64'h74656e72_65687465,
64'h1b000000_19000000,
64'h03000000_00003040,
64'h7968702d_74656e72,
64'h65687465_01000000,
64'h00000000_0f000000,
64'h04000000_03000000,
64'h01000000_00000000,
64'h04000000_03000000,
64'h00000000_6f69646d,
64'h01000000_00000000,
64'h64692d69_696d6772,
64'h23020000_09000000,
64'h03000000_01000000,
64'h15020000_04000000,
64'h03000000_00000000,
64'h03020000_04000000,
64'h03000000_01000000,
64'hf1010000_04000000,
64'h03000000_04000000,
64'hdd010000_04000000,
64'h03000000_01000000,
64'hcb010000_04000000,
64'h03000000_00657469,
64'h6c74656e_72656874,
64'h655f6978_615f786e,
64'h6c785f69_bd010000,
64'h18000000_03000000,
64'h01000000_ab010000,
64'h04000000_03000000,
64'h00000000_8c010000,
64'h04000000_03000000,
64'h01000000_70010000,
64'h04000000_03000000,
64'h01000000_64010000,
64'h04000000_03000000,
64'h00000100_00000000,
64'h00000030_00000000,
64'h67000000_10000000,
64'h03000000_03000000,
64'h59010000_04000000,
64'h03000000_00002201,
64'h00350a00_47010000,
64'h06000000_03000000,
64'h00000000_02000000,
64'h25010000_08000000,
64'h03000000_02000000,
64'h14010000_04000000,
64'h03000000_006b726f,
64'h7774656e_5b000000,
64'h08000000_03000000,
64'h0000612e_30302e31,
64'h2d657469_6c74656e,
64'h72656874_652d7370,
64'h782c786e_6c780030,
64'h2e332d65_74696c74,
64'h656e7265_6874652d,
64'h6978612c_786e6c78,
64'h1b000000_37000000,
64'h03000000_00000030,
64'h30303030_30303340,
64'h74656e72_65687465,
64'h01000000_02000000,
64'h04000000_3a010000,
64'h04000000_03000000,
64'h02000000_30010000,
64'h04000000_03000000,
64'h01000000_25010000,
64'h04000000_03000000,
64'h02000000_14010000,
64'h04000000_03000000,
64'h00c20100_06010000,
64'h04000000_03000000,
64'h80f0fa02_4b000000,
64'h04000000_03000000,
64'h00100000_00000000,
64'h00000010_00000000,
64'h67000000_10000000,
64'h03000000_00303537,
64'h3631736e_1b000000,
64'h08000000_03000000,
64'h00000030_30303030,
64'h30303140_74726175,
64'h01000000_02000000,
64'h006c6f72_746e6f63,
64'hde000000_08000000,
64'h03000000_00100000,
64'h00000000_00000000,
64'h00000000_67000000,
64'h10000000_03000000,
64'hffff0000_01000000,
64'hca000000_08000000,
64'h03000000_00333130,
64'h2d677562_65642c76,
64'h63736972_1b000000,
64'h10000000_03000000,
64'h00003040_72656c6c,
64'h6f72746e_6f632d67,
64'h75626564_01000000,
64'h02000000_02000000,
64'hbb000000_04000000,
64'h03000000_02000000,
64'hb5000000_04000000,
64'h03000000_02000000,
64'hfb000000_04000000,
64'h03000000_07000000,
64'he8000000_04000000,
64'h03000000_00000004,
64'h00000000_0000000c,
64'h00000000_67000000,
64'h10000000_03000000,
64'h09000000_01000000,
64'h0b000000_01000000,
64'hca000000_10000000,
64'h03000000_a0000000,
64'h00000000_03000000,
64'h00306369_6c702c76,
64'h63736972_1b000000,
64'h0c000000_03000000,
64'h01000000_8f000000,
64'h04000000_03000000,
64'h00000000_00000000,
64'h04000000_03000000,
64'h00000000_30303030,
64'h30306340_72656c6c,
64'h6f72746e_6f632d74,
64'h70757272_65746e69,
64'h01000000_02000000,
64'h006c6f72_746e6f63,
64'hde000000_08000000,
64'h03000000_00000c00,
64'h00000000_00000002,
64'h00000000_67000000,
64'h10000000_03000000,
64'h07000000_01000000,
64'h03000000_01000000,
64'hca000000_10000000,
64'h03000000_00000000,
64'h30746e69_6c632c76,
64'h63736972_1b000000,
64'h0d000000_03000000,
64'h00000030_30303030,
64'h30324074_6e696c63,
64'h01000000_c3000000,
64'h00000000_03000000,
64'h00007375_622d656c,
64'h706d6973_00636f73,
64'h2d657261_622d656e,
64'h61697261_2c687465,
64'h1b000000_1f000000,
64'h03000000_02000000,
64'h0f000000_04000000,
64'h03000000_02000000,
64'h00000000_04000000,
64'h03000000_00636f73,
64'h01000000_02000000,
64'h00000008_00000000,
64'h00000080_00000000,
64'h67000000_10000000,
64'h03000000_00007972,
64'h6f6d656d_5b000000,
64'h07000000_03000000,
64'h00303030_30303030,
64'h38407972_6f6d656d,
64'h01000000_02000000,
64'h02000000_02000000,
64'h01000000_bb000000,
64'h04000000_03000000,
64'h01000000_b5000000,
64'h04000000_03000000,
64'h00006374_6e692d75,
64'h70632c76_63736972,
64'h1b000000_0f000000,
64'h03000000_a0000000,
64'h00000000_03000000,
64'h01000000_8f000000,
64'h04000000_03000000,
64'h00000000_72656c6c,
64'h6f72746e_6f632d74,
64'h70757272_65746e69,
64'h01000000_85000000,
64'h00000000_03000000,
64'h00003933_76732c76,
64'h63736972_7c000000,
64'h0b000000_03000000,
64'h00007573_63616d69,
64'h34367672_72000000,
64'h0b000000_03000000,
64'h00000076_63736972,
64'h00656e61_69726120,
64'h2c687465_1b000000,
64'h12000000_03000000,
64'h00000000_79616b6f,
64'h6b000000_05000000,
64'h03000000_00000000,
64'h67000000_04000000,
64'h03000000_00757063,
64'h5b000000_04000000,
64'h03000000_80f0fa02,
64'h4b000000_04000000,
64'h03000000_00000030,
64'h40757063_01000000,
64'h40787d01_38000000,
64'h04000000_03000000,
64'h00000000_0f000000,
64'h04000000_03000000,
64'h01000000_00000000,
64'h04000000_03000000,
64'h00000000_73757063,
64'h01000000_02000000,
64'h00000030_30323531,
64'h313a3030_30303030,
64'h30314074_7261752f,
64'h636f732f_2c000000,
64'h1a000000_03000000,
64'h00006e65_736f6863,
64'h01000000_00657261,
64'h622d656e_61697261,
64'h2c687465_26000000,
64'h10000000_03000000,
64'h00766564_2d657261,
64'h622d656e_61697261,
64'h2c687465_1b000000,
64'h14000000_03000000,
64'h02000000_0f000000,
64'h04000000_03000000,
64'h02000000_00000000,
64'h04000000_03000000,
64'h00000000_01000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'ha0070000_2c020000,
64'h00000000_10000000,
64'h11000000_28000000,
64'hd8070000_38000000,
64'h040a0000_edfe0dd0,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_0000bff5,
64'h10500073_03c58593,
64'h00000597_f1402573,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00000000_00000000,
64'h00008402_07458593,
64'h00000597_f1402573,
64'h01f41413_0010041b
};
logic [$clog2(RomSize)-1:0] addr_q;
always_ff @(posedge clk_i) begin
if (req_i) begin
addr_q <= addr_i[$clog2(RomSize)-1+3:3];
end
end
// this prevents spurious Xes from propagating into
// the speculative fetch stage of the core
assign rdata_o = (addr_q < RomSize) ? mem[addr_q] : '0;
endmodule

1
fpga/src/bootrom/gen_rom.py Symbolic link
View file

@ -0,0 +1 @@
../../../bootrom/gen_rom.py

View file

@ -0,0 +1,21 @@
SECTIONS
{
ROM_BASE = 0x10000; /* ... but actually position independent */
. = ROM_BASE;
.text.start : { *(.text.start) }
. = ROM_BASE + 0x40;
.text.hang : { *(.text.hang) }
. = ROM_BASE + 0x80;
.rodata.dtb : { *(.rodata.dtb) }
.bss : ALIGN(0x100) {
_BSS_START_ = .;
*(.bss)
_BSS_END_ = .;
}
PROVIDE(_sp = 0x84000000);
PROVIDE(_heap_end = _sp - 0x800);
}

View file

@ -0,0 +1,2 @@
#define DRAM_BASE 0x80000000
#define DRAM_SIZE 0x4000000

59
fpga/src/fan_ctrl.sv Normal file
View file

@ -0,0 +1,59 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
// Description: PWM Fan Control for Genesys II board
// Author: Florian Zaruba, zarubaf@iis.ee.ethz.ch
module fan_ctrl (
input logic clk_i,
input logic rst_ni,
input logic [3:0] pwm_setting_i,
output logic fan_pwm_o
);
logic [3:0] ms_clock_d, ms_clock_q;
logic [19:0] cycle_counter_d, cycle_counter_q;
// clock divider
always_comb begin
cycle_counter_d = cycle_counter_q;
ms_clock_d = ms_clock_q;
// divide clock by 499999
if (cycle_counter_q == 499_999) begin
cycle_counter_d = 0;
ms_clock_d = ms_clock_q + 1;
end else begin
cycle_counter_d = cycle_counter_q + 1;
end
if (ms_clock_q == 15) begin
ms_clock_d = 0;
end
end
// duty cycle
always_comb begin
if (ms_clock_q < pwm_setting_i) begin
fan_pwm_o = 1'b1;
end else begin
fan_pwm_o = 1'b0;
end
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
ms_clock_q <= '0;
cycle_counter_q <= '0;
end else begin
ms_clock_q <= ms_clock_d;
cycle_counter_q <= cycle_counter_d;
end
end
endmodule

14
fpga/src/genesysii.svh Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
// Description: Set global FPGA degines
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
`define GENESYSII

14
fpga/src/vcu118.svh Normal file
View file

@ -0,0 +1,14 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
// Description: Set global FPGA degines
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
`define VCU118

5
fpga/xilinx/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
xlnx*/*
!xlnx*/tcl
!Makefile
!common.mk
!*.prj

19
fpga/xilinx/common.mk Normal file
View file

@ -0,0 +1,19 @@
all:
vivado -mode batch -source tcl/run.tcl
mkdir -p ip
cp -r ${PROJECT}.srcs/sources_1/ip/${PROJECT}/* ip/.
cp ${PROJECT}.runs/${PROJECT}_synth_1/${PROJECT}.dcp ip/.
gui:
vivado -mode gui -source tcl/run.tcl &
clean:
rm -rf ip/*
mkdir -p ip
rm -rf ${PROJECT}.*
rm -rf component.xml
rm -rf vivado*.jou
rm -rf vivado*.log
rm -rf vivado*.str
rm -rf xgui
rm -rf .Xil

View file

@ -0,0 +1,2 @@
PROJECT:=xlnx_axi_clock_converter
include ../common.mk

View file

@ -0,0 +1,17 @@
set partNumber $::env(XILINX_PART)
set boardName $::env(XILINX_BOARD)
set ipName xlnx_axi_clock_converter
create_project $ipName . -part $partNumber
set_property board_part $boardName [current_project]
create_ip -name axi_clock_converter -vendor xilinx.com -library ip -module_name $ipName
set_property -dict [list CONFIG.ADDR_WIDTH {64} CONFIG.DATA_WIDTH {64} CONFIG.ID_WIDTH {5}] [get_ips $ipName]
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
launch_run -jobs 8 ${ipName}_synth_1
wait_on_run ${ipName}_synth_1

View file

@ -0,0 +1,2 @@
PROJECT:=xlnx_axi_dwidth_converter
include ../common.mk

View file

@ -0,0 +1,17 @@
set partNumber $::env(XILINX_PART)
set boardName $::env(XILINX_BOARD)
set ipName xlnx_axi_dwidth_converter
create_project $ipName . -part $partNumber
set_property board_part $boardName [current_project]
create_ip -name axi_dwidth_converter -vendor xilinx.com -library ip -module_name $ipName
set_property -dict [list CONFIG.SI_DATA_WIDTH {64} CONFIG.SI_ID_WIDTH {5} CONFIG.MI_DATA_WIDTH {32}] [get_ips $ipName]
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
launch_run -jobs 8 ${ipName}_synth_1
wait_on_run ${ipName}_synth_1

View file

@ -0,0 +1,2 @@
PROJECT:=xlnx_axi_ethernetlite
include ../common.mk

View file

@ -0,0 +1,17 @@
set partNumber $::env(XILINX_PART)
set boardName $::env(XILINX_BOARD)
set ipName xlnx_axi_ethernetlite
create_project $ipName . -part $partNumber
set_property board_part $boardName [current_project]
create_ip -name axi_ethernetlite -vendor xilinx.com -library ip -module_name $ipName
set_property -dict [list CONFIG.C_S_AXI_PROTOCOL {AXI4}] [get_ips $ipName]
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
launch_run -jobs 8 ${ipName}_synth_1
wait_on_run ${ipName}_synth_1

View file

@ -0,0 +1,2 @@
PROJECT:=xlnx_axi_quad_spi
include ../common.mk

View file

@ -0,0 +1,16 @@
set partNumber $::env(XILINX_PART)
set boardName $::env(XILINX_BOARD)
set ipName xlnx_axi_quad_spi
create_project $ipName . -part $partNumber
set_property board_part $boardName [current_project]
create_ip -name axi_quad_spi -vendor xilinx.com -library ip -module_name $ipName
set_property -dict [list CONFIG.C_USE_STARTUP {0} CONFIG.C_USE_STARTUP_INT {0} CONFIG.C_SCK_RATIO {4} CONFIG.C_TYPE_OF_AXI4_INTERFACE {1} CONFIG.C_S_AXI4_ID_WIDTH {0}] [get_ips $ipName]
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
launch_run -jobs 8 ${ipName}_synth_1
wait_on_run ${ipName}_synth_1

View file

@ -0,0 +1,2 @@
PROJECT:=xlnx_clk_gen
include ../common.mk

View file

@ -0,0 +1,17 @@
set partNumber $::env(XILINX_PART)
set boardName $::env(XILINX_BOARD)
set ipName xlnx_clk_gen
create_project $ipName . -part $partNumber
set_property board_part $boardName [current_project]
create_ip -name clk_wiz -vendor xilinx.com -library ip -module_name $ipName
set_property -dict [list CONFIG.PRIM_IN_FREQ {200.000} CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {50} CONFIG.CLKIN1_JITTER_PS {50.0} CONFIG.MMCM_DIVCLK_DIVIDE {1} CONFIG.MMCM_CLKFBOUT_MULT_F {5.000} CONFIG.MMCM_CLKIN1_PERIOD {5.000} CONFIG.MMCM_CLKIN2_PERIOD {10.0} CONFIG.MMCM_CLKOUT0_DIVIDE_F {20.000} CONFIG.CLKOUT1_JITTER {129.198} CONFIG.CLKOUT1_PHASE_ERROR {89.971}] [get_ips $ipName]
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
launch_run -jobs 8 ${ipName}_synth_1
wait_on_run ${ipName}_synth_1

View file

@ -0,0 +1,2 @@
PROJECT:=xlnx_mig_7_ddr3
include ../common.mk

View file

@ -0,0 +1,160 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- IMPORTANT: This is an internal file that has been generated by the MIG software. Any direct editing or changes made to this file may result in unpredictable behavior or data corruption. It is strongly advised that users do not edit the contents of this file. Re-run the MIG GUI with the required settings if any of the options provided below need to be altered. -->
<Project NoOfControllers="1" >
<ModuleName>xlnx_mig_7_ddr3</ModuleName>
<dci_inouts_inputs>1</dci_inouts_inputs>
<dci_inputs>1</dci_inputs>
<Debug_En>OFF</Debug_En>
<DataDepth_En>1024</DataDepth_En>
<LowPower_En>ON</LowPower_En>
<XADC_En>Enabled</XADC_En>
<TargetFPGA>xc7k325t-ffg900/-2</TargetFPGA>
<Version>4.1</Version>
<SystemClock>Differential</SystemClock>
<ReferenceClock>Use System Clock</ReferenceClock>
<SysResetPolarity>ACTIVE LOW</SysResetPolarity>
<BankSelectionFlag>FALSE</BankSelectionFlag>
<InternalVref>0</InternalVref>
<dci_hr_inouts_inputs>50 Ohms</dci_hr_inouts_inputs>
<dci_cascade>0</dci_cascade>
<Controller number="0" >
<MemoryDevice>DDR3_SDRAM/Components/MT41J256m16XX-107</MemoryDevice>
<TimePeriod>1250</TimePeriod>
<VccAuxIO>2.0V</VccAuxIO>
<PHYRatio>4:1</PHYRatio>
<InputClkFreq>200</InputClkFreq>
<UIExtraClocks>0</UIExtraClocks>
<MMCM_VCO>800</MMCM_VCO>
<MMCMClkOut0> 1.000</MMCMClkOut0>
<MMCMClkOut1>1</MMCMClkOut1>
<MMCMClkOut2>1</MMCMClkOut2>
<MMCMClkOut3>1</MMCMClkOut3>
<MMCMClkOut4>1</MMCMClkOut4>
<DataWidth>32</DataWidth>
<DeepMemory>1</DeepMemory>
<DataMask>1</DataMask>
<ECC>Disabled</ECC>
<Ordering>Normal</Ordering>
<BankMachineCnt>4</BankMachineCnt>
<CustomPart>FALSE</CustomPart>
<NewPartName></NewPartName>
<RowAddress>15</RowAddress>
<ColAddress>10</ColAddress>
<BankAddress>3</BankAddress>
<MemoryVoltage>1.5V</MemoryVoltage>
<UserMemoryAddressMap>BANK_ROW_COLUMN</UserMemoryAddressMap>
<PinSelection>
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AC12" SLEW="" name="ddr3_addr[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AB8" SLEW="" name="ddr3_addr[10]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AA8" SLEW="" name="ddr3_addr[11]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AB12" SLEW="" name="ddr3_addr[12]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AA12" SLEW="" name="ddr3_addr[13]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AH9" SLEW="" name="ddr3_addr[14]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AE8" SLEW="" name="ddr3_addr[1]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AD8" SLEW="" name="ddr3_addr[2]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AC10" SLEW="" name="ddr3_addr[3]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AD9" SLEW="" name="ddr3_addr[4]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AA13" SLEW="" name="ddr3_addr[5]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AA10" SLEW="" name="ddr3_addr[6]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AA11" SLEW="" name="ddr3_addr[7]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="Y10" SLEW="" name="ddr3_addr[8]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="Y11" SLEW="" name="ddr3_addr[9]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AE9" SLEW="" name="ddr3_ba[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AB10" SLEW="" name="ddr3_ba[1]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AC11" SLEW="" name="ddr3_ba[2]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AF11" SLEW="" name="ddr3_cas_n" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15" PADName="AC9" SLEW="" name="ddr3_ck_n[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15" PADName="AB9" SLEW="" name="ddr3_ck_p[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AJ9" SLEW="" name="ddr3_cke[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AH12" SLEW="" name="ddr3_cs_n[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AD4" SLEW="" name="ddr3_dm[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AF3" SLEW="" name="ddr3_dm[1]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AH4" SLEW="" name="ddr3_dm[2]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AF8" SLEW="" name="ddr3_dm[3]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AD3" SLEW="" name="ddr3_dq[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AF1" SLEW="" name="ddr3_dq[10]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AE4" SLEW="" name="ddr3_dq[11]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AE3" SLEW="" name="ddr3_dq[12]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AE5" SLEW="" name="ddr3_dq[13]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AF5" SLEW="" name="ddr3_dq[14]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AF6" SLEW="" name="ddr3_dq[15]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AJ4" SLEW="" name="ddr3_dq[16]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AH6" SLEW="" name="ddr3_dq[17]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AH5" SLEW="" name="ddr3_dq[18]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AH2" SLEW="" name="ddr3_dq[19]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AC2" SLEW="" name="ddr3_dq[1]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AJ2" SLEW="" name="ddr3_dq[20]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AJ1" SLEW="" name="ddr3_dq[21]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AK1" SLEW="" name="ddr3_dq[22]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AJ3" SLEW="" name="ddr3_dq[23]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AF7" SLEW="" name="ddr3_dq[24]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AG7" SLEW="" name="ddr3_dq[25]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AJ6" SLEW="" name="ddr3_dq[26]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AK6" SLEW="" name="ddr3_dq[27]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AJ8" SLEW="" name="ddr3_dq[28]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AK8" SLEW="" name="ddr3_dq[29]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AC1" SLEW="" name="ddr3_dq[2]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AK5" SLEW="" name="ddr3_dq[30]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AK4" SLEW="" name="ddr3_dq[31]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AC5" SLEW="" name="ddr3_dq[3]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AC4" SLEW="" name="ddr3_dq[4]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AD6" SLEW="" name="ddr3_dq[5]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AE6" SLEW="" name="ddr3_dq[6]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AC7" SLEW="" name="ddr3_dq[7]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AF2" SLEW="" name="ddr3_dq[8]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15_T_DCI" PADName="AE1" SLEW="" name="ddr3_dq[9]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AD1" SLEW="" name="ddr3_dqs_n[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AG3" SLEW="" name="ddr3_dqs_n[1]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AH1" SLEW="" name="ddr3_dqs_n[2]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AJ7" SLEW="" name="ddr3_dqs_n[3]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AD2" SLEW="" name="ddr3_dqs_p[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AG4" SLEW="" name="ddr3_dqs_p[1]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AG2" SLEW="" name="ddr3_dqs_p[2]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="DIFF_SSTL15_T_DCI" PADName="AH7" SLEW="" name="ddr3_dqs_p[3]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AK9" SLEW="" name="ddr3_odt[0]" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AE11" SLEW="" name="ddr3_ras_n" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="LVCMOS15" PADName="AG5" SLEW="" name="ddr3_reset_n" IN_TERM="" />
<Pin VCCAUX_IO="HIGH" IOSTANDARD="SSTL15" PADName="AG13" SLEW="" name="ddr3_we_n" IN_TERM="" />
</PinSelection>
<System_Clock>
<Pin PADName="AD12/AD11(CC_P/N)" Bank="33" name="sys_clk_p/n" />
</System_Clock>
<System_Control>
<Pin PADName="No connect" Bank="Select Bank" name="sys_rst" />
<Pin PADName="No connect" Bank="Select Bank" name="init_calib_complete" />
<Pin PADName="No connect" Bank="Select Bank" name="tg_compare_error" />
</System_Control>
<TimingParameters>
<Parameters twtr="7.5" trrd="6" trefi="7.8" tfaw="35" trtp="7.5" tcke="5" trfc="260" trp="13.91" tras="34" trcd="13.91" />
</TimingParameters>
<mrBurstLength name="Burst Length" >8 - Fixed</mrBurstLength>
<mrBurstType name="Read Burst Type and Length" >Sequential</mrBurstType>
<mrCasLatency name="CAS Latency" >11</mrCasLatency>
<mrMode name="Mode" >Normal</mrMode>
<mrDllReset name="DLL Reset" >No</mrDllReset>
<mrPdMode name="DLL control for precharge PD" >Slow Exit</mrPdMode>
<emrDllEnable name="DLL Enable" >Enable</emrDllEnable>
<emrOutputDriveStrength name="Output Driver Impedance Control" >RZQ/7</emrOutputDriveStrength>
<emrMirrorSelection name="Address Mirroring" >Disable</emrMirrorSelection>
<emrCSSelection name="Controller Chip Select Pin" >Enable</emrCSSelection>
<emrRTT name="RTT (nominal) - On Die Termination (ODT)" >RZQ/6</emrRTT>
<emrPosted name="Additive Latency (AL)" >0</emrPosted>
<emrOCD name="Write Leveling Enable" >Disabled</emrOCD>
<emrDQS name="TDQS enable" >Enabled</emrDQS>
<emrRDQS name="Qoff" >Output Buffer Enabled</emrRDQS>
<mr2PartialArraySelfRefresh name="Partial-Array Self Refresh" >Full Array</mr2PartialArraySelfRefresh>
<mr2CasWriteLatency name="CAS write latency" >8</mr2CasWriteLatency>
<mr2AutoSelfRefresh name="Auto Self Refresh" >Enabled</mr2AutoSelfRefresh>
<mr2SelfRefreshTempRange name="High Temparature Self Refresh Rate" >Normal</mr2SelfRefreshTempRange>
<mr2RTTWR name="RTT_WR - Dynamic On Die Termination (ODT)" >Dynamic ODT off</mr2RTTWR>
<PortInterface>AXI</PortInterface>
<AXIParameters>
<C0_C_RD_WR_ARB_ALGORITHM>RD_PRI_REG</C0_C_RD_WR_ARB_ALGORITHM>
<C0_S_AXI_ADDR_WIDTH>30</C0_S_AXI_ADDR_WIDTH>
<C0_S_AXI_DATA_WIDTH>64</C0_S_AXI_DATA_WIDTH>
<C0_S_AXI_ID_WIDTH>5</C0_S_AXI_ID_WIDTH>
<C0_S_AXI_SUPPORTS_NARROW_BURST>0</C0_S_AXI_SUPPORTS_NARROW_BURST>
</AXIParameters>
</Controller>
</Project>

View file

@ -0,0 +1,19 @@
set partNumber $::env(XILINX_PART)
set boardName $::env(XILINX_BOARD)
set ipName xlnx_mig_7_ddr3
create_project $ipName . -part $partNumber
set_property board_part $boardName [current_project]
create_ip -name mig_7series -vendor xilinx.com -library ip -module_name $ipName
exec cp mig_genesys2.prj ./$ipName.srcs/sources_1/ip/$ipName/mig_a.prj
set_property -dict [list CONFIG.XML_INPUT_FILE {mig_a.prj} CONFIG.RESET_BOARD_INTERFACE {Custom} CONFIG.MIG_DONT_TOUCH_PARAM {Custom} CONFIG.BOARD_MIG_PARAM {Custom}] [get_ips $ipName]
generate_target {instantiation_template} [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
generate_target all [get_files ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
create_ip_run [get_files -of_objects [get_fileset sources_1] ./$ipName.srcs/sources_1/ip/$ipName/$ipName.xci]
launch_run -jobs 8 ${ipName}_synth_1
wait_on_run ${ipName}_synth_1

View file

@ -31,7 +31,7 @@ package ariane_pkg;
localparam BITS_SATURATION_COUNTER = 2;
localparam NR_COMMIT_PORTS = 2;
localparam ENABLE_RENAME = 1'b1;
localparam ENABLE_RENAME = 1'b0;
localparam ISSUE_WIDTH = 1;
// amount of pipeline registers inserted for load/store return path
@ -102,6 +102,7 @@ package ariane_pkg;
// 32 registers + 1 bit for re-naming = 6
localparam REG_ADDR_SIZE = 6;
localparam NR_WB_PORTS = 4;
// static debug hartinfo
localparam dm::hartinfo_t DebugHartInfo = '{
@ -121,27 +122,34 @@ package ariane_pkg;
// where coherence is not necessary this can improve performance. This needs to be switched on
// when more than one core is in a system
localparam logic INVALIDATE_ON_FLUSH = 1'b1;
localparam NR_WB_PORTS = 4;
// enable performance cycle counter, if set to zero mcycle will be incremented
// with instret (non RISC-V conformal)
localparam bit ENABLE_CYCLE_COUNT = 1'b1;
// mark WIF as nop
localparam bit ENABLE_WFI = 1'b1;
// Spike zeros tval on all exception except memory faults
localparam bit ZERO_TVAL = 1'b0;
// read mask for SSTATUS over MMSTATUS
localparam logic [63:0] SMODE_STATUS_MASK = riscv::SSTATUS_UIE
| riscv::SSTATUS_SIE
| riscv::SSTATUS_SPIE
| riscv::SSTATUS_SPP
| riscv::SSTATUS_FS
| riscv::SSTATUS_XS
| riscv::SSTATUS_SUM
| riscv::SSTATUS_MXR
| riscv::SSTATUS_UPIE
| riscv::SSTATUS_SPIE
| riscv::SSTATUS_SPP
| riscv::SSTATUS_FS
| riscv::SSTATUS_XS
| riscv::SSTATUS_SUM
| riscv::SSTATUS_MXR
| riscv::SSTATUS_UXL
| riscv::SSTATUS64_SD;
localparam logic [63:0] SMODE_STATUS_READ_MASK = riscv::SSTATUS_UIE
| riscv::SSTATUS_SIE
| riscv::SSTATUS_SPIE
| riscv::SSTATUS_SPP
| riscv::SSTATUS_FS
| riscv::SSTATUS_XS
| riscv::SSTATUS_SUM
| riscv::SSTATUS_MXR
| riscv::SSTATUS_UPIE
| riscv::SSTATUS_SPIE
| riscv::SSTATUS_UXL
| riscv::SSTATUS64_SD;
localparam logic [63:0] SMODE_STATUS_WRITE_MASK = riscv::SSTATUS_SIE
| riscv::SSTATUS_SPIE
| riscv::SSTATUS_SPP
| riscv::SSTATUS_FS
| riscv::SSTATUS_SUM
| riscv::SSTATUS_MXR;
// ---------------
// Fetch Stage
// ---------------
@ -446,6 +454,7 @@ package ariane_pkg;
} tlb_update_t;
localparam logic [3:0] MODE_SV39 = 4'h8;
localparam logic [3:0] MODE_OFF = 4'h0;
// Bits required for representation of physical address space as 4K pages
// (e.g. 27*4K == 39bit address space).

View file

@ -417,6 +417,30 @@ package riscv;
localparam logic [63:0] SSTATUS64_SD = 64'h8000000000000000;
localparam logic [63:0] SSTATUS32_SD = 64'h80000000;
localparam logic [63:0] MSTATUS_UIE = 64'h00000001;
localparam logic [63:0] MSTATUS_SIE = 64'h00000002;
localparam logic [63:0] MSTATUS_HIE = 64'h00000004;
localparam logic [63:0] MSTATUS_MIE = 64'h00000008;
localparam logic [63:0] MSTATUS_UPIE = 64'h00000010;
localparam logic [63:0] MSTATUS_SPIE = 64'h00000020;
localparam logic [63:0] MSTATUS_HPIE = 64'h00000040;
localparam logic [63:0] MSTATUS_MPIE = 64'h00000080;
localparam logic [63:0] MSTATUS_SPP = 64'h00000100;
localparam logic [63:0] MSTATUS_HPP = 64'h00000600;
localparam logic [63:0] MSTATUS_MPP = 64'h00001800;
localparam logic [63:0] MSTATUS_FS = 64'h00006000;
localparam logic [63:0] MSTATUS_XS = 64'h00018000;
localparam logic [63:0] MSTATUS_MPRV = 64'h00020000;
localparam logic [63:0] MSTATUS_SUM = 64'h00040000;
localparam logic [63:0] MSTATUS_MXR = 64'h00080000;
localparam logic [63:0] MSTATUS_TVM = 64'h00100000;
localparam logic [63:0] MSTATUS_TW = 64'h00200000;
localparam logic [63:0] MSTATUS_TSR = 64'h00400000;
localparam logic [63:0] MSTATUS32_SD = 64'h80000000;
localparam logic [63:0] MSTATUS_UXL = 64'h0000000300000000;
localparam logic [63:0] MSTATUS_SXL = 64'h0000000C00000000;
localparam logic [63:0] MSTATUS64_SD = 64'h8000000000000000;
typedef enum logic [2:0] {
CSRRW = 3'h1,
CSRRS = 3'h2,
@ -539,4 +563,15 @@ package riscv;
end
endfunction
// pragma translate_on
typedef struct {
byte priv;
longint unsigned pc;
byte is_fp;
byte rd;
longint unsigned data;
int unsigned instr;
byte was_exception;
} commit_log_t;
endpackage

View file

@ -1,20 +1,18 @@
// Copyright (c) 2018 ETH Zurich, University of Bologna
// All rights reserved.
//
// This code is under development and not yet released to the public.
// Until it is released, the code is under the copyright of ETH Zurich and
// the University of Bologna, and may contain confidential and/or unpublished
// work. Any reuse/redistribution is strictly forbidden without written
// permission from ETH Zurich.
//
// Bug fixes and contributions will eventually be released under the
// SolderPad open hardware license in the context of the PULP platform
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
// University of Bologna.
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>, ETH Zurich
// Michael Schaffner <schaffner@iis.ee.ethz.ch>, ETH Zurich
// Date: 15.08.2018
// ******* WIP *******
// Description: package for the standard Ariane cache subsystem.
package std_cache_pkg;

10
scripts/parse_ila_trace.py Executable file
View file

@ -0,0 +1,10 @@
import csv
with open('iladata.csv', 'r') as csvfile:
csvreader = csv.reader(csvfile, delimiter=',', quotechar='|')
for row in csvreader:
if (row[5] == '1'):
print(row[3])
if (row[6] == '1'):
print(row[4])
# print(', '.join(row[]));

View file

@ -21,7 +21,7 @@ import instruction_tracer_pkg::*;
module ariane #(
parameter logic [63:0] CACHE_START_ADDR = 64'h8000_0000 // address on which to decide whether the request is cache-able or not
)(
) (
input logic clk_i,
input logic rst_ni,
// Core ID, Cluster ID and boot address are considered more or less static

@ -1 +1 @@
Subproject commit 50c23985e4ea063dd4aa919101ce16c4e48624ac
Subproject commit de1af467229315ee6af31fea96664c7aae5638a9

@ -1 +1 @@
Subproject commit 1f77f634b65fdee56dfc928cadadd66e9fafc485
Subproject commit 6338af6ee3065c4de22b555a67f64755745b7129

View file

@ -38,7 +38,6 @@ module branch_unit (
automatic logic [63:0] jump_base;
jump_base = (fu_data_i.operator == JALR) ? fu_data_i.operand_a : pc_i;
target_address = 64'b0;
resolve_branch_o = 1'b0;
resolved_branch_o.target_address = 64'b0;
resolved_branch_o.is_taken = 1'b0;

View file

@ -22,7 +22,7 @@ import std_cache_pkg::*;
module cache_ctrl #(
parameter logic [63:0] CACHE_START_ADDR = 64'h4000_0000
)(
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic flush_i,
@ -142,9 +142,9 @@ module cache_ctrl #(
// Bypass mode, check for uncacheable address here as well
if (bypass_i) begin
state_d = WAIT_TAG_BYPASSED;
// grant this access
req_port_o.data_gnt = 1'b1;
state_d = (req_port_i.data_we) ? WAIT_REFILL_GNT : WAIT_TAG_BYPASSED;
// grant this access only if it was a load
req_port_o.data_gnt = (req_port_i.data_we) ? 1'b0 : 1'b1;
mem_req_d.bypass = 1'b1;
// ------------------
// Cache is enabled
@ -260,7 +260,7 @@ module cache_ctrl #(
mem_req_d.bypass = 1'b1;
state_d = WAIT_REFILL_GNT;
end
end // !kill_req_i
end
end
// ~> we are here as we need a second round of memory access for a store
@ -304,8 +304,7 @@ module cache_ctrl #(
addr_o = mem_req_q.index;
if (gnt_i)
state_d = WAIT_TAG_SAVED;
if (gnt_i) state_d = WAIT_TAG_SAVED;
end
end
@ -428,9 +427,9 @@ module cache_ctrl #(
assert (DCACHE_LINE_WIDTH == 128) else $error ("Cacheline width has to be 128 for the moment. But only small changes required in data select logic");
end
// if the full MSHR address matches so should also match the partial one
partial_full_mshr_match: assert property(@(posedge clk_i) disable iff (rst_ni !== 1'b0) mshr_addr_matches_i -> mshr_index_matches_i) else $fatal ("partial mshr index doesn't match");
// there should never be a valid answer when the MSHR matches
no_valid_on_mshr_match: assert property(@(posedge clk_i) disable iff (rst_ni !== 1'b0) mshr_addr_matches_i -> !req_port_o.data_rvalid) else $fatal ("rvalid_o should not be set on MSHR match");
partial_full_mshr_match: assert property(@(posedge clk_i) disable iff (~rst_ni) mshr_addr_matches_i -> mshr_index_matches_i) else $fatal (1, "partial mshr index doesn't match");
// there should never be a valid answer when the MSHR matches and we are not being served
no_valid_on_mshr_match: assert property(@(posedge clk_i) disable iff (~rst_ni) (mshr_addr_matches_i && !active_serving_i)-> !req_port_o.data_rvalid || req_port_i.kill_req) else $fatal (1, "rvalid_o should not be set on MSHR match");
`endif
//pragma translate_on
endmodule

View file

@ -168,7 +168,6 @@ module miss_handler #(
evict_cl_d = evict_cl_q;
mshr_d = mshr_q;
// communicate to the requester which unit we are currently serving
active_serving_o = '0;
active_serving_o[mshr_q.id] = mshr_q.valid;
// AMOs
amo_resp_o.ack = 1'b0;
@ -414,10 +413,27 @@ module miss_handler #(
amo_operand_b = amo_req_i.operand_b;
end
// we do not need a store request for load reserved
req_fsm_miss_valid = (amo_req_i.amo_op == AMO_LR) ? 1'b0 : 1'b1;
// for a load reserved we do not want to write
req_fsm_miss_we = (amo_req_i.amo_op == AMO_LR) ? 1'b0 : 1'b1;
// we do not need a store request for load reserved or a failing store conditional
// we can bail-out without making any further requests
if (amo_req_i.amo_op == AMO_LR ||
(amo_req_i.amo_op == AMO_SC &&
((reservation_q.valid && reservation_q.address != amo_req_i.operand_a[63:3]) || !reservation_q.valid))) begin
req_fsm_miss_valid = 1'b0;
state_d = IDLE;
amo_resp_o.ack = 1'b1;
// write-back the result
amo_resp_o.result = amo_operand_a;
// we know that the SC failed
if (amo_req_i.amo_op == AMO_SC) begin
amo_resp_o.result = 1'b1;
// also clear the reservation
reservation_d.valid = 1'b0;
end
end else begin
req_fsm_miss_valid = 1'b1;
end
req_fsm_miss_we = 1'b1;
req_fsm_miss_req = SINGLE_REQ;
req_fsm_miss_size = amo_req_i.size;
req_fsm_miss_addr = amo_req_i.operand_a;
@ -432,20 +448,16 @@ module miss_handler #(
end
// the request is valid or we didn't need to go for another store
if (valid_miss_fsm || (amo_req_i.amo_op == AMO_LR)) begin
if (valid_miss_fsm) begin
state_d = IDLE;
amo_resp_o.ack = 1'b1;
// write-back the result
amo_resp_o.result = amo_operand_a;
// in case we have a SC we need to look into the reservation table
if (amo_req_i.amo_op == AMO_SC) begin
if (reservation_q.address == amo_req_i.operand_a[63:3] && reservation_q.valid) begin
amo_resp_o.result = 1'b0;
end else begin
amo_resp_o.result = 1'b1;
end
amo_resp_o.result = 1'b0;
// An SC must fail if there is a nother SC (to any address) between the LR and the SC in program
// order.
// order (even to the same address).
// in any case destory the reservation
reservation_d.valid = 1'b0;
end

View file

@ -19,7 +19,7 @@ import std_cache_pkg::*;
module std_cache_subsystem #(
parameter logic [63:0] CACHE_START_ADDR = 64'h4000_0000
)(
) (
input logic clk_i,
input logic rst_ni,
input riscv::priv_lvl_t priv_lvl_i,

View file

@ -259,98 +259,3 @@ module std_nbdcache #(
end
//pragma translate_on
endmodule
// --------------
// Tag Compare
// --------------
//
// Description: Arbitrates access to cache memories, simplified request grant protocol
// checks for hit or miss on cache
//
module tag_cmp #(
parameter int unsigned NR_PORTS = 3,
parameter int unsigned ADDR_WIDTH = 64,
parameter type data_t = cache_line_t,
parameter type be_t = cl_be_t,
parameter int unsigned DCACHE_SET_ASSOC = 8
)(
input logic clk_i,
input logic rst_ni,
input logic [NR_PORTS-1:0][DCACHE_SET_ASSOC-1:0] req_i,
output logic [NR_PORTS-1:0] gnt_o,
input logic [NR_PORTS-1:0][ADDR_WIDTH-1:0] addr_i,
input data_t [NR_PORTS-1:0] wdata_i,
input logic [NR_PORTS-1:0] we_i,
input be_t [NR_PORTS-1:0] be_i,
output data_t [DCACHE_SET_ASSOC-1:0] rdata_o,
input logic [NR_PORTS-1:0][DCACHE_TAG_WIDTH-1:0] tag_i, // tag in - comes one cycle later
output logic [DCACHE_SET_ASSOC-1:0] hit_way_o, // we've got a hit on the corresponding way
output logic [DCACHE_SET_ASSOC-1:0] req_o,
output logic [ADDR_WIDTH-1:0] addr_o,
output data_t wdata_o,
output logic we_o,
output be_t be_o,
input data_t [DCACHE_SET_ASSOC-1:0] rdata_i
);
assign rdata_o = rdata_i;
// one hot encoded
logic [NR_PORTS-1:0] id_d, id_q;
logic [DCACHE_TAG_WIDTH-1:0] sel_tag;
always_comb begin : tag_sel
sel_tag = '0;
for (int unsigned i = 0; i < NR_PORTS; i++)
if (id_q[i])
sel_tag = tag_i[i];
end
for (genvar j = 0; j < DCACHE_SET_ASSOC; j++) begin : tag_cmp
assign hit_way_o[j] = (sel_tag == rdata_i[j].tag) ? rdata_i[j].valid : 1'b0;
end
always_comb begin
gnt_o = '0;
id_d = '0;
wdata_o = '0;
req_o = '0;
addr_o = '0;
be_o = '0;
we_o = '0;
// Request Side
// priority select
for (int unsigned i = 0; i < NR_PORTS; i++) begin
req_o = req_i[i];
id_d = (1'b1 << i);
gnt_o[i] = 1'b1;
addr_o = addr_i[i];
be_o = be_i[i];
we_o = we_i[i];
wdata_o = wdata_i[i];
if (req_i[i])
break;
end
//pragma translate_off
`ifndef VERILATOR
// assert that cache only hits on one way
assert property (
@(posedge clk_i) $onehot0(hit_way_o)) else begin $error("Hit should be one-hot encoded"); $stop(); end
`endif
//pragma translate_on
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
id_q <= 0;
end else begin
id_q <= id_d;
end
end
endmodule

View file

@ -0,0 +1,328 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
// Author: Florian Zaruba, ETH Zurich
// Description: Bypass version of data cache
module std_nbdcache #(
parameter logic [63:0] CACHE_START_ADDR = 64'h8000_0000
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
// Cache management
input logic enable_i, // from CSR
input logic flush_i, // high until acknowledged
output logic flush_ack_o, // send a single cycle acknowledge signal when the cache is flushed
output logic miss_o, // we missed on a LD/ST
// AMOs
input ariane_pkg::amo_req_t amo_req_i,
output ariane_pkg::amo_resp_t amo_resp_o,
// Request ports
input ariane_pkg::dcache_req_i_t [2:0] req_ports_i, // request ports
output ariane_pkg::dcache_req_o_t [2:0] req_ports_o, // request ports
// Cache AXI refill port
AXI_BUS.Master data_if,
AXI_BUS.Master bypass_if
);
localparam PTW = 0;
localparam LOAD = 1;
localparam STORE = 2;
// Registers
enum logic [3:0] {
Idle,
SampleTagPTW,
SampleTagLoad,
ReadPTW,
ReadLoad,
WaitReadPTW,
WaitReadLoad,
Write,
SendWrite,
WaitB,
AMORead,
WaitAMORead,
AMOSendAW,
AMOSendW,
AMOWaitB
} state_d, state_q;
typedef struct packed {
logic [63:0] addr;
logic [7:0] be;
logic [1:0] size;
} cache_req_t;
cache_req_t req_q, req_d;
logic [63:0] amo_load_d, amo_load_q;
// tie-off bypass bus
assign bypass_if.aw_valid = 1'b0;
assign bypass_if.w_valid = 1'b0;
assign bypass_if.ar_valid = 1'b0;
assign bypass_if.b_ready = 1'b1;
assign bypass_if.r_ready = 1'b1;
// AMOs
ariane_pkg::amo_t amo_op;
logic [63:0] amo_operand_a, amo_operand_b, amo_result_o;
logic [63:0] load_data;
// re-align load data
assign load_data = data_align(amo_req_i.operand_a[2:0], amo_load_q);
always_comb begin
req_d = req_q;
amo_load_d = amo_load_q;
for (int i = 0; i < 3; i++) begin
req_ports_o[i].data_gnt = 1'b0;
req_ports_o[i].data_rvalid = 1'b0;
req_ports_o[i].data_rdata = '0;
end
data_if.aw_valid = 1'b0;
data_if.aw_id = '0;
data_if.aw_addr = '0;
data_if.aw_size = '0;
data_if.aw_lock = '0;
data_if.aw_cache = '0;
data_if.aw_prot = '0;
data_if.aw_qos = '0;
data_if.aw_region = '0;
data_if.aw_user = '0;
data_if.w_valid = 1'b0;
data_if.w_data = '0;
data_if.w_strb = '0;
data_if.w_user = '0;
data_if.w_last = 1'b1;
data_if.ar_id = '0;
data_if.ar_addr = req_q.addr;
data_if.ar_size = req_q.size;
data_if.ar_lock = '0;
data_if.ar_cache = '0;
data_if.ar_prot = '0;
data_if.ar_qos = '0;
data_if.ar_region = '0;
data_if.ar_user = '0;
// AMOs
amo_resp_o.ack = 1'b0;
amo_resp_o.result = '0;
// silence the unit when not used
amo_op = amo_req_i.amo_op;
amo_operand_a = '0;
amo_operand_b = '0;
case (state_q)
Idle: begin
// PTW
if (req_ports_i[PTW].data_req) begin
state_d = SampleTagPTW;
req_d.addr[ariane_pkg::DCACHE_INDEX_WIDTH-1:0] = req_ports_i[PTW].address_index;
req_d.size = req_ports_i[PTW].data_size;
req_ports_o[PTW].data_gnt = 1'b1;
// Load
end else if (req_ports_i[LOAD].data_req) begin
state_d = SampleTagLoad;
req_d.addr[ariane_pkg::DCACHE_INDEX_WIDTH-1:0] = req_ports_i[LOAD].address_index;
req_d.size = req_ports_i[LOAD].data_size;
req_ports_o[LOAD].data_gnt = 1'b1;
// Store
end else if (req_ports_i[STORE].data_req) begin
state_d = Write;
// AMO
end else if (amo_req_i.req) begin
state_d = AMORead;
end
end
SampleTagPTW: begin
req_d.addr[ariane_pkg::DCACHE_TAG_WIDTH+ariane_pkg::DCACHE_INDEX_WIDTH-1:ariane_pkg::DCACHE_INDEX_WIDTH] = req_ports_i[PTW].address_tag;
if (req_ports_i[PTW].kill_req) begin
state_d = Idle;
req_ports_o[PTW].data_rvalid = 1'b1;
end else begin
state_d = ReadPTW;
end
end
SampleTagLoad: begin
req_d.addr[ariane_pkg::DCACHE_TAG_WIDTH+ariane_pkg::DCACHE_INDEX_WIDTH-1:ariane_pkg::DCACHE_INDEX_WIDTH] = req_ports_i[LOAD].address_tag;
if (req_ports_i[LOAD].kill_req) begin
state_d = Idle;
req_ports_o[LOAD].data_rvalid = 1'b1;
end else begin
state_d = ReadLoad;
end
end
ReadPTW: begin
data_if.aw_valid = 1'b1;
if (data_if.aw_ready) begin
state_d = WaitReadPTW;
end
end
ReadLoad: begin
data_if.aw_valid = 1'b1;
if (data_if.aw_ready) begin
state_d = WaitReadLoad;
end
end
WaitReadPTW: begin
data_if.r_ready = 1'b1;
if (data_if.r_valid) begin
req_ports_o[PTW].data_rvalid = 1'b1;
req_ports_o[PTW].data_rdata = data_if.r_data;
state_d = Idle;
end
end
WaitReadLoad: begin
data_if.r_ready = 1'b1;
if (data_if.r_valid) begin
req_ports_o[LOAD].data_rvalid = 1'b1;
req_ports_o[LOAD].data_rdata = data_if.r_data;
state_d = Idle;
end
end
Write: begin
data_if.aw_valid = 1'b1;
data_if.aw_addr = {req_ports_i[STORE].address_tag, req_ports_i[STORE].address_index};
data_if.aw_size = {1'b0, req_ports_i[STORE].data_size};
if (data_if.w_ready) state_d = SendWrite;
end
SendWrite: begin
data_if.w_valid = 1'b1;
data_if.w_data = req_ports_i[STORE].data_wdata;
data_if.w_strb = req_ports_i[STORE].data_be;
if (data_if.w_ready) begin
state_d = WaitB;
req_ports_o[STORE].data_gnt = 1'b1;
end
end
WaitB: begin
data_if.b_ready = 1'b1;
if (data_if.b_valid) begin
state_d = Idle;
req_ports_o[STORE].data_rvalid = 1'b1;
end
end
AMORead: begin
data_if.ar_addr = amo_req_i.operand_a;
data_if.ar_size = amo_req_i.size;
data_if.ar_valid = 1'b1;
if (data_if.ar_ready) state_d = WaitAMORead;
end
WaitAMORead: begin
data_if.r_ready = 1'b1;
if (data_if.r_valid) begin
amo_load_d = data_if.r_data;
state_d = AMOSendAW;
end
// place a reservation on the memory and bail out
if (amo_req_i.amo_op == ariane_pkg::AMO_LR) begin
state_d = Idle;
reservation_d.address = amo_req_i.operand_a[63:3];
reservation_d.valid = 1'b1;
amo_resp_o.ack = 1'b1;
// Sign-extend for word operation
if (amo_req_i.size == 2'b10) begin
amo_resp_o.result = sext32(load_data[31:0]);
end else begin
amo_resp_o.result = load_data;
end
end
end
AMOSendAW: begin
data_if.aw_valid = 1'b1;
data_if.aw_addr = amo_req_i.operand_a;
data_if.aw_size = {1'b0, amo_req_i.size};
if (data_if.aw_ready) begin
state_d = AMOSendW;
end
end
AMOSendW: begin
// Sign-extend for word operation
if (amo_req_i.size == 2'b10) begin
amo_operand_a = sext32(load_data[31:0]);
amo_operand_b = sext32(amo_req_i.operand_b[31:0]);
end else begin
amo_operand_a = load_data;
amo_operand_b = amo_req_i.operand_b;
end
data_if.w_valid = 1'b1;
data_if.w_data = data_align(amo_req_i.operand_a[2:0], amo_result_o);
data_if.w_strb = be_gen(amo_req_i.operand_a[2:0], amo_req_i.size);
if (data_if.w_ready) begin
state_d = AMOWaitB;
end
end
AMOWaitB: begin
data_if.b_ready = 1'b1;
if (data_if.b_valid) begin
state_d = Idle;
end
end
endcase
end
// -----------------
// AMO ALU
// -----------------
amo_alu i_amo_alu (
.amo_op_i ( amo_op ),
.amo_operand_a_i ( amo_operand_a ),
.amo_operand_b_i ( amo_operand_b ),
.amo_result_o ( amo_result_o )
);
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
state_q <= Idle;
req_q <= '0;
amo_load_q <= '0;
end else begin
state_q <= state_d;
req_q <= req_d;
amo_load_q <= amo_load_d;
end
end
endmodule

View file

@ -0,0 +1,104 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
// --------------
// Tag Compare
// --------------
//
// Description: Arbitrates access to cache memories, simplified request grant protocol
// checks for hit or miss on cache
//
module tag_cmp #(
parameter int unsigned NR_PORTS = 3,
parameter int unsigned ADDR_WIDTH = 64,
parameter type l_data_t = std_cache_pkg::cache_line_t,
parameter type l_be_t = std_cache_pkg::cl_be_t,
parameter int unsigned DCACHE_SET_ASSOC = 8
) (
input logic clk_i,
input logic rst_ni,
input logic [NR_PORTS-1:0][DCACHE_SET_ASSOC-1:0] req_i,
output logic [NR_PORTS-1:0] gnt_o,
input logic [NR_PORTS-1:0][ADDR_WIDTH-1:0] addr_i,
input l_data_t [NR_PORTS-1:0] wdata_i,
input logic [NR_PORTS-1:0] we_i,
input l_be_t [NR_PORTS-1:0] be_i,
output l_data_t [DCACHE_SET_ASSOC-1:0] rdata_o,
input logic [NR_PORTS-1:0][ariane_pkg::DCACHE_TAG_WIDTH-1:0] tag_i, // tag in - comes one cycle later
output logic [DCACHE_SET_ASSOC-1:0] hit_way_o, // we've got a hit on the corresponding way
output logic [DCACHE_SET_ASSOC-1:0] req_o,
output logic [ADDR_WIDTH-1:0] addr_o,
output l_data_t wdata_o,
output logic we_o,
output l_be_t be_o,
input l_data_t [DCACHE_SET_ASSOC-1:0] rdata_i
);
assign rdata_o = rdata_i;
// one hot encoded
logic [NR_PORTS-1:0] id_d, id_q;
logic [ariane_pkg::DCACHE_TAG_WIDTH-1:0] sel_tag;
always_comb begin : tag_sel
sel_tag = '0;
for (int unsigned i = 0; i < NR_PORTS; i++)
if (id_q[i])
sel_tag = tag_i[i];
end
for (genvar j = 0; j < DCACHE_SET_ASSOC; j++) begin : tag_cmp
assign hit_way_o[j] = (sel_tag == rdata_i[j].tag) ? rdata_i[j].valid : 1'b0;
end
always_comb begin
gnt_o = '0;
id_d = '0;
wdata_o = '0;
req_o = '0;
addr_o = '0;
be_o = '0;
we_o = '0;
// Request Side
// priority select
for (int unsigned i = 0; i < NR_PORTS; i++) begin
req_o = req_i[i];
id_d = (1'b1 << i);
gnt_o[i] = 1'b1;
addr_o = addr_i[i];
be_o = be_i[i];
we_o = we_i[i];
wdata_o = wdata_i[i];
if (req_i[i])
break;
end
`ifndef SYNTHESIS
`ifndef VERILATOR
// assert that cache only hits on one way
assert property (
@(posedge clk_i) $onehot0(hit_way_o)) else begin $error("Hit should be one-hot encoded"); $stop(); end
`endif
`endif
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
id_q <= 0;
end else begin
id_q <= id_d;
end
end
endmodule

View file

@ -62,9 +62,11 @@ module axi_lite_interface #(
slave.aw_ready = 1'b0;
slave.w_ready = 1'b0;
slave.b_valid = 1'b0;
slave.b_user = 1'b0;
slave.ar_ready = 1'b1;
slave.r_valid = 1'b0;
slave.r_user = 1'b0;
address_o = '0;
we_o = 1'b0;

View file

@ -52,9 +52,6 @@ module clint #(
// increase the timer
logic increase_timer;
// currently not implemented
assign ipi_o = '0;
// -----------------------------
// AXI Interface Logic
// -----------------------------
@ -63,12 +60,14 @@ module clint #(
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ID_WIDTH ( AXI_ID_WIDTH )
) axi_lite_interface_i (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.slave ( slave ),
.address_o ( address ),
.en_o ( en ),
.we_o ( we ),
.data_i ( rdata ),
.data_o ( wdata ),
.*
.data_o ( wdata )
);
// -----------------------------
@ -135,7 +134,7 @@ module clint #(
always_comb begin : irq_gen
// check that the mtime cmp register is set to a meaningful value
for (int unsigned i = 0; i < NR_CORES; i++) begin
if (mtimecmp_q[i] != 0 && mtime_q >= mtimecmp_q[i]) begin
if (mtime_q >= mtimecmp_q[i]) begin
timer_irq_o[i] = 1'b1;
end else begin
timer_irq_o[i] = 1'b0;
@ -149,12 +148,13 @@ module clint #(
// 1. Put the RTC input through a classic two stage edge-triggered synchronizer to filter out any
// metastability effects (or at least make them unlikely :-))
sync_wedge i_sync_edge (
.clk_i,
.rst_ni,
.en_i ( ~testmode_i ),
.serial_i ( rtc_i ),
.r_edge_o ( increase_timer ),
.f_edge_o ( ), // left open
.serial_o ( ),
.*
.serial_o ( ) // left open
);
// Registers
@ -170,6 +170,8 @@ module clint #(
end
end
assign ipi_o = msip_q;
// -------------
// Assertions
// --------------

View file

@ -56,6 +56,20 @@ module commit_stage #(
output logic sfence_vma_o // flush TLBs and pipeline
);
// ila_0 i_ila_commit (
// .clk(clk_i), // input wire clk
// .probe0(commit_instr_i[0].pc), // input wire [63:0] probe0
// .probe1(commit_instr_i[1].pc), // input wire [63:0] probe1
// .probe2(commit_instr_i[0].valid), // input wire [0:0] probe2
// .probe3(commit_instr_i[1].valid), // input wire [0:0] probe3
// .probe4(commit_ack_o[0]), // input wire [0:0] probe4
// .probe5(commit_ack_o[0]), // input wire [0:0] probe5
// .probe6(1'b0), // input wire [0:0] probe6
// .probe7(1'b0), // input wire [0:0] probe7
// .probe8(1'b0), // input wire [0:0] probe8
// .probe9(1'b0) // input wire [0:0] probe9
// );
// TODO make these parametric with NR_COMMIT_PORTS
assign waddr_o[0] = commit_instr_i[0].rd[4:0];
assign waddr_o[1] = commit_instr_i[1].rd[4:0];
@ -139,6 +153,7 @@ module commit_stage #(
// CSR Logic
// ---------
// check whether the instruction we retire was a CSR instruction
// interrupts are never taken on CSR instructions
if (commit_instr_i[0].fu == CSR) begin
// write the CSR file
commit_csr_o = 1'b1;
@ -149,6 +164,8 @@ module commit_stage #(
// ------------------
// SFENCE.VMA Logic
// ------------------
// sfence.vma is idempotent so we can safely re-execute it after returning
// from interrupt service routine
// check if this instruction was a SFENCE_VMA
if (commit_instr_i[0].op == SFENCE_VMA) begin
// no store pending so we can flush the TLBs and pipeline
@ -159,6 +176,8 @@ module commit_stage #(
// ------------------
// FENCE.I Logic
// ------------------
// fence.i is idempotent so we can safely re-execute it after returning
// from interrupt service routine
// Fence synchronizes data and instruction streams. That means that we need to flush the private icache
// and the private dcache. This is the most expensive instruction.
if (commit_instr_i[0].op == FENCE_I || (flush_dcache_i && commit_instr_i[0].fu != STORE)) begin
@ -169,6 +188,8 @@ module commit_stage #(
// ------------------
// FENCE Logic
// ------------------
// fence is idempotent so we can safely re-execute it after returning
// from interrupt service routine
if (commit_instr_i[0].op == FENCE) begin
commit_ack_o[0] = no_st_pending_i;
// tell the controller to flush the D$
@ -228,6 +249,7 @@ module commit_stage #(
// -----------------------------
// Exception & Interrupt Logic
// -----------------------------
// TODO(zarubaf): Move interrupt handling to commit stage.
// here we know for sure that we are taking the exception
always_comb begin : exception_handling
// Multiple simultaneous interrupts and traps at the same privilege level are handled in the following decreasing
@ -263,8 +285,15 @@ module commit_stage #(
// ------------------------
// check for CSR interrupts (e.g.: normal interrupts which get triggered here)
// by putting interrupts here we give them precedence over any other exception
// Don't take the interrupt if we are committing an AMO.
if (csr_exception_i.valid && csr_exception_i.cause[63] && !amo_valid_commit_o) begin
// Don't take the interrupt if we are committing an AMO or a CSR.
// - Atomics because they are atomic in their nature and should not be interrupted
// - CSRs because it makes the implementation easier as CSRs are figured out at the same
// time as interrupts (here in the commit stage). By not allowing them on CSRs we
// reduce the potential critical path length. As all CSRs are single-cycle (plus a
// potential pipeline flush) this only impacts interrupt latency in a couple of cycles.
if (csr_exception_i.valid && csr_exception_i.cause[63]
&& !amo_valid_commit_o
&& commit_instr_i[0].fu != CSR) begin
exception_o = csr_exception_i;
exception_o.tval = commit_instr_i[0].ex.tval;
end
@ -276,4 +305,4 @@ module commit_stage #(
end
end
endmodule
endmodule

@ -1 +1 @@
Subproject commit 1bea86b04d0c341c555e2ff83a8e247c7d1a3260
Subproject commit cb801849915b6bcd7af33f4aa8389c627324a31b

View file

@ -54,9 +54,9 @@ module controller (
flush_unissued_instr_o = 1'b0;
flush_id_o = 1'b0;
flush_ex_o = 1'b0;
flush_tlb_o = 1'b0;
flush_dcache = 1'b0;
flush_icache_o = 1'b0;
flush_tlb_o = 1'b0;
// ------------
// Mis-predict
// ------------

View file

@ -17,7 +17,7 @@ import ariane_pkg::*;
module csr_regfile #(
parameter int ASID_WIDTH = 1,
parameter int unsigned NR_COMMIT_PORTS = 2
)(
) (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic time_irq_i, // Timer threw a interrupt
@ -120,8 +120,6 @@ module csr_regfile #(
logic [63:0] medeleg_q, medeleg_d;
logic [63:0] mideleg_q, mideleg_d;
logic [63:0] mip_q, mip_d;
logic [63:0] pmpcfg0_q, pmpcfg0_d;
logic [63:0] pmpaddr0_q, pmpaddr0_d;
logic [63:0] mie_q, mie_d;
logic [63:0] mscratch_q, mscratch_d;
logic [63:0] mepc_q, mepc_d;
@ -194,7 +192,9 @@ module csr_regfile #(
riscv::CSR_TDATA2:; // not implemented
riscv::CSR_TDATA3:; // not implemented
// supervisor registers
riscv::CSR_SSTATUS: csr_rdata = mstatus_q & ariane_pkg::SMODE_STATUS_MASK;
riscv::CSR_SSTATUS: begin
csr_rdata = mstatus_q & ariane_pkg::SMODE_STATUS_READ_MASK;
end
riscv::CSR_SIE: csr_rdata = mie_q & mideleg_q;
riscv::CSR_SIP: csr_rdata = mip_q & mideleg_q;
riscv::CSR_STVEC: csr_rdata = stvec_q;
@ -205,10 +205,11 @@ module csr_regfile #(
riscv::CSR_STVAL: csr_rdata = stval_q;
riscv::CSR_SATP: begin
// intercept reads to SATP if in S-Mode and TVM is enabled
if (priv_lvl_o == riscv::PRIV_LVL_S && mstatus_q.tvm)
if (priv_lvl_o == riscv::PRIV_LVL_S && mstatus_q.tvm) begin
read_access_exception = 1'b1;
else
end else begin
csr_rdata = satp_q;
end
end
// machine mode registers
riscv::CSR_MSTATUS: csr_rdata = mstatus_q;
@ -223,9 +224,6 @@ module csr_regfile #(
riscv::CSR_MCAUSE: csr_rdata = mcause_q;
riscv::CSR_MTVAL: csr_rdata = mtval_q;
riscv::CSR_MIP: csr_rdata = mip_q;
// Placeholders for M-mode protection
riscv::CSR_PMPCFG0: csr_rdata = pmpcfg0_q;
riscv::CSR_PMPADDR0: csr_rdata = pmpaddr0_q;
riscv::CSR_MVENDORID: csr_rdata = 64'b0; // not implemented
riscv::CSR_MARCHID: csr_rdata = ARIANE_MARCHID;
riscv::CSR_MIMPID: csr_rdata = 64'b0; // not implemented
@ -262,19 +260,24 @@ module csr_regfile #(
automatic riscv::satp_t sapt;
automatic logic [63:0] instret;
sapt = satp_q;
instret = instret_q;
// --------------------
// Counters
// --------------------
cycle_d = cycle_q;
instret_d = instret_q;
if (!debug_mode_q) begin
// just increment the cycle count
cycle_d = cycle_q + 1'b1;
// increase instruction retired counter
for (int i = 0; i < NR_COMMIT_PORTS; i++) if (commit_ack_i[i]) instret++;
for (int i = 0; i < NR_COMMIT_PORTS; i++) begin
if (commit_ack_i[i] && !ex_i.valid) instret++;
end
instret_d = instret;
// increment the cycle count
if (ENABLE_CYCLE_COUNT) cycle_d = cycle_q + 1'b1;
else cycle_d = instret;
end
eret_o = 1'b0;
@ -327,8 +330,6 @@ module csr_regfile #(
en_ld_st_translation_d = en_ld_st_translation_q;
dirty_fp_state_csr = 1'b0;
pmpcfg0_d = pmpcfg0_q;
pmpaddr0_d = pmpaddr0_q;
// check for correct access rights and that we are writing
if (csr_we) begin
@ -379,6 +380,8 @@ module csr_regfile #(
dcsr_d = csr_wdata[31:0];
// debug is implemented
dcsr_d.xdebugver = 4'h4;
// privilege level
dcsr_d.prv = priv_lvl_q;
// currently not supported
dcsr_d.nmip = 1'b0;
dcsr_d.stopcount = 1'b0;
@ -393,27 +396,14 @@ module csr_regfile #(
riscv::CSR_TDATA3:; // not implemented
// sstatus is a subset of mstatus - mask it accordingly
riscv::CSR_SSTATUS: begin
mstatus_d = csr_wdata;
// also hardwire the registers for sstatus
mstatus_d.sxl = riscv::XLEN_64;
mstatus_d.uxl = riscv::XLEN_64;
// hardwired extension registers
mstatus_d.sd = (&mstatus_q.xs) | (&mstatus_q.fs);
mstatus_d.xs = riscv::Off;
mask = ariane_pkg::SMODE_STATUS_WRITE_MASK;
mstatus_d = (mstatus_q & ~mask) | (csr_wdata & mask);
// hardwire to zero if floating point extension is not present
if (!FP_PRESENT) begin
mstatus_d.fs = riscv::Off;
end
mstatus_d.upie = 1'b0;
mstatus_d.uie = 1'b0;
// not all fields of mstatus can be written
mstatus_d.mie = mstatus_q.mie;
mstatus_d.mpie = mstatus_q.mpie;
mstatus_d.mpp = mstatus_q.mpp;
mstatus_d.mprv = mstatus_q.mprv;
mstatus_d.tsr = mstatus_q.tsr;
mstatus_d.tw = mstatus_q.tw;
mstatus_d.tvm = mstatus_q.tvm;
// hardwired extension registers
mstatus_d.sd = (&mstatus_q.xs) | (&mstatus_q.fs);
// this instruction has side-effects
flush_o = 1'b1;
end
@ -445,7 +435,8 @@ module csr_regfile #(
sapt = riscv::satp_t'(csr_wdata);
// only make ASID_LEN - 1 bit stick, that way software can figure out how many ASID bits are supported
sapt.asid = sapt.asid & {{(16-ASID_WIDTH){1'b0}}, {ASID_WIDTH{1'b1}}};
satp_d = sapt;
// only update if we actually support this mode
if (sapt.mode == MODE_OFF || sapt.mode == MODE_SV39) satp_d = sapt;
end
// changing the mode can have side-effects on address translation (e.g.: other instructions), re-fetch
// the next instruction by executing a flush
@ -454,8 +445,6 @@ module csr_regfile #(
riscv::CSR_MSTATUS: begin
mstatus_d = csr_wdata;
mstatus_d.sxl = riscv::XLEN_64;
mstatus_d.uxl = riscv::XLEN_64;
// hardwired zero registers
mstatus_d.sd = (&mstatus_q.xs) | (&mstatus_q.fs);
mstatus_d.xs = riscv::Off;
@ -508,9 +497,6 @@ module csr_regfile #(
mask = riscv::MIP_SSIP | riscv::MIP_STIP | riscv::MIP_SEIP;
mip_d = (mip_q & ~mask) | (csr_wdata & mask);
end
// Placeholders for M-mode protection
riscv::CSR_PMPCFG0: pmpcfg0_d = csr_wdata;
riscv::CSR_PMPADDR0: pmpaddr0_d = csr_wdata;
// performance counters
riscv::CSR_MCYCLE: cycle_d = csr_wdata;
riscv::CSR_MINSTRET: instret = csr_wdata;
@ -535,22 +521,23 @@ module csr_regfile #(
endcase
end
mstatus_d.sxl = riscv::XLEN_64;
mstatus_d.uxl = riscv::XLEN_64;
// mark the floating point extension register as dirty
if (FP_PRESENT && (dirty_fp_state_csr || dirty_fp_state_i)) begin
mstatus_d.fs = riscv::Dirty;
end
// write the floating point status register
if (csr_write_fflags_i)
if (csr_write_fflags_i) begin
fcsr_d.fflags = csr_wdata_i[4:0] | fcsr_q.fflags;
end
// ---------------------
// External Interrupts
// ---------------------
// Machine Mode External Interrupt Pending
mip_d[riscv::IRQ_M_EXT] = irq_i[0];
// Supervisor Mode External Interrupt Pending
mip_d[riscv::IRQ_S_EXT] = mie_q[riscv::IRQ_S_EXT] & irq_i[1];
// Machine software interrupt
mip_d[riscv::IRQ_M_SOFT] = ipi_i;
// Timer interrupt pending, coming from platform timer
@ -584,13 +571,20 @@ module csr_regfile #(
mstatus_d.sie = 1'b0;
mstatus_d.spie = mstatus_q.sie;
// this can either be user or supervisor mode
mstatus_d.spp = logic'(priv_lvl_q);
mstatus_d.spp = priv_lvl_q[0];
// set cause
scause_d = ex_i.cause;
// set epc
sepc_d = pc_i;
// set mtval or stval
stval_d = ex_i.tval;
stval_d = (ariane_pkg::ZERO_TVAL
&& (ex_i.cause inside {
riscv::ILLEGAL_INSTR,
riscv::BREAKPOINT,
riscv::ENV_CALL_UMODE,
riscv::ENV_CALL_SMODE,
riscv::ENV_CALL_MMODE
} || ex_i.cause[63])) ? '0 : ex_i.tval;
// trap to machine mode
end else begin
// update mstatus
@ -602,11 +596,17 @@ module csr_regfile #(
// set epc
mepc_d = pc_i;
// set mtval or stval
mtval_d = ex_i.tval;
mtval_d = (ariane_pkg::ZERO_TVAL
&& (ex_i.cause inside {
riscv::ILLEGAL_INSTR,
riscv::BREAKPOINT,
riscv::ENV_CALL_UMODE,
riscv::ENV_CALL_SMODE,
riscv::ENV_CALL_MMODE
} || ex_i.cause[63])) ? '0 : ex_i.tval;
end
priv_lvl_d = trap_to_priv_lvl;
end
// ------------------------------
@ -720,11 +720,11 @@ module csr_regfile #(
// return from exception, IF doesn't care from where we are returning
eret_o = 1'b1;
// return the previous supervisor interrupt enable flag
mstatus_d.sie = mstatus_d.spie;
mstatus_d.sie = mstatus_q.spie;
// restore the previous privilege level
priv_lvl_d = riscv::priv_lvl_t'({1'b0, mstatus_d.spp});
priv_lvl_d = riscv::priv_lvl_t'({1'b0, mstatus_q.spp});
// set spp to user mode
mstatus_d.spp = logic'(riscv::PRIV_LVL_U);
mstatus_d.spp = 1'b0;
// set spie to 1
mstatus_d.spie = 1'b1;
end
@ -773,7 +773,7 @@ module csr_regfile #(
csr_we = 1'b0;
csr_read = 1'b0;
dret = 1'b1; // signal a return from debug mode
end // DRET:
end
default: begin
csr_we = 1'b0;
csr_read = 1'b0;
@ -803,6 +803,7 @@ module csr_regfile #(
// -----------------
// Interrupt Control
// -----------------
// TODO(zarubaf): Move interrupt handling to commit stage.
// we decode an interrupt the same as an exception, hence it will be taken if the instruction did not
// throw any previous exception.
// we have three interrupt sources: external interrupts, software interrupts, timer interrupts (order of precedence)
@ -855,7 +856,8 @@ module csr_regfile #(
// -----------------
// Privilege Check
// -----------------
// if we are reading or writing, check for the correct privilege level
// if we are reading or writing, check for the correct privilege level this has
// precedence over interrupts
if (csr_we || csr_read) begin
if ((riscv::priv_lvl_t'(priv_lvl_o & csr_addr.csr_decode.priv_lvl) != csr_addr.csr_decode.priv_lvl)) begin
csr_exception_o.cause = riscv::ILLEGAL_INSTR;
@ -880,9 +882,10 @@ module csr_regfile #(
// -------------------
// if there is any interrupt pending un-stall the core
// also un-stall if we want to enter debug mode
if (|mip_q || debug_req_i) begin
if (|mip_q || debug_req_i || irq_i[1]) begin
wfi_d = 1'b0;
// or alternatively if there is no exception pending and we are not in debug mode wait here for the interrupt
// or alternatively if there is no exception pending and we are not in debug mode wait here
// for the interrupt
end else if (!debug_mode_q && csr_op_i == WFI && !ex_i.valid) begin
wfi_d = 1'b1;
end
@ -922,11 +925,23 @@ module csr_regfile #(
// -------------------
// Output Assignments
// -------------------
// When the SEIP bit is read with a CSRRW, CSRRS, or CSRRC instruction, the value
// returned in the rd destination register contains the logical-OR of the software-writable
// bit and the interrupt signal from the interrupt controller.
assign csr_rdata_o = (csr_addr.address == riscv::CSR_MIP) ? (csr_rdata | (irq_i[1] << riscv::IRQ_S_EXT))
: csr_rdata;
always_comb begin
// When the SEIP bit is read with a CSRRW, CSRRS, or CSRRC instruction, the value
// returned in the rd destination register contains the logical-OR of the software-writable
// bit and the interrupt signal from the interrupt controller.
csr_rdata_o = csr_rdata;
unique case (csr_addr.address)
riscv::CSR_MIP: csr_rdata_o = csr_rdata | (irq_i[1] << riscv::IRQ_S_EXT);
// in supervisor mode we also need to check whether we delegated this bit
riscv::CSR_SIP: begin
csr_rdata_o = csr_rdata
| ((irq_i[1] & mideleg_q[riscv::IRQ_S_EXT]) << riscv::IRQ_S_EXT);
end
default:;
endcase
end
// in debug mode we execute with privilege level M
assign priv_lvl_o = (debug_mode_q) ? riscv::PRIV_LVL_M : priv_lvl_q;
// FPU outputs
@ -938,7 +953,9 @@ module csr_regfile #(
assign asid_o = satp_q.asid[ASID_WIDTH-1:0];
assign sum_o = mstatus_q.sum;
// we support bare memory addressing and SV39
assign en_translation_o = (satp_q.mode == 4'h8 && priv_lvl_o != riscv::PRIV_LVL_M) ? 1'b1 : 1'b0;
assign en_translation_o = (satp_q.mode == 4'h8 && priv_lvl_o != riscv::PRIV_LVL_M)
? 1'b1
: 1'b0;
assign mxr_o = mstatus_q.mxr;
assign tvm_o = mstatus_q.tvm;
assign tw_o = mstatus_q.tw;
@ -965,9 +982,6 @@ module csr_regfile #(
dscratch0_q <= 64'b0;
// machine mode registers
mstatus_q <= 64'b0;
// m-mode protection
pmpcfg0_q <= '0;
pmpaddr0_q <= '0;
// set to boot address + direct mode + 4 byte offset which is the initial trap
mtvec_rst_load_q <= 1'b1;
mtvec_q <= '0;
@ -1018,9 +1032,6 @@ module csr_regfile #(
mtval_q <= mtval_d;
dcache_q <= dcache_d;
icache_q <= icache_d;
// m-mode protection
pmpcfg0_q <= pmpcfg0_d;
pmpaddr0_q <= pmpaddr0_d;
// supervisor mode registers
sepc_q <= sepc_d;
scause_q <= scause_d;

View file

@ -15,7 +15,7 @@ riscv set_reset_timeout_sec 120
riscv set_command_timeout_sec 120
# prefer to use sba for system bus access
riscv set_prefer_sba off
riscv set_prefer_sba on
init
halt

View file

@ -23,6 +23,7 @@ import ariane_pkg::*;
module decoder (
input logic [63:0] pc_i, // PC from IF
input logic is_compressed_i, // is a compressed instruction
input logic [15:0] compressed_instr_i, // compressed form of instruction
input logic is_illegal_i, // illegal compressed instruction
input logic [31:0] instruction_i, // instruction from IF
input branchpredict_sbe_t branch_predict_i,
@ -114,7 +115,7 @@ module decoder (
if (priv_lvl_i == riscv::PRIV_LVL_S && tsr_i) begin
illegal_instr = 1'b1;
// do not change privilege level if this is an illegal instruction
instruction_o.op = ADD;
instruction_o.op = ADD;
end
end
// MRET
@ -133,7 +134,7 @@ module decoder (
end
// WFI
12'b1_0000_0101: begin
instruction_o.op = WFI;
if (ENABLE_WFI) instruction_o.op = WFI;
// if timeout wait is set, trap on an illegal instruction in S Mode
// (after 0 cycles timeout)
if (priv_lvl_i == riscv::PRIV_LVL_S && tw_i) begin
@ -1055,7 +1056,7 @@ module decoder (
if (~ex_i.valid) begin
// if we didn't already get an exception save the instruction here as we may need it
// in the commit stage if we got a access exception to one of the CSR registers
instruction_o.ex.tval = {32'b0, instruction_i};
instruction_o.ex.tval = (is_compressed_i) ? {48'b0, compressed_instr_i} : {32'b0, instruction_i};
// instructions which will throw an exception are marked as valid
// e.g.: they can be committed anytime and do not need to wait for any functional unit
// check here if we decoded an invalid instruction or if the compressed decoder already decoded

View file

@ -215,7 +215,7 @@ module ex_stage (
generate
if (FP_PRESENT) begin : fpu_gen
fu_data_t fpu_data;
assign fpu_data.operator = fpu_valid_i ? fu_data_i : '0;
assign fpu_data = fpu_valid_i ? fu_data_i : '0;
fpu_wrap fpu_i (
.clk_i,

View file

@ -112,26 +112,11 @@ module frontend (
instruction_valid = icache_valid_q;
// 32-bit can contain 2 instructions
if (FETCH_WIDTH == 32) begin
instr[0] = icache_data_q;
addr[0] = icache_vaddr_q;
instr[0] = icache_data_q;
addr[0] = icache_vaddr_q;
instr[1] = '0;
addr[1] = {icache_vaddr_q[63:2], 2'b10};
// with 64-bit we can fetch up to 4 instructions/cycle
end else if (FETCH_WIDTH == 64) begin
instr[0] = icache_data_q;
addr[0] = icache_vaddr_q;
instr[1] = '0;
addr[1] = {icache_vaddr_q[63:3], 3'b010};
instr[2] = '0;
addr[2] = {icache_vaddr_q[63:3], 3'b100};
instr[3] = '0;
addr[3] = {icache_vaddr_q[63:3], 3'b110};
end
instr[1] = '0;
addr[1] = {icache_vaddr_q[63:2], 2'b10};
if (icache_valid_q) begin
// last instruction was unaligned
@ -139,117 +124,37 @@ module frontend (
instr[0] = {icache_data_q[15:0], unaligned_instr_q};
addr[0] = unaligned_address_q;
if (FETCH_WIDTH == 32) begin
unaligned_address_d = {icache_vaddr_q[63:2], 2'b10};
unaligned_instr_d = icache_data_q[31:16]; // save the upper bits for next cycle
end else if (FETCH_WIDTH == 64) begin
unaligned_address_d = {icache_vaddr_q[63:3], 3'b110};
unaligned_instr_d = icache_data_q[63:48]; // save the upper bits for next cycle
end
unaligned_address_d = {icache_vaddr_q[63:2], 2'b10};
unaligned_instr_d = icache_data_q[31:16]; // save the upper bits for next cycle
// check if this is instruction is still unaligned e.g.: it is not compressed
// if its compressed re-set unaligned flag
if (FETCH_WIDTH == 32) begin
// for 32 bit we can simply check the next instruction and whether it is compressed or not
// if it is compressed the next fetch will contain an aligned instruction
if (instr_is_compressed[1]) begin
unaligned_d = 1'b0;
instr[1] = {16'b0, icache_data_q[31:16]};
end
end else if (FETCH_WIDTH === 64) begin
// for 64 bit there exist the following options:
// 64 32 0
// | I | I | U | -> again unaligned
// | * | C | I | U | -> aligned
// | * | I | C | U | -> aligned
// | I | C | C | U | -> again unaligned
// | * | C | C | C | U | -> aligned
// Legend: C = compressed, I = 32 bit instruction, U = unaligned upper half
// * = don't care
if (instr_is_compressed[1]) begin
instr[1] = {16'b0, icache_data_q[31:16]};
if (instr_is_compressed[2]) begin
if (instr_is_compressed[3]) begin
unaligned_d = 1'b0;
instr[3] = {16'b0, icache_data_q[63:48]};
end else begin
// continues to be unaligned
end
end else begin
unaligned_d = 1'b0;
instr[2] = icache_data_q[63:32];
end
// instruction 1 is not compressed
end else begin
instr[1] = icache_data_q[47:16];
if (instr_is_compressed[2]) begin
unaligned_d = 1'b0;
instr[2] = icache_data_q[63:48];
end else begin
// continues to be unaligned
end
end
// for 32 bit we can simply check the next instruction and whether it is compressed or not
// if it is compressed the next fetch will contain an aligned instruction
if (instr_is_compressed[1]) begin
unaligned_d = 1'b0;
instr[1] = {16'b0, icache_data_q[31:16]};
end
end else if (instr_is_compressed[0]) begin // instruction zero is RVC
if (FETCH_WIDTH == 32) begin
// is instruction 1 also compressed
// yes? -> no problem, no -> we've got an unaligned instruction
if (instr_is_compressed[1]) begin
instr[1] = {16'b0, icache_data_q[31:16]};
end else begin
unaligned_instr_d = icache_data_q[31:16];
unaligned_address_d = {icache_vaddr_q[63:2], 2'b10};
unaligned_d = 1'b1;
end
end else if (FETCH_WIDTH == 64) begin
// 64 32 0
// | I | I | C | -> again unaligned
// | * | C | I | C | -> aligned
// | * | I | C | C | -> aligned
// | I | C | C | C | -> again unaligned
// | * | C | C | C | C | -> aligned
if (instr_is_compressed[1]) begin
instr[1] = {16'b0, icache_data_q[31:16]};
if (instr_is_compressed[2]) begin
if (instr_is_compressed[3]) begin
unaligned_d = 1'b0;
instr[3] = {16'b0, icache_data_q[63:48]};
end else begin
// continues to be unaligned
end
end else begin
unaligned_d = 1'b0;
instr[2] = icache_data_q[63:32];
end
// instruction 1 is not compressed
end else begin
instr[1] = icache_data_q[47:16];
if (instr_is_compressed[2]) begin
unaligned_d = 1'b0;
instr[2] = icache_data_q[63:48];
end else begin
// continues to be unaligned
end
end
// is instruction 1 also compressed
// yes? -> no problem, no -> we've got an unaligned instruction
if (instr_is_compressed[1]) begin
instr[1] = {16'b0, icache_data_q[31:16]};
end else begin
unaligned_instr_d = icache_data_q[31:16];
unaligned_address_d = {icache_vaddr_q[63:2], 2'b10};
unaligned_d = 1'b1;
end
end // else -> normal fetch
end
// we started to fetch on a unaligned boundary with a whole instruction -> wait until we've
// received the next instruction
if (FETCH_WIDTH == 32) begin
if (icache_valid_q && icache_vaddr_q[1] && !instr_is_compressed[1]) begin
instruction_valid = 1'b0;
unaligned_d = 1'b1;
unaligned_address_d = {icache_vaddr_q[63:2], 2'b10};
unaligned_instr_d = icache_data_q[31:16];
end
end else if (FETCH_WIDTH == 64) begin
if (icache_valid_q && icache_vaddr_q[2] && icache_vaddr_q[1] && !instr_is_compressed[3]) begin
instruction_valid = 1'b0;
unaligned_d = 1'b1;
unaligned_address_d = {icache_vaddr_q[63:2], 2'b10};
unaligned_instr_d = icache_data_q[31:16];
end
if (icache_valid_q && icache_vaddr_q[1] && !instr_is_compressed[1]) begin
instruction_valid = 1'b0;
unaligned_d = 1'b1;
unaligned_address_d = {icache_vaddr_q[63:2], 2'b10};
unaligned_instr_d = icache_data_q[31:16];
end
// if we killed the consecutive fetch we are starting on a clean slate
@ -337,19 +242,8 @@ module frontend (
end
// we are not interested in the lower instruction
if (FETCH_WIDTH == 32) begin
if (icache_vaddr_q[1]) begin
taken[1] = 1'b0;
// TODO(zarubaf): that seems to be overly pessimistic
ras_pop = 1'b0;
ras_push = 1'b0;
end
end else if (FETCH_WIDTH == 64) begin
case (icache_vaddr_q[2:1])
3'b010: taken[1] = 0;
3'b100: taken[2] = 0;
3'b110: taken[3] = 0;
endcase
if (icache_vaddr_q[1]) begin
taken[1] = 1'b0;
// TODO(zarubaf): that seems to be overly pessimistic
ras_pop = 1'b0;
ras_push = 1'b0;
@ -427,7 +321,7 @@ module frontend (
// 0. Default assignment
// -------------------------------
if (if_ready) begin
npc_d = {fetch_address[63:2], 2'b0} + ((FETCH_WIDTH == 64) ? 'h8 : 'h4);
npc_d = {fetch_address[63:2], 2'b0} + 'h4;
end
// -------------------------------
// 2. Control flow change request
@ -499,7 +393,7 @@ module frontend (
else $fatal("[frontend] fetch fifo credits must be <= FETCH_FIFO_DEPTH!");
initial begin
assert (FETCH_FIFO_DEPTH <= 8) else $fatal("[frontend] fetch fifo deeper than 8 not supported");
assert (FETCH_WIDTH == 32 || FETCH_WIDTH == 64) else $fatal("[frontend] fetch width != not supported");
assert (FETCH_WIDTH == 32) else $fatal("[frontend] fetch width != not supported");
end
`endif
//pragma translate_on

View file

@ -84,14 +84,15 @@ module id_stage (
// 3. Decode and emit instruction to issue stage
// ---------------------------------------------------------
decoder decoder_i (
.pc_i ( fetch_entry.address ),
.is_compressed_i ( is_compressed ),
.instruction_i ( instruction ),
.branch_predict_i ( fetch_entry.branch_predict ),
.is_illegal_i ( is_illegal ),
.ex_i ( fetch_entry.ex ),
.instruction_o ( decoded_instruction ),
.is_control_flow_instr_o ( is_control_flow_instr ),
.pc_i ( fetch_entry.address ),
.is_compressed_i ( is_compressed ),
.compressed_instr_i ( fetch_entry.instruction[15:0] ),
.instruction_i ( instruction ),
.branch_predict_i ( fetch_entry.branch_predict ),
.is_illegal_i ( is_illegal ),
.ex_i ( fetch_entry.ex ),
.instruction_o ( decoded_instruction ),
.is_control_flow_instr_o ( is_control_flow_instr ),
.fs_i,
.frm_i,
.*

View file

@ -156,6 +156,25 @@ module mmu #(
.*
);
// ila_1 i_ila_1 (
// .clk(clk_i), // input wire clk
// .probe0({req_port_o.address_tag, req_port_o.address_index}),
// .probe1(req_port_o.data_req), // input wire [63:0] probe1
// .probe2(req_port_i.data_gnt), // input wire [0:0] probe2
// .probe3(req_port_i.data_rdata), // input wire [0:0] probe3
// .probe4(req_port_i.data_rvalid), // input wire [0:0] probe4
// .probe5(ptw_error), // input wire [1:0] probe5
// .probe6(update_vaddr), // input wire [0:0] probe6
// .probe7(update_ptw_itlb.valid), // input wire [0:0] probe7
// .probe8(update_ptw_dtlb.valid), // input wire [0:0] probe8
// .probe9(dtlb_lu_access), // input wire [0:0] probe9
// .probe10(lsu_vaddr_i), // input wire [0:0] probe10
// .probe11(dtlb_lu_hit), // input wire [0:0] probe11
// .probe12(itlb_lu_access), // input wire [0:0] probe12
// .probe13(icache_areq_i.fetch_vaddr), // input wire [0:0] probe13
// .probe14(itlb_lu_hit) // input wire [0:0] probe13
// );
//-----------------------
// Instruction Interface
//-----------------------

155
src/plic/plic.sv Normal file
View file

@ -0,0 +1,155 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
//-------------------------------------------------------------------------------
//-- Title : PLIC Core
//-- File : plic_core.sv
//-- Author : Gian Marti <gimarti.student.ethz.ch>
//-- Author : Thomas Kramer <tkramer.student.ethz.ch>
//-- Author : Thomas E. Benz <tbenz.student.ethz.ch>
//-- Company : Integrated Systems Laboratory, ETH Zurich
//-- Created : 2018-03-31
//-- Last update: 2018-03-31
//-- Platform : ModelSim (simulation), Synopsys (synthesis)
//-- Standard : SystemVerilog IEEE 1800-2012
//-------------------------------------------------------------------------------
//-- Description: PLIC Top-level
//-------------------------------------------------------------------------------
//-- Revisions :
//-- Date Version Author Description
//-- 2018-03-31 2.0 tbenz Created header
//-------------------------------------------------------------------------------
module plic #(
parameter int ID_BITWIDTH = -1, // width of the gateway identifiers
parameter int PARAMETER_BITWIDTH = -1, // width of the internal parameter e.g. priorities
parameter int NUM_TARGETS = -1, // number of target slices
parameter int NUM_SOURCES = -1 // number of sources = number of gateways
) (
input logic clk_i,
input logic rst_ni,
input logic [NUM_SOURCES-1:0] irq_sources_i,
output logic [NUM_TARGETS-1:0] eip_targets_o,
REG_BUS.in external_bus_io
);
localparam int ADDR_WIDTH = 32;
localparam int DATA_WIDTH = 32;
// declare all local variables
// gateway arrays always go from NUM_SOURCES to 1 because gateway ids start at 1
logic gateway_irq_pendings [NUM_SOURCES]; //for pending irqs of the gateways
logic gateway_claimed [NUM_SOURCES]; //if a gateway is claimed, it masks its irq
logic gateway_completed [NUM_SOURCES]; //if a gateway is completed, it is reenabled
logic [ID_BITWIDTH-1:0 ] gateway_ids [NUM_SOURCES]; //ids of gateways
logic [PARAMETER_BITWIDTH-1:0] gateway_priorities [NUM_SOURCES]; //priorities of gateways
logic irq_enableds [NUM_SOURCES][NUM_TARGETS];
logic [PARAMETER_BITWIDTH-1:0] target_thresholds [NUM_TARGETS];
logic [ID_BITWIDTH-1:0 ] identifier_of_largest_priority_per_target [NUM_TARGETS];
logic target_irq_claims [NUM_TARGETS];
logic target_irq_completes [NUM_TARGETS];
logic [ID_BITWIDTH-1:0 ] target_irq_completes_id [NUM_TARGETS];
//instantiate and connect gateways
for (genvar counter = 0; counter < NUM_SOURCES; counter++) begin : gen_plic_gateway
plic_gateway plic_gateway_instance (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.irq_source_i ( irq_sources_i [counter] ),
.claim_i ( gateway_claimed [counter] ),
.completed_i ( gateway_completed [counter] ),
.irq_pending_o ( gateway_irq_pendings[counter] )
);
end
// assign ids to gateways
for (genvar counter = 1; counter <= NUM_SOURCES; counter++) begin
assign gateway_ids[counter-1] = counter;
end
// instantiate and connect target slices
for (genvar counter = 0; counter < NUM_TARGETS; counter++) begin : gen_plic_target_slice
logic irq_enableds_slice[NUM_SOURCES];
for (genvar inner_counter = 0; inner_counter < NUM_SOURCES; inner_counter++) begin
assign irq_enableds_slice[inner_counter] = irq_enableds[inner_counter][counter];
end
plic_target_slice #(
.PRIORITY_BITWIDTH ( PARAMETER_BITWIDTH ),
.ID_BITWIDTH ( ID_BITWIDTH ),
.NUM_GATEWAYS ( NUM_SOURCES )
) plic_target_slice_instance (
.interrupt_pending_i ( gateway_irq_pendings ),
.interrupt_priority_i ( gateway_priorities ),
.interrupt_id_i ( gateway_ids ),
.interrupt_enable_i ( irq_enableds_slice ),
.threshold_i ( target_thresholds[counter] ),
.ext_interrupt_present_o ( eip_targets_o[counter] ),
.identifier_of_largest_o ( identifier_of_largest_priority_per_target[counter] )
);
end
//instantiate and connect plic_interface
plic_interface #(
.ADDR_WIDTH ( ADDR_WIDTH ),
.DATA_WIDTH ( DATA_WIDTH ),
.ID_BITWIDTH ( ID_BITWIDTH ),
.PARAMETER_BITWIDTH ( PARAMETER_BITWIDTH ),
.NUM_TARGETS ( NUM_TARGETS ),
.NUM_GATEWAYS ( NUM_SOURCES )
) plic_interface_instance (
.clk_i,
.rst_ni,
.id_of_largest_priority_i ( identifier_of_largest_priority_per_target ),
.pending_array_i ( gateway_irq_pendings ),
.thresholds_o ( target_thresholds ),
.gateway_priorities_o ( gateway_priorities ),
.irq_enables_o ( irq_enableds ),
.target_irq_claims_o ( target_irq_claims ),
.target_irq_completes_o ( target_irq_completes ),
.target_irq_completes_id_o ( target_irq_completes_id ),
.external_bus_io ( external_bus_io )
);
//instantiate and connect claim_complete_tracker
plic_claim_complete_tracker #(
.NUM_TARGETS ( NUM_TARGETS ),
.NUM_GATEWAYS ( NUM_SOURCES ),
.ID_BITWIDTH ( ID_BITWIDTH )
) plic_claim_complete_tracker_instance (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.identifier_of_largest_priority_per_target ( identifier_of_largest_priority_per_target ),
.target_irq_claims_i ( target_irq_claims ),
.target_irq_completes_i ( target_irq_completes ),
.target_irq_completes_identifier_i ( target_irq_completes_id ),
.gateway_irq_claims_o ( gateway_claimed ),
.gateway_irq_completes_o ( gateway_completed )
);
//pragma translate_off
`ifndef VERILATOR
initial begin
assert((ADDR_WIDTH == 32) | (ADDR_WIDTH == 64)) else $error("Address width has to bei either 32 or 64 bit");
assert((DATA_WIDTH == 32) | (DATA_WIDTH == 64)) else $error("Data width has to bei either 32 or 64 bit");
assert(ID_BITWIDTH > 0 ) else $error("ID_BITWIDTH has to be larger than 1");
assert(ID_BITWIDTH < 10 ) else $error("ID_BITWIDTH has to be smaller than 10");
assert(PARAMETER_BITWIDTH > 0) else $error("PARAMETER_BITWIDTH has to be larger than 1");
assert(PARAMETER_BITWIDTH < 8) else $error("PARAMETER_BITWIDTH has to be smaller than 8");
assert(NUM_SOURCES > 0 ) else $error("Num od Gateways has to be larger than 1");
assert(NUM_SOURCES < 512 ) else $error("Num of Gateways has to be smaller than 512");
assert(NUM_TARGETS > 0 ) else $error("Num Target slices has to be larger than 1");
assert(NUM_TARGETS < 15872 ) else $error("Num target slices has to be smaller than 15872");
end
`endif
//pragma translate_on
endmodule

View file

@ -0,0 +1,134 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
//-------------------------------------------------------------------------------
//-- Title : Claim - Complete - Tracker
//-------------------------------------------------------------------------------
//-- File : plic_claim_complete_tracker.sv
//-- Author : Gian Marti <gimarti.student.ethz.ch>
//-- Author : Thomas Kramer <tkramer.student.ethz.ch>
//-- Author : Thomas E. Benz <tbenz.student.ethz.ch>
//-- Company : Integrated Systems Laboratory, ETH Zurich
//-- Created : 2018-03-31
//-- Last update: 2018-03-31
//-- Platform : ModelSim (simulation), Synopsys (synthesis)
//-- Standard : SystemVerilog IEEE 1800-2012
//-------------------------------------------------------------------------------
//-- Description: Implements the control logic of the plic
//-------------------------------------------------------------------------------
//-- Revisions :
//-- Date Version Author Description
//-- 2018-03-31 2.0 tbenz Created header
//-------------------------------------------------------------------------------
//FSM that receives interrupt claims and interrupt completes from targets
//and generates the fitting inerrupt claims and interrupt completes for sources
module plic_claim_complete_tracker #(
parameter int NUM_TARGETS = 1,
parameter int NUM_GATEWAYS = 1,
parameter int ID_BITWIDTH = 4
)(
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic [ID_BITWIDTH-1:0] identifier_of_largest_priority_per_target[NUM_TARGETS],
input logic target_irq_claims_i [NUM_TARGETS],
input logic target_irq_completes_i[NUM_TARGETS],
input logic [ID_BITWIDTH-1:0] target_irq_completes_identifier_i[NUM_TARGETS],
output logic gateway_irq_claims_o [NUM_GATEWAYS],
output logic gateway_irq_completes_o[NUM_GATEWAYS]
);
// claimed_gateways_q[target] is 0 if the target has not claimed the irq of any gateway
// and the is the identifier of the claimed gateway otherwise
logic [ID_BITWIDTH-1:0] claimed_gateways_q[NUM_TARGETS];
// the +1 is because counting starts from 1 and goes to NUM_GATEWAYS+1
logic claim_array [NUM_GATEWAYS+1][NUM_TARGETS];
logic save_claims_array_q [NUM_GATEWAYS+1][NUM_TARGETS];
logic complete_array [NUM_GATEWAYS+1][NUM_TARGETS];
logic [ID_BITWIDTH-1:0] complete_id;
// for handling claims
for (genvar counter = 0; counter < NUM_TARGETS; counter++) begin
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_target
integer id;
if (~rst_ni) begin
claimed_gateways_q[counter] <= '0;
for (integer i = 0; i <= NUM_GATEWAYS; i++) begin
claim_array[i][counter] <= '0;
save_claims_array_q[i][counter] <= '0;
end
end else begin
// per default, all claims and completes are zero
for (integer i = 0; i <= NUM_GATEWAYS; i++) begin
claim_array[i][counter] <= 0;
complete_array[i][counter] <= 0;
end
// if a claim is issued, forward it to gateway with highest priority for the claiming target
if (target_irq_claims_i[counter]) begin
id = identifier_of_largest_priority_per_target[counter];
claim_array[id][counter] <= 1;
// save claim for later when the complete-notification arrives
save_claims_array_q[id][counter] <= 1;
end else begin
// if a complete is issued, check if that gateway has previously been claimed by
// this target and forward the
// complete message to that gateway. if no claim has previously been issued, the
// complete message is ignored
// integer complete_id = target_irq_completes_identifier_i[counter];
complete_id = target_irq_completes_identifier_i[counter];
if (target_irq_completes_i[counter] && (save_claims_array_q[complete_id][counter] > 0)) begin
complete_array[complete_id][counter] <= 1;
save_claims_array_q[complete_id][counter] <= 0;
end
end
end
end
end
// the outputs for an id are the ORs of all targets for that id
always_comb begin : proc_result_computation
for (integer gateway = 1; gateway <= NUM_GATEWAYS; gateway++) begin
automatic logic is_claimed = '0;
automatic logic is_completed = '0;
for (integer target = 0; target < NUM_TARGETS; target++) begin
is_claimed = is_claimed | claim_array [gateway][target];
is_completed = is_completed | complete_array[gateway][target];
end
if (is_claimed) begin
gateway_irq_claims_o [gateway-1] = 1;
end else begin
gateway_irq_claims_o [gateway-1] = 0;
end
if (is_completed) begin
gateway_irq_completes_o[gateway-1] = 1;
end else begin
gateway_irq_completes_o[gateway-1] = 0;
end
end
end
endmodule //plic_claim_complete_tracker

View file

@ -0,0 +1,63 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
//-------------------------------------------------------------------------------
//-- Title : Comperator
//-- File : plic_comperator.sv
//-- Author : Gian Marti <gimarti.student.ethz.ch>
//-- Author : Thomas Kramer <tkramer.student.ethz.ch>
//-- Author : Thomas E. Benz <tbenz.student.ethz.ch>
//-- Company : Integrated Systems Laboratory, ETH Zurich
//-- Created : 2018-03-31
//-- Last update: 2018-03-31
//-- Platform : ModelSim (simulation), Synopsys (synthesis)
//-- Standard : SystemVerilog IEEE 1800-2012
//-------------------------------------------------------------------------------
//-- Description: Comparator
//-------------------------------------------------------------------------------
//-- Revisions :
//-- Date Version Author Description
//-- 2018-03-31 2.0 tbenz Created header
//-------------------------------------------------------------------------------
// find larger operand (value and identifier)
// chooses the left operand on equality
module plic_comparator #(
parameter int ID_BITWIDTH = -1,
parameter int PRIORITY_BITWIDTH = -1
)(
input logic [PRIORITY_BITWIDTH-1:0] left_priority_i,
input logic [PRIORITY_BITWIDTH-1:0] right_priority_i,
input logic [ID_BITWIDTH-1:0 ] left_identifier_i,
input logic [ID_BITWIDTH-1:0 ] right_identifier_i,
output logic [PRIORITY_BITWIDTH-1:0] larger_priority_o,
output logic[ ID_BITWIDTH-1:0 ] identifier_of_larger_o
);
always_comb begin : proc_compare
if (left_priority_i >= right_priority_i) begin
larger_priority_o = left_priority_i;
identifier_of_larger_o = left_identifier_i;
end else begin
larger_priority_o = right_priority_i;
identifier_of_larger_o = right_identifier_i;
end
end
//pragma translate_off
`ifndef VERILATOR
initial begin
assert(ID_BITWIDTH > 0) else $error("ID_BITWIDTH has to be larger than 0");
assert(PRIORITY_BITWIDTH > 0) else $error("PRIORITY_BITWIDTH has to be larger than 0");
end
`endif
//pragma translate_on
endmodule

78
src/plic/plic_find_max.sv Normal file
View file

@ -0,0 +1,78 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
//-------------------------------------------------------------------------------
//-- Title : Find Maximun
//-- File : plic_find_max.sv
//-- Author : Gian Marti <gimarti.student.ethz.ch>
//-- Author : Thomas Kramer <tkramer.student.ethz.ch>
//-- Author : Thomas E. Benz <tbenz.student.ethz.ch>
//-- Company : Integrated Systems Laboratory, ETH Zurich
//-- Created : 2018-03-31
//-- Last update: 2018-03-31
//-- Platform : ModelSim (simulation), Synopsys (synthesis)
//-- Standard : SystemVerilog IEEE 1800-2012
//-------------------------------------------------------------------------------
//-- Description: Find the element with the largest priority
//-------------------------------------------------------------------------------
//-- Revisions :
//-- Date Version Author Description
//-- 2018-03-31 2.0 tbenz Created header
//-------------------------------------------------------------------------------
module plic_find_max #(
parameter int NUM_OPERANDS = 2,
parameter int ID_BITWIDTH = 4,
parameter int PRIORITY_BITWIDTH = 3
)(
input logic [PRIORITY_BITWIDTH-1:0] priorities_i [NUM_OPERANDS],
input logic [ID_BITWIDTH-1:0 ] identifiers_i [NUM_OPERANDS],
output logic [PRIORITY_BITWIDTH-1:0] largest_priority_o,
output logic [ID_BITWIDTH-1:0 ] identifier_of_largest_o
);
localparam int max_stage = ($clog2(NUM_OPERANDS)-1);
localparam int num_operands_aligned = 2**(max_stage+1);
logic [PRIORITY_BITWIDTH-1:0] priority_stages [max_stage + 2][num_operands_aligned];
logic [ID_BITWIDTH-1:0 ] identifier_stages [max_stage + 2][num_operands_aligned];
always_comb begin : proc_zero_padding
for (integer operand = 0; operand < num_operands_aligned; operand++) begin
if(operand < NUM_OPERANDS) begin
priority_stages [0][operand] = priorities_i [operand];
identifier_stages[0][operand] = identifiers_i [operand];
end else begin
priority_stages [0][operand] = '0;
identifier_stages[0][operand] = '0;
end
end
end
for (genvar comparator_stage = max_stage; comparator_stage >= 0 ; comparator_stage--) begin
for (genvar stage_index = 0; stage_index < 2**comparator_stage; stage_index++) begin
plic_comparator #(
.ID_BITWIDTH (ID_BITWIDTH ),
.PRIORITY_BITWIDTH (PRIORITY_BITWIDTH )
) comp_instance(
.left_priority_i ( priority_stages [max_stage - comparator_stage][2*stage_index] ),
.right_priority_i ( priority_stages [max_stage - comparator_stage][2*stage_index + 1] ),
.left_identifier_i ( identifier_stages[max_stage - comparator_stage][2*stage_index] ),
.right_identifier_i ( identifier_stages[max_stage - comparator_stage][2*stage_index + 1] ),
.larger_priority_o ( priority_stages [max_stage - (comparator_stage-1)][stage_index] ),
.identifier_of_larger_o ( identifier_stages[max_stage - (comparator_stage-1)][stage_index] )
);
end
end
assign largest_priority_o = priority_stages [max_stage+1][0];
assign identifier_of_largest_o = identifier_stages[max_stage+1][0];
endmodule

80
src/plic/plic_gateway.sv Normal file
View file

@ -0,0 +1,80 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
//-------------------------------------------------------------------------------
//-- Title : Interrupt Gateway
//-- File : plic_gateway.sv
//-- Author : Gian Marti <gimarti.student.ethz.ch>
//-- Author : Thomas Kramer <tkramer.student.ethz.ch>
//-- Author : Thomas E. Benz <tbenz.student.ethz.ch>
//-- Company : Integrated Systems Laboratory, ETH Zurich
//-- Created : 2018-03-31
//-- Last update: 2018-03-31
//-- Platform : ModelSim (simulation), Synopsys (synthesis)
//-- Standard : SystemVerilog IEEE 1800-2012
//-------------------------------------------------------------------------------
//-- Description: Implementation of the Irq Gateway
//-------------------------------------------------------------------------------
//-- Revisions :
//-- Date Version Author Description
//-- 2018-03-31 2.0 tbenz Created header
//-------------------------------------------------------------------------------
// the gateway does enable or disable itself depending on the signals claim_i, completed_i
// the gateway knows neither its gateway_id nor its priority
module plic_gateway (
input logic clk_i,
input logic rst_ni,
input logic irq_source_i,
input logic claim_i,
input logic completed_i,
output logic irq_pending_o
);
logic irq_pending_q; // is 1 when an interrupt appears until the interrupt is claimed
logic wait_completion_q; // is 1 when an interrupt appears until the interrupt is completed
// also determines if the gateway is disabled, i.e. if interrupts are masked
logic irq_trigger;
assign irq_trigger = (~wait_completion_q | completed_i) & irq_source_i;
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_update_ff
if (~rst_ni) begin
irq_pending_q <= 1'b0;
wait_completion_q <= 1'b0;
end else begin
//pragma translate_off
`ifndef VERILATOR
assert (~(claim_i & (~wait_completion_q & irq_source_i)));
assert (~(completed_i & (~wait_completion_q & irq_source_i)));
`endif
//pragma translate_on
//interrupts not masked and interrupt received -> output to 1
if (irq_trigger) begin
irq_pending_q <= 1;
//interrupt claimed -> output to 0
end else if (claim_i) begin
irq_pending_q <= 0;
end
//interrupts not masked and interrupt received -> interrupts masked from know on
if (irq_trigger) begin
wait_completion_q <= 1;
//interrupt completed -> demask interrupts
end else if (completed_i) begin
wait_completion_q <= 0;
end
end
end
// Make sure there is 0 cycles delay from claim_i to irq_pending_o.
assign irq_pending_o = (irq_pending_q | irq_trigger) & ~claim_i;
endmodule

304
src/plic/plic_interface.sv Normal file
View file

@ -0,0 +1,304 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
//-------------------------------------------------------------------------------
//-- Title : Register Interface
//-- File : plic_target_slice.sv
//-- Author : Gian Marti <gimarti.student.ethz.ch>
//-- Author : Thomas Kramer <tkramer.student.ethz.ch>
//-- Author : Thomas E. Benz <tbenz.student.ethz.ch>
//-- Company : Integrated Systems Laboratory, ETH Zurich
//-- Created : 2018-03-31
//-- Last update: 2018-03-31
//-- Platform : ModelSim (simulation), Synopsys (synthesis)
//-- Standard : SystemVerilog IEEE 1800-2012
//-------------------------------------------------------------------------------
//-- Description: Implementation of the plic's register interface
//-------------------------------------------------------------------------------
//-- Revisions :
//-- Date Version Author Description
//-- 2018-03-31 2.0 tbenz Created header
//-------------------------------------------------------------------------------
module plic_interface #(
parameter int ADDR_WIDTH = 32, // width of external address bus
parameter int DATA_WIDTH = 32, // width of external data bus
parameter int ID_BITWIDTH = 10, // width of the gateway indecies
parameter int PARAMETER_BITWIDTH = 3, // width of the internal parameter e.g. priorities
parameter int NUM_TARGETS = 1, // number of target slices
parameter int NUM_GATEWAYS = 1 // number of gateways
)(
input logic clk_i, // the clock signal
input logic rst_ni, // asynchronous reset active low
input logic[ID_BITWIDTH-1:0] id_of_largest_priority_i[NUM_TARGETS], // input array id of largest priority
input logic pending_array_i[NUM_GATEWAYS], // array with the interrupt pending , idx0 is gateway 1
output reg [PARAMETER_BITWIDTH-1:0] thresholds_o[NUM_TARGETS], // save internally the thresholds, communicate values over this port to the core
output reg [PARAMETER_BITWIDTH-1:0] gateway_priorities_o[NUM_GATEWAYS], // save internally the the priorities, communicate values
output logic irq_enables_o[NUM_GATEWAYS][NUM_TARGETS], // communicate enable bits over this port
output logic target_irq_claims_o[NUM_TARGETS], // claim signals
output logic target_irq_completes_o[NUM_TARGETS], // complete signals
output logic[ID_BITWIDTH-1:0] target_irq_completes_id_o[NUM_TARGETS], // the id of the gateway to be completed
REG_BUS.in external_bus_io // the bus
);
//define ennumerated types
enum logic [2:0] {INV, PRI, IPA, IEB, THR, CCP} funct; // the address mapping will primarily check what
// function should be performed
// INV: invalid, PRI: priorities, IPA: interrupt pending
// IEB: interrupt enable, THR: threshold and claim/complete
// CCP: claim/clear pulses
//calculate some parameter needed later
localparam int num_gateway_bundles = (NUM_GATEWAYS-1) / DATA_WIDTH + 1; // how many bundles we have to consider
localparam int bpw = DATA_WIDTH / 8; // how many bytes a data word consist of
//internal signals
logic [ADDR_WIDTH-12-1:0 ] page_address; // the upper part of the address
logic [11:0 ] page_offset; // the lowest 12 bit describes the page offset
logic [11-$clog2(bpw):0 ] page_word_offset; // the word address of each page offset
logic [$clog2(bpw)-1:0 ] word_offset; // the byte in the word
logic [DATA_WIDTH/8-1:0 ] write_active; // 0 if inactive, else what byte ahs to be written
logic read_active; // 0 if inactive, 1 when reading the word
//bundle definitions
logic [DATA_WIDTH-1:0 ] irq_pending_bundle[num_gateway_bundles];
//registers
logic [PARAMETER_BITWIDTH-1:0] thresholds_d[NUM_TARGETS];
logic [PARAMETER_BITWIDTH-1:0] thresholds_q[NUM_TARGETS];
logic [PARAMETER_BITWIDTH-1:0] priorities_d[NUM_GATEWAYS];
logic [PARAMETER_BITWIDTH-1:0] priorities_q[NUM_GATEWAYS];
logic [ID_BITWIDTH-1:0 ] id_of_largest_priority_d[NUM_TARGETS];
logic [ID_BITWIDTH-1:0 ] id_of_largest_priority_q[NUM_TARGETS];
logic [DATA_WIDTH/bpw-1:0 ] ena_bundles_d[num_gateway_bundles][NUM_TARGETS][DATA_WIDTH/8];
logic [DATA_WIDTH/bpw-1:0 ] ena_bundles_q[num_gateway_bundles][NUM_TARGETS][DATA_WIDTH/8];
// assignments
assign id_of_largest_priority_d = id_of_largest_priority_i;
// assign addresses
assign page_address = external_bus_io.addr[ADDR_WIDTH-1:12];
assign page_offset = external_bus_io.addr[11:0 ];
assign page_word_offset = external_bus_io.addr[11:$clog2(bpw) ];
assign word_offset = external_bus_io.addr[$clog2(bpw)-1:0];
assign write_active = (external_bus_io.valid & external_bus_io.write) ? external_bus_io.wstrb : '0;
assign read_active = external_bus_io.valid & !external_bus_io.write;
// bundle signals
for (genvar bundle = 0; bundle < num_gateway_bundles; bundle++) begin
for (genvar ip_bit = 0; ip_bit < DATA_WIDTH; ip_bit++) begin
if (bundle * DATA_WIDTH + ip_bit < NUM_GATEWAYS) begin
assign irq_pending_bundle[bundle][ip_bit] = pending_array_i[bundle * DATA_WIDTH + ip_bit];
end else begin
assign irq_pending_bundle[bundle][ip_bit] = '0;
end
end
end
for (genvar bundle = 0; bundle < num_gateway_bundles; bundle++) begin
for (genvar target = 0; target < NUM_TARGETS; target++) begin
for (genvar byte_in_word = 0; byte_in_word < DATA_WIDTH/8; byte_in_word++) begin
for (genvar enable_bit = 0; enable_bit < 8; enable_bit++) begin
assign irq_enables_o[bundle * DATA_WIDTH + enable_bit + byte_in_word * 8][target] =
ena_bundles_q[bundle][target][byte_in_word][enable_bit];
end
end
end
end
// determine the function to be performed
always_comb begin : proc_address_map
// default values
funct = INV;
// only aligned access is allowed:
if (word_offset == '0) begin
// we have now an word alligned access -> check out page offset to determine
// what type of access this is.
if (page_address[13:0] == 0) begin // we access the gateway priority bits
// the page_word_offset tells us now which gateway we consider
// in order to grant or deny access, we have to check if the gateway
// in question really exist.
// Gateway 0 does not exist, so return an error
if (page_word_offset <= NUM_GATEWAYS && page_word_offset > 0) begin //the gateway in question exists
// set the current operation to be an access to the priority registers
funct = PRI;
end
// we now access the IP Bits, read only
end else if (page_address[13:0] == 1) begin
// the page_word_offset tells us now, which word we have to consider,
// the word, which includes the IP bit in question should be returned
if (page_word_offset<num_gateway_bundles) begin
funct = IPA;
end
// access of the enable bits for each target
end else if (page_address[13:9] == 0) begin
// the bottom part page_word_offset now tells us which gateway bundle we have to consider
// part of the page_address and the upper part of the page_word_offset give us the target nr.
if (page_offset[6:$clog2(bpw)] < num_gateway_bundles) begin
if (({page_address[8:0], page_offset[11:7]} - 64) < NUM_TARGETS) begin
funct = IEB;
end
end
// priority / claim / complete
end else begin
// page address - 0h20 gives the target number
if (page_address[13:0] - 'h200 < NUM_TARGETS) begin
// check lowest bit of the page_word_offset to get the exact function
if (page_word_offset == 0) begin
funct = THR;
end else if (page_word_offset == 1) begin
funct = CCP;
end
end
end
end
end
always_comb begin : proc_read_write
// defalt values
external_bus_io.rdata = 0;
external_bus_io.error = 0;
external_bus_io.ready = 0;
for (integer target = 0; target<NUM_TARGETS; target++) begin
target_irq_claims_o [target] = '0;
target_irq_completes_o [target] = '0;
target_irq_completes_id_o[target] = '0;
end
//just keep the values untouched as default
priorities_d = priorities_q;
ena_bundles_d = ena_bundles_q;
thresholds_d = thresholds_q;
case (funct)
PRI: begin
// read case
if (read_active != 0) begin
external_bus_io.rdata = priorities_q[page_word_offset-1];
external_bus_io.ready = 1;
// write case
end else if (write_active[0] == 1) begin
priorities_d[page_word_offset-1] = external_bus_io.wdata[PARAMETER_BITWIDTH-1:0];
external_bus_io.ready = 1;
end
end
IPA: begin
// read case
if (read_active != 0) begin
external_bus_io.rdata = irq_pending_bundle[page_word_offset];
external_bus_io.ready = 1;
// write case
end else if (write_active != 0) begin
external_bus_io.error = 1; //not allowed
end
end
IEB: begin
// read case
if (read_active != 0) begin
for (integer byte_in_word = 0; byte_in_word < DATA_WIDTH/8; byte_in_word++) begin
external_bus_io.rdata[8*(byte_in_word) +: 8] = ena_bundles_q[page_offset[6:$clog2(bpw)]][({page_address[8:0], page_offset[11:7]} - 64)][byte_in_word];
end
external_bus_io.ready = 1;
// write case
end else if(write_active != 0) begin
for (integer byte_in_word=0; byte_in_word<DATA_WIDTH/8; byte_in_word++) begin
if(write_active[byte_in_word]) begin
ena_bundles_d[page_offset[6:$clog2(bpw)]][({page_address[8:0], page_offset[11:7]} - 64)][byte_in_word] = external_bus_io.wdata[8*(byte_in_word) +: 8];
end
end
external_bus_io.ready = 1;
end
end
THR: begin
// read case
if (read_active != 0) begin
external_bus_io.rdata[PARAMETER_BITWIDTH-1:0] = thresholds_q[(page_address[13:0] - 'h200)];
external_bus_io.ready = 1;
// write case
end else if (write_active != 0) begin
thresholds_d[(page_address[13:0] - 'h200)] = external_bus_io.wdata[PARAMETER_BITWIDTH-1:0];
external_bus_io.ready = 1;
end
end
CCP: begin
// read case
if (read_active != 0) begin
target_irq_claims_o[(page_address[13:0] - 'h200)] = 1;
external_bus_io.rdata[ID_BITWIDTH-1:0] = id_of_largest_priority_q[(page_address[13:0] - 'h200)];
external_bus_io.ready = 1;
// write case
end else if (write_active != 0) begin
target_irq_completes_o[(page_address[13:0] - 'h200)] = 1;
target_irq_completes_id_o[(page_address[13:0] - 'h200)] = external_bus_io.wdata[ID_BITWIDTH-1:0];
external_bus_io.ready = 1;
end
end
default : begin
//per default: error
external_bus_io.error = 1;
external_bus_io.ready = 1;
end
endcase // funct
end
// store data in flip flops
always_ff @(posedge clk_i or negedge rst_ni) begin : proc_update_ff
if (~rst_ni) begin // set all registers to 0
for (integer gateway = 0; gateway < NUM_GATEWAYS; gateway++)
priorities_q[gateway] <= 0;
for (integer bundle = 0; bundle < num_gateway_bundles; bundle++)
for (integer target = 0; target < NUM_TARGETS; target++)
for (integer byte_in_word = 0; byte_in_word < DATA_WIDTH/8; byte_in_word++)
ena_bundles_q[bundle][target][byte_in_word] <= 0;
for (integer target = 0; target < NUM_TARGETS; target++) begin
thresholds_q[target] <= 0;
id_of_largest_priority_q[target] <= 0;
end
end else begin
priorities_q <= priorities_d;
ena_bundles_q <= ena_bundles_d;
thresholds_q <= thresholds_d;
id_of_largest_priority_q <= id_of_largest_priority_d;
end
end
//assign outputs
assign thresholds_o = thresholds_q;
assign gateway_priorities_o = priorities_q;
// pragma translate_off
`ifndef VERILATOR
initial begin
assert ((ADDR_WIDTH==32) | (ADDR_WIDTH==64)) else $error("Address width has to bei either 32 or 64 bit");
assert ((DATA_WIDTH==32) | (DATA_WIDTH==64)) else $error("Data width has to bei either 32 or 64 bit");
assert (ID_BITWIDTH>0) else $error("ID_BITWIDTH has to be larger than 1");
assert (ID_BITWIDTH<10) else $error("ID_BITWIDTH has to be smaller than 10");
assert (PARAMETER_BITWIDTH>0) else $error("PARAMETER_BITWIDTH has to be larger than 1");
assert (PARAMETER_BITWIDTH<8) else $error("PARAMETER_BITWIDTH has to be smaller than 8");
assert (NUM_GATEWAYS>0) else $error("Num od Gateways has to be larger than 1");
assert (NUM_GATEWAYS<512) else $error("Num of Gateways has to be smaller than 512");
assert (NUM_TARGETS>0) else $error("Num Target slices has to be larger than 1");
assert (NUM_TARGETS<15872) else $error("Num target slices has to be smaller than 15872");
end
`endif
// pragma translate_on
endmodule

View file

@ -0,0 +1,92 @@
// Copyright 2018 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this 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.
//
//-------------------------------------------------------------------------------
//-- Title : Target Slice
//-- File : plic_target_slice.sv
//-- Author : Gian Marti <gimarti.student.ethz.ch>
//-- Author : Thomas Kramer <tkramer.student.ethz.ch>
//-- Author : Thomas E. Benz <tbenz.student.ethz.ch>
//-- Company : Integrated Systems Laboratory, ETH Zurich
//-- Created : 2018-03-31
//-- Last update: 2018-03-31
//-- Platform : ModelSim (simulation), Synopsys (synthesis)
//-- Standard : SystemVerilog IEEE 1800-2012
//-------------------------------------------------------------------------------
//-- Description: Target Slice
//-------------------------------------------------------------------------------
//-- Revisions :
//-- Date Version Author Description
//-- 2018-03-31 2.0 tbenz Created header
//-------------------------------------------------------------------------------
// Note: The gateways are expected to be ordered by their IDs (ascending).
// This resolves priority ties by choosing the gateway with the lower ID.
module plic_target_slice #(
parameter int PRIORITY_BITWIDTH = 8,
parameter int ID_BITWIDTH = 8,
parameter int NUM_GATEWAYS = 1
)(
// Input signals from gateways.
input logic interrupt_pending_i [NUM_GATEWAYS],
input logic [PRIORITY_BITWIDTH-1:0] interrupt_priority_i[NUM_GATEWAYS],
input logic [ID_BITWIDTH-1:0 ] interrupt_id_i [NUM_GATEWAYS],
input logic interrupt_enable_i [NUM_GATEWAYS],
input logic [PRIORITY_BITWIDTH-1:0] threshold_i,
output logic ext_interrupt_present_o,
output logic [ID_BITWIDTH-1:0 ] identifier_of_largest_o
);
logic[PRIORITY_BITWIDTH:0] interrupt_priority_masked[NUM_GATEWAYS];
// Signals that represent the selected interrupt source.
logic[PRIORITY_BITWIDTH:0] best_priority;
logic[ID_BITWIDTH-1:0 ] best_id;
// Create a tree to find the best interrupt source.
plic_find_max #(
.NUM_OPERANDS ( NUM_GATEWAYS ),
.ID_BITWIDTH ( ID_BITWIDTH ),
.PRIORITY_BITWIDTH ( PRIORITY_BITWIDTH + 1 )
) find_max_instance (
.priorities_i ( interrupt_priority_masked ),
.identifiers_i ( interrupt_id_i ),
// Outputs
.largest_priority_o ( best_priority ),
.identifier_of_largest_o ( best_id )
);
// Compare the priority of the best interrupt source to the threshold.
always_comb begin : proc_compare_threshold
if ((best_priority - 1 > threshold_i) && (best_priority != '0)) begin
ext_interrupt_present_o = 1;
identifier_of_largest_o = best_id;
end else begin
if ((best_priority - 1 <= threshold_i) && (best_priority != '0)) begin
ext_interrupt_present_o = 0;
identifier_of_largest_o = best_id;
end else begin
ext_interrupt_present_o = 0;
identifier_of_largest_o = 0;
end
end
end
always_comb begin : proc_mask_gateway_outputs
for (int i = 0; i < NUM_GATEWAYS; i++) begin
if (interrupt_enable_i[i] && interrupt_pending_i[i]) begin
interrupt_priority_masked[i] = interrupt_priority_i[i] + 1; //priority shift +1
end else begin
interrupt_priority_masked[i] = '0;
end
end
end
endmodule

@ -0,0 +1 @@
Subproject commit d10dce04b7211da044d31baaa06c7044c84083d9

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