From 0ae3fb5ebb96cd94396579a0ffb11027f96920ee Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Thu, 6 Sep 2018 12:08:50 +0200 Subject: [PATCH] Clean-up and fpga preparataion - fix CDC - Bump repo versions - Fix interface issue with bypassed read/writes --- .gitmodules | 3 - Makefile | 42 ++--- README.md | 4 + bootrom/bootrom.img | Bin 1122 -> 1144 bytes include/axi_if.sv | 128 ---------------- include/axi_intf.sv | 321 +++++++++++++++++++++++++++++++++++++++ src/axi_adapter.sv | 2 + src/axi_slice | 1 - src/clint/clint.sv | 7 +- src/debug/dmi_cdc.sv | 64 ++++---- tb/ariane_tb.sv | 6 +- tb/ariane_testharness.sv | 49 ++++-- 12 files changed, 427 insertions(+), 200 deletions(-) delete mode 100644 include/axi_if.sv create mode 100644 include/axi_intf.sv delete mode 160000 src/axi_slice diff --git a/.gitmodules b/.gitmodules index 9d2bcb97f..38c356f40 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "src/axi_mem_if"] path = src/axi_mem_if url = https://github.com/pulp-platform/axi_mem_if.git -[submodule "src/axi_slice"] - path = src/axi_slice - url = https://github.com/pulp-platform/axi_slice.git [submodule "src/axi_node"] path = src/axi_node url = https://github.com/pulp-platform/axi_node.git diff --git a/Makefile b/Makefile index 7595da754..34f88b841 100755 --- a/Makefile +++ b/Makefile @@ -10,7 +10,6 @@ ver-library ?= work-ver dpi-library ?= work-dpi # Top level module to compile top_level ?= ariane_tb -test_top_level ?= ariane_tb # Maximum amount of cycles for a successful simulation run max_cycles ?= 10000000 # Test case to run @@ -50,16 +49,21 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \ $(wildcard src/frontend/*.sv) \ $(wildcard src/cache_subsystem/*.sv) \ $(wildcard bootrom/*.sv) \ - $(wildcard src/axi_slice/*.sv) \ $(wildcard src/clint/*.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/axi/src/axi_cut.sv \ + src/axi/src/axi_join.sv \ src/fpga-support/rtl/SyncSpRamBeNx64.sv \ src/common_cells/src/deprecated/generic_fifo.sv \ src/common_cells/src/deprecated/pulp_sync.sv \ - src/common_cells/src/fifo_v2.sv \ + src/common_cells/src/sync.sv \ + src/common_cells/src/spill_register.sv \ + src/common_cells/src/sync_wedge.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/lfsr_8bit.sv \ @@ -85,7 +89,7 @@ riscv-benchmarks := $(shell xargs printf '\n%s' < $(riscv-benchmarks-list) riscv-test ?= rv64ui-p-add # Search here for include files (e.g.: non-standalone components) -incdir := +incdir := # Compile and sim flags compile_flag += +cover=bcfst+/dut -incr -64 -nologo -quiet -suppress 13262 -permissive +define+$(defines) uvm-flags += +UVM_NO_RELNOTES @@ -100,7 +104,7 @@ riscv-torture-bin := java -Xmx1G -Xss8M -XX:MaxPermSize=128M -jar sbt-launch. # 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) $(test_top_level) -o $(test_top_level)_optimized +acc -check_synthesis + 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) @@ -111,7 +115,7 @@ $(library)/.build-srcs: $(ariane_pkg) $(util) $(src) $(library) touch $(library)/.build-srcs # build TBs -$(library)/.build-tb: $(dpi) $(tbs) +$(library)/.build-tb: $(dpi) $(tbs) # Compile top level vlog$(questa_version) -sv $(tbs) -work $(library) touch $(library)/.build-tb @@ -120,31 +124,31 @@ $(library): vlib${questa_version} ${library} # compile DPIs -$(dpi-library)/%.o: tb/dpi/%.cc $(dpi_hdr) +$(dpi-library)/%.o: tb/dpi/%.cc $(dpi_hdr) mkdir -p $(dpi-library) $(CXX) -shared -fPIC -std=c++0x -Bsymbolic -I$(QUESTASIM_HOME)/include -o $@ $< -$(dpi-library)/ariane_dpi.so: $(dpi) +$(dpi-library)/ariane_dpi.so: $(dpi) mkdir -p $(dpi-library) # Compile C-code and generate .so file $(CXX) -shared -m64 -o $(dpi-library)/ariane_dpi.so $? -lfesvr -sim: build +sim: build vsim${questa_version} +permissive -64 -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \ +BASEDIR=$(riscv-test-dir) $(uvm-flags) "+UVM_VERBOSITY=LOW" -coverage -classdebug +jtag_rbb_enable=0 \ $(QUESTASIM_FLAGS) \ -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi -do " do tb/wave/wave_core.do; run -all; exit" \ ${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$(riscv-test) ++$(target-options) -simc: build +simc: build vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \ +BASEDIR=$(riscv-test-dir) $(uvm-flags) "+UVM_VERBOSITY=LOW" -coverage -classdebug +jtag_rbb_enable=0 \ $(QUESTASIM_FLAGS) \ -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi -do " run -all; exit" \ ${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$(riscv-test) ++$(target-options) -$(riscv-asm-tests): build +$(riscv-asm-tests): build vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \ +BASEDIR=$(riscv-test-dir) $(uvm-flags) "+UVM_VERBOSITY=LOW" -coverage -classdebug +jtag_rbb_enable=0 \ $(QUESTASIM_FLAGS) \ @@ -152,7 +156,7 @@ $(riscv-asm-tests): build -do "coverage save -onexit tmp/$@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \ ${top_level}_optimized +permissive-off ++$(riscv-test-dir)/$@ ++$(target-options) | tee tmp/riscv-asm-tests-$@.log -$(riscv-benchmarks): build +$(riscv-benchmarks): build vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles) +UVM_TESTNAME=${test_case} \ +BASEDIR=$(riscv-benchmarks-dir) $(uvm-flags) "+UVM_VERBOSITY=LOW" -coverage -classdebug +jtag_rbb_enable=0 \ $(QUESTASIM_FLAGS) \ @@ -199,7 +203,7 @@ verilate_command := $(verilator) --exe tb/ariane_tb.cpp tb/dpi/SimDTM.cc tb/dpi/SimJTAG.cc tb/dpi/remote_bitbang.cc # User Verilator, at some point in the future this will be auto-generated -verilate: +verilate: $(verilate_command) cd $(ver-library) && make -j${NUM_JOBS} -f Variane_testharness.mk @@ -220,10 +224,10 @@ $(addsuffix -verilator,$(riscv-benchmarks)): verilate run-benchmarks-verilator: $(addsuffix -verilator,$(riscv-benchmarks)) # torture-specific -torture-gen: +torture-gen: cd $(riscv-torture-dir) && $(riscv-torture-bin) 'generator/run' -torture-itest: +torture-itest: cd $(riscv-torture-dir) && $(riscv-torture-bin) 'testrun/run -a output/test.S' torture-rtest: build @@ -236,14 +240,14 @@ torture-rtest-verilator: verilate cd $(riscv-torture-dir) && $(riscv-torture-bin) 'testrun/run -r ./call.sh -a output/test.S' | tee output/test.log make check-torture -run-torture: build +run-torture: build vsim${questa_version} +permissive -64 -c -lib ${library} +max-cycles=$(max_cycles)+UVM_TESTNAME=${test_case} \ +BASEDIR=$(riscv-torture-dir) $(uvm-flags) "+UVM_VERBOSITY=LOW" -coverage -classdebug +jtag_rbb_enable=0 \ $(QUESTASIM_FLAGS) \ -gblso $(RISCV)/lib/libfesvr.so -sv_lib $(dpi-library)/ariane_dpi \ -do "coverage save -onexit tmp/$@.ucdb; run -a; quit -code [coverage attribute -name TESTSTATUS -concise]" \ ${top_level}_optimized +permissive-off \ - +signature=$(riscv-torture-dir)/output/test.rtlsim.sig ++$(riscv-torture-dir)/output/test ++$(target-options) + +signature=$(riscv-torture-dir)/output/test.rtlsim.sig ++$(riscv-torture-dir)/output/test ++$(target-options) run-torture-verilator: verilate $(ver-library)/Variane_testharness +max-cycles=$(max_cycles) +signature=$(riscv-torture-dir)/output/test.rtlsim.sig $(riscv-torture-dir)/output/test @@ -254,9 +258,9 @@ check-torture: clean: rm -rf $(riscv-torture-dir)/output/test* - rm -rf $(library)/ $(dpi-library)/ $(ver-library)/ + rm -rf $(library)/ $(dpi-library)/ $(ver-library)/ rm -f tmp/*.ucdb tmp/*.log *.wlf *vstf wlft* *.ucdb - + .PHONY: build sim simc verilate clean \ $(riscv-asm-tests) $(addsuffix _verilator,$(riscv-asm-tests)) \ diff --git a/README.md b/README.md index da8c508dc..41aa7d885 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ Build the Verilator model of Ariane by using the Makefile: ``` $ make verilate ``` +To build the verilator model with support for vcd files run +``` +$ make verilate DEBUG=1 +``` This will create a C++ model of the core including a SystemVerilog wrapper and link it against a C++ testbench (in the `tb` subfolder). The binary can be found in the `work-ver` and accepts a RISC-V ELF binary as an argument, e.g.: diff --git a/bootrom/bootrom.img b/bootrom/bootrom.img index 1cc077cab46d7865848e1b06dfaa2b9f8b3a4732..e15ccba0553d673ed833738439e8ab7c28426850 100644 GIT binary patch delta 84 zcmaFF@q=SRyW$T91_lcT24({wtpUV>Kr8^nAaH_#f$7IYMd6LRr!aCd0|i)scKr8^nAaIC*f$7CWMd6LRr!Y>AXWGEHe6j$u QHRHO?KFrLFlS5gQ0q3I+3;+NC diff --git a/include/axi_if.sv b/include/axi_if.sv deleted file mode 100644 index 4797d2de9..000000000 --- a/include/axi_if.sv +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2015 - 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. -// -//////////////////////////////////////////////////////////////////////////////// -// Only general functions and definitions are defined here // -// These functions are not intended to be modified // -//////////////////////////////////////////////////////////////////////////////// - -interface AXI_BUS -#( - parameter AXI_ADDR_WIDTH = 64, - parameter AXI_DATA_WIDTH = 64, - parameter AXI_ID_WIDTH = 10, - parameter AXI_USER_WIDTH = 6 -); - - localparam AXI_STRB_WIDTH = AXI_DATA_WIDTH/8; - - logic [AXI_ADDR_WIDTH-1:0] aw_addr; - logic [2:0] aw_prot; - logic [3:0] aw_region; - logic [7:0] aw_len; - logic [2:0] aw_size; - logic [1:0] aw_burst; - logic aw_lock; - logic [3:0] aw_cache; - logic [3:0] aw_qos; - logic [AXI_ID_WIDTH-1:0] aw_id; - logic [AXI_USER_WIDTH-1:0] aw_user; - logic aw_ready; - logic aw_valid; - - logic [AXI_ADDR_WIDTH-1:0] ar_addr; - logic [2:0] ar_prot; - logic [3:0] ar_region; - logic [7:0] ar_len; - logic [2:0] ar_size; - logic [1:0] ar_burst; - logic ar_lock; - logic [3:0] ar_cache; - logic [3:0] ar_qos; - logic [AXI_ID_WIDTH-1:0] ar_id; - logic [AXI_USER_WIDTH-1:0] ar_user; - logic ar_ready; - logic ar_valid; - - logic w_valid; - logic [AXI_DATA_WIDTH-1:0] w_data; - logic [AXI_STRB_WIDTH-1:0] w_strb; - logic [AXI_USER_WIDTH-1:0] w_user; - logic w_last; - logic w_ready; - - logic [AXI_DATA_WIDTH-1:0] r_data; - logic [1:0] r_resp; - logic r_last; - logic [AXI_ID_WIDTH-1:0] r_id; - logic [AXI_USER_WIDTH-1:0] r_user; - logic r_ready; - logic r_valid; - - logic [1:0] b_resp; - logic [AXI_ID_WIDTH-1:0] b_id; - logic [AXI_USER_WIDTH-1:0] b_user; - logic b_ready; - logic b_valid; - - // Master Side - //*************************************** - modport Master - ( - - output aw_valid, output aw_addr, output aw_prot, output aw_region, - output aw_len, output aw_size, output aw_burst, output aw_lock, - output aw_cache, output aw_qos, output aw_id, output aw_user, - input aw_ready, - - output ar_valid, output ar_addr, output ar_prot, output ar_region, - output ar_len, output ar_size, output ar_burst, output ar_lock, - output ar_cache, output ar_qos, output ar_id, output ar_user, - input ar_ready, - - output w_valid, output w_data, output w_strb, output w_user, output w_last, - input w_ready, - - input r_valid, input r_data, input r_resp, input r_last, input r_id, input r_user, - output r_ready, - - input b_valid, input b_resp, input b_id, input b_user, - output b_ready - - ); - - // Slave Side - //*************************************** - modport Slave - ( - - input aw_valid, input aw_addr, input aw_prot, input aw_region, - input aw_len, input aw_size, input aw_burst, input aw_lock, - input aw_cache, input aw_qos, input aw_id, input aw_user, - output aw_ready, - - input ar_valid, input ar_addr, input ar_prot, input ar_region, - input ar_len, input ar_size, input ar_burst, input ar_lock, - input ar_cache, input ar_qos, input ar_id, input ar_user, - output ar_ready, - - input w_valid, input w_data, input w_strb, input w_user, input w_last, - output w_ready, - - output r_valid, output r_data, output r_resp, output r_last, output r_id, output r_user, - input r_ready, - - output b_valid, output b_resp, output b_id, output b_user, - input b_ready - - ); - -endinterface - diff --git a/include/axi_intf.sv b/include/axi_intf.sv new file mode 100644 index 000000000..2df625fae --- /dev/null +++ b/include/axi_intf.sv @@ -0,0 +1,321 @@ +// Copyright (c) 2014-2018 ETH Zurich, 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. +// +// Fabian Schuiki +// +// This file defines the interfaces we support. + +import axi_pkg::*; + + +/// An AXI4 interface. +interface AXI_BUS #( + parameter AXI_ADDR_WIDTH = -1, + parameter AXI_DATA_WIDTH = -1, + parameter AXI_ID_WIDTH = -1, + parameter AXI_USER_WIDTH = -1 +); + + localparam AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8; + + typedef logic [AXI_ID_WIDTH-1:0] id_t; + typedef logic [AXI_ADDR_WIDTH-1:0] addr_t; + typedef logic [AXI_DATA_WIDTH-1:0] data_t; + typedef logic [AXI_STRB_WIDTH-1:0] strb_t; + typedef logic [AXI_USER_WIDTH-1:0] user_t; + + id_t aw_id; + addr_t aw_addr; + logic [7:0] aw_len; + logic [2:0] aw_size; + burst_t aw_burst; + logic aw_lock; + cache_t aw_cache; + prot_t aw_prot; + qos_t aw_qos; + region_t aw_region; + user_t aw_user; + logic aw_valid; + logic aw_ready; + + data_t w_data; + strb_t w_strb; + logic w_last; + user_t w_user; + logic w_valid; + logic w_ready; + + id_t b_id; + resp_t b_resp; + user_t b_user; + logic b_valid; + logic b_ready; + + id_t ar_id; + addr_t ar_addr; + logic [7:0] ar_len; + logic [2:0] ar_size; + burst_t ar_burst; + logic ar_lock; + cache_t ar_cache; + prot_t ar_prot; + qos_t ar_qos; + region_t ar_region; + user_t ar_user; + logic ar_valid; + logic ar_ready; + + id_t r_id; + data_t r_data; + resp_t r_resp; + logic r_last; + user_t r_user; + logic r_valid; + logic r_ready; + + modport Master ( + output aw_id, aw_addr, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_user, aw_valid, input aw_ready, + output w_data, w_strb, w_last, w_user, w_valid, input w_ready, + input b_id, b_resp, b_user, b_valid, output b_ready, + output ar_id, ar_addr, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_user, ar_valid, input ar_ready, + input r_id, r_data, r_resp, r_last, r_user, r_valid, output r_ready + ); + + modport Slave ( + input aw_id, aw_addr, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_user, aw_valid, output aw_ready, + input w_data, w_strb, w_last, w_user, w_valid, output w_ready, + output b_id, b_resp, b_user, b_valid, input b_ready, + input ar_id, ar_addr, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_user, ar_valid, output ar_ready, + output r_id, r_data, r_resp, r_last, r_user, r_valid, input r_ready + ); + + /// The interface as an output (issuing requests, initiator, master). + modport out ( + output aw_id, aw_addr, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_user, aw_valid, input aw_ready, + output w_data, w_strb, w_last, w_user, w_valid, input w_ready, + input b_id, b_resp, b_user, b_valid, output b_ready, + output ar_id, ar_addr, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_user, ar_valid, input ar_ready, + input r_id, r_data, r_resp, r_last, r_user, r_valid, output r_ready + ); + + /// The interface as an input (accepting requests, target, slave). + modport in ( + input aw_id, aw_addr, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_user, aw_valid, output aw_ready, + input w_data, w_strb, w_last, w_user, w_valid, output w_ready, + output b_id, b_resp, b_user, b_valid, input b_ready, + input ar_id, ar_addr, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_user, ar_valid, output ar_ready, + output r_id, r_data, r_resp, r_last, r_user, r_valid, input r_ready + ); + +endinterface + + +/// An asynchronous AXI4 interface. +interface AXI_BUS_ASYNC +#( + parameter AXI_ADDR_WIDTH = -1, + parameter AXI_DATA_WIDTH = -1, + parameter AXI_ID_WIDTH = -1, + parameter AXI_USER_WIDTH = -1, + parameter BUFFER_WIDTH = -1 +); + + localparam AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8; + + + logic [AXI_ID_WIDTH-1:0] aw_id; + logic [AXI_ADDR_WIDTH-1:0] aw_addr; + logic [7:0] aw_len; + logic [2:0] aw_size; + logic [1:0] aw_burst; + logic aw_lock; + logic [3:0] aw_cache; + logic [2:0] aw_prot; + logic [3:0] aw_qos; + logic [3:0] aw_region; + logic [AXI_USER_WIDTH-1:0] aw_user; + logic [BUFFER_WIDTH-1:0] aw_writetoken; + logic [BUFFER_WIDTH-1:0] aw_readpointer; + + logic [AXI_DATA_WIDTH-1:0] w_data; + logic [AXI_STRB_WIDTH-1:0] w_strb; + logic w_last; + logic [AXI_USER_WIDTH-1:0] w_user; + logic [BUFFER_WIDTH-1:0] w_writetoken; + logic [BUFFER_WIDTH-1:0] w_readpointer; + + logic [AXI_ID_WIDTH-1:0] b_id; + logic [1:0] b_resp; + logic [AXI_USER_WIDTH-1:0] b_user; + logic [BUFFER_WIDTH-1:0] b_writetoken; + logic [BUFFER_WIDTH-1:0] b_readpointer; + + logic [AXI_ID_WIDTH-1:0] ar_id; + logic [AXI_ADDR_WIDTH-1:0] ar_addr; + logic [7:0] ar_len; + logic [2:0] ar_size; + logic [1:0] ar_burst; + logic ar_lock; + logic [3:0] ar_cache; + logic [2:0] ar_prot; + logic [3:0] ar_qos; + logic [3:0] ar_region; + logic [AXI_USER_WIDTH-1:0] ar_user; + logic [BUFFER_WIDTH-1:0] ar_writetoken; + logic [BUFFER_WIDTH-1:0] ar_readpointer; + + logic [AXI_ID_WIDTH-1:0] r_id; + logic [AXI_DATA_WIDTH-1:0] r_data; + logic [1:0] r_resp; + logic r_last; + logic [AXI_USER_WIDTH-1:0] r_user; + logic [BUFFER_WIDTH-1:0] r_writetoken; + logic [BUFFER_WIDTH-1:0] r_readpointer; + + modport Master ( + output aw_id, aw_addr, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_user, aw_writetoken, input aw_readpointer, + output w_data, w_strb, w_last, w_user, w_writetoken, input w_readpointer, + input b_id, b_resp, b_user, b_writetoken, output b_readpointer, + output ar_id, ar_addr, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_user, ar_writetoken, input ar_readpointer, + input r_id, r_data, r_resp, r_last, r_user, r_writetoken, output r_readpointer + ); + + modport Slave ( + input aw_id, aw_addr, aw_len, aw_size, aw_burst, aw_lock, aw_cache, aw_prot, aw_qos, aw_region, aw_user, aw_writetoken, output aw_readpointer, + input w_data, w_strb, w_last, w_user, w_writetoken, output w_readpointer, + output b_id, b_resp, b_user, b_writetoken, input b_readpointer, + input ar_id, ar_addr, ar_len, ar_size, ar_burst, ar_lock, ar_cache, ar_prot, ar_qos, ar_region, ar_user, ar_writetoken, output ar_readpointer, + output r_id, r_data, r_resp, r_last, r_user, r_writetoken, input r_readpointer + ); + +endinterface + + +/// An AXI4-Lite interface. +interface AXI_LITE #( + parameter AXI_ADDR_WIDTH = -1, + parameter AXI_DATA_WIDTH = -1 +); + + localparam AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8; + + typedef logic [AXI_ADDR_WIDTH-1:0] addr_t; + typedef logic [AXI_DATA_WIDTH-1:0] data_t; + typedef logic [AXI_STRB_WIDTH-1:0] strb_t; + + // AW channel + addr_t aw_addr; + logic aw_valid; + logic aw_ready; + + data_t w_data; + strb_t w_strb; + logic w_valid; + logic w_ready; + + resp_t b_resp; + logic b_valid; + logic b_ready; + + addr_t ar_addr; + logic ar_valid; + logic ar_ready; + + data_t r_data; + resp_t r_resp; + logic r_valid; + logic r_ready; + + modport Master ( + output aw_addr, aw_valid, input aw_ready, + output w_data, w_strb, w_valid, input w_ready, + input b_resp, b_valid, output b_ready, + output ar_addr, ar_valid, input ar_ready, + input r_data, r_resp, r_valid, output r_ready + ); + + modport Slave ( + input aw_addr, aw_valid, output aw_ready, + input w_data, w_strb, w_valid, output w_ready, + output b_resp, b_valid, input b_ready, + input ar_addr, ar_valid, output ar_ready, + output r_data, r_resp, r_valid, input r_ready + ); + + /// The interface as an output (issuing requests, initiator, master). + modport out ( + output aw_addr, aw_valid, input aw_ready, + output w_data, w_strb, w_valid, input w_ready, + input b_resp, b_valid, output b_ready, + output ar_addr, ar_valid, input ar_ready, + input r_data, r_resp, r_valid, output r_ready + ); + + /// The interface as an input (accepting requests, target, slave). + modport in ( + input aw_addr, aw_valid, output aw_ready, + input w_data, w_strb, w_valid, output w_ready, + output b_resp, b_valid, input b_ready, + input ar_addr, ar_valid, output ar_ready, + output r_data, r_resp, r_valid, input r_ready + ); + +endinterface + + +/// An AXI routing table. +/// +/// For each slave, multiple rules can be defined. Each rule consists of an +/// address mask and a base. Addresses are masked and then compared against the +/// base to decide where transfers need to go. +interface AXI_ROUTING_RULES #( + /// The address width. + parameter int AXI_ADDR_WIDTH = -1, + /// The number of slaves in the routing table. + parameter int NUM_SLAVE = -1, + /// The number of rules in the routing table. + parameter int NUM_RULES = -1 +); + + struct packed { + logic enabled; + logic [AXI_ADDR_WIDTH-1:0] mask; + logic [AXI_ADDR_WIDTH-1:0] base; + } [NUM_RULES-1:0] rules [NUM_SLAVE]; + + modport xbar(input rules); + modport cfg(output rules); + +endinterface + + +/// An AXI arbitration interface. +interface AXI_ARBITRATION #( + /// The number of requestors. + parameter int NUM_REQ = -1 +); + + // Incoming requests. + logic [NUM_REQ-1:0] in_req; + logic [NUM_REQ-1:0] in_ack; + + // Outgoing request. + logic out_req; + logic out_ack; + logic [$clog2(NUM_REQ)-1:0] out_sel; + + // The arbiter side of the interface. + modport arb(input in_req, out_ack, output out_req, out_sel, in_ack); + + // The requestor side of the interface. + modport req(output in_req, out_ack, input out_req, out_sel, in_ack); + +endinterface diff --git a/src/axi_adapter.sv b/src/axi_adapter.sv index 03166754d..7b7766132 100644 --- a/src/axi_adapter.sv +++ b/src/axi_adapter.sv @@ -131,6 +131,8 @@ module axi_adapter #( axi.w_valid = 1'b1; // its a single write if (type_i == SINGLE_REQ) begin + // only a single write so the data is already the last one + axi.w_last = 1'b1; // single req can be granted here gnt_o = axi.aw_ready & axi.w_ready; gnt_id_o = id_i; diff --git a/src/axi_slice b/src/axi_slice deleted file mode 160000 index f8886bd3f..000000000 --- a/src/axi_slice +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f8886bd3f2d4967aaccff15b67bf1f9e1a0e3453 diff --git a/src/clint/clint.sv b/src/clint/clint.sv index 76fe06d76..659d6cefd 100644 --- a/src/clint/clint.sv +++ b/src/clint/clint.sv @@ -27,9 +27,7 @@ module clint #( AXI_BUS.Slave slave, - input logic halted_i, // cores are halted, also halt timer input logic rtc_i, // Real-time clock in (usually 32.768 kHz) - output logic [63:0] time_o, // Global Time out, this is the time-base of the whole SoC output logic [NR_CORES-1:0] timer_irq_o, // Timer interrupts output logic [NR_CORES-1:0] ipi_o // software interrupt (a.k.a inter-process-interrupt) ); @@ -54,9 +52,6 @@ module clint #( // increase the timer logic increase_timer; - // directly output the mtime_q register - this needs synchronization (but in the core). - assign time_o = mtime_q; - // ----------------------------- // AXI Interface Logic // ----------------------------- @@ -82,7 +77,7 @@ module clint #( mtimecmp_n = mtimecmp_q; msip_n = msip_q; // RTC says we should increase the timer - if (increase_timer && !halted_i) + if (increase_timer) mtime_n = mtime_q + 1; // written from APB bus - gets priority diff --git a/src/debug/dmi_cdc.sv b/src/debug/dmi_cdc.sv index 0f2188965..4740f2e17 100644 --- a/src/debug/dmi_cdc.sv +++ b/src/debug/dmi_cdc.sv @@ -174,6 +174,8 @@ module dmi_cdc_jtag #( logic [DATA_WIDTH/8-1:0] cdc_be_p; logic [DATA_WIDTH-1:0] cdc_wdata_p; + logic cdc_req_n; + logic cdc_clear_p; logic cdc_ack; @@ -184,7 +186,7 @@ module dmi_cdc_jtag #( req_state_n = req_state_p; mem_gnt_o = 1'b0; - cdc_req_ao = 1'b0; + cdc_req_n = 1'b0; unique case (req_state_p) IDLE: begin @@ -196,7 +198,7 @@ module dmi_cdc_jtag #( end WAIT_ACK_HIGH: begin - cdc_req_ao = 1'b1; + cdc_req_n = 1'b1; if (cdc_ack) begin req_state_n = WAIT_ACK_LOW; @@ -255,8 +257,7 @@ module dmi_cdc_jtag #( endcase end - always_ff @(posedge tck_i, negedge trst_ni) - begin + always_ff @(posedge tck_i, negedge trst_ni) begin if (~trst_ni) begin req_state_p <= IDLE; resp_state_p <= RIDLE; @@ -266,9 +267,11 @@ module dmi_cdc_jtag #( cdc_be_p <= '0; cdc_wdata_p <= '0; cdc_clear_p <= '0; + cdc_req_ao <= 1'b0; end else begin req_state_p <= req_state_n; resp_state_p <= resp_state_n; + cdc_req_ao <= cdc_req_n; if (mem_gnt_o) begin cdc_addr_p <= mem_addr_i; @@ -286,16 +289,18 @@ module dmi_cdc_jtag #( assign cdc_wdata_ao = cdc_wdata_p; assign cdc_clear_ao = cdc_clear_p; - pulp_sync i_sync_ack ( + (* ASYNC_REG = "TRUE" *) + sync i_sync_ack ( .clk_i ( tck_i ), - .rstn_i ( trst_ni ) , + .rst_ni ( trst_ni ) , .serial_i ( cdc_ack_ai ), .serial_o ( cdc_ack ) ); - pulp_sync i_sync_rreq ( + (* ASYNC_REG = "TRUE" *) + sync i_sync_rreq ( .clk_i ( tck_i ), - .rstn_i ( trst_ni ) , + .rst_ni ( trst_ni ) , .serial_i ( cdc_rreq_ai ), .serial_o ( cdc_rreq ) ); @@ -356,11 +361,13 @@ module dmi_cdc_mem #( logic [DATA_WIDTH-1:0] cdc_rdata_p; logic cdc_rerror_p; - always_comb - begin + logic cdc_rreq_n; + logic cdc_ack_n; + + always_comb begin req_state_n = req_state_p; - cdc_ack_ao = 1'b0; + cdc_ack_n = 1'b0; cdc_sample = 1'b0; mem_req_o = 1'b0; @@ -375,7 +382,7 @@ module dmi_cdc_mem #( REQUEST: begin mem_req_o = 1'b1; - cdc_ack_ao = 1'b1; + cdc_ack_n = 1'b1; if (mem_gnt_i) begin req_state_n = WAIT_REQ_LOW; @@ -383,7 +390,7 @@ module dmi_cdc_mem #( end WAIT_REQ_LOW: begin - cdc_ack_ao = 1'b1; + cdc_ack_n = 1'b1; if (~cdc_req) begin req_state_n = IDLE; @@ -397,10 +404,9 @@ module dmi_cdc_mem #( req_state_n = IDLE; end - always_comb - begin + always_comb begin resp_state_n = resp_state_p; - cdc_rreq_ao = 1'b0; + cdc_rreq_n = 1'b0; unique case (resp_state_p) RIDLE: begin @@ -410,7 +416,7 @@ module dmi_cdc_mem #( end WAIT_ACK_HIGH: begin - cdc_rreq_ao = 1'b1; + cdc_rreq_n = 1'b1; if (cdc_rack) begin resp_state_n = WAIT_ACK_LOW; @@ -418,7 +424,7 @@ module dmi_cdc_mem #( end WAIT_ACK_LOW: begin - cdc_rreq_ao = 1'b0; + cdc_rreq_n = 1'b0; if (~cdc_rack) begin resp_state_n = RIDLE; @@ -432,8 +438,7 @@ module dmi_cdc_mem #( resp_state_n = RIDLE; end - always_ff @(posedge clk_i, negedge rst_ni) - begin + always_ff @(posedge clk_i, negedge rst_ni) begin if (~rst_ni) begin req_state_p <= IDLE; resp_state_p <= RIDLE; @@ -446,9 +451,13 @@ module dmi_cdc_mem #( cdc_rdata_p <= '0; cdc_rerror_p <= '0; + cdc_rreq_ao <= 1'b0; + cdc_ack_ao <= 1'b0; end else begin req_state_p <= req_state_n; resp_state_p <= resp_state_n; + cdc_rreq_ao <= cdc_rreq_n; + cdc_ack_ao <= cdc_ack_n; if (cdc_sample) begin mem_addr_p <= cdc_addr_ai; @@ -476,23 +485,26 @@ module dmi_cdc_mem #( assign cdc_rdata_ao = cdc_rdata_p; assign cdc_rerror_ao = cdc_rerror_p; - pulp_sync i_sync_req ( + (* ASYNC_REG = "TRUE" *) + sync i_sync_req ( .clk_i ( clk_i ), - .rstn_i ( rst_ni ) , + .rst_ni ( rst_ni ) , .serial_i ( cdc_req_ai ), .serial_o ( cdc_req ) ); - pulp_sync i_sync_clear ( + (* ASYNC_REG = "TRUE" *) + sync i_sync_clear ( .clk_i ( clk_i ), - .rstn_i ( rst_ni ), + .rst_ni ( rst_ni ), .serial_i ( cdc_clear_ai ), .serial_o ( cdc_clear ) ); - pulp_sync i_sync_rack ( + (* ASYNC_REG = "TRUE" *) + sync i_sync_rack ( .clk_i ( clk_i ), - .rstn_i ( rst_ni ) , + .rst_ni ( rst_ni ) , .serial_i ( cdc_rack_ai ), .serial_o ( cdc_rack ) ); diff --git a/tb/ariane_tb.sv b/tb/ariane_tb.sv index 4676edb8b..65dd9fd0f 100644 --- a/tb/ariane_tb.sv +++ b/tb/ariane_tb.sv @@ -34,9 +34,9 @@ module ariane_tb; logic [31:0] exit_o; ariane_testharness dut ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .exit_o ( exit_o ) + .clk_i, + .rst_ni, + .exit_o ); // Clock process diff --git a/tb/ariane_testharness.sv b/tb/ariane_testharness.sv index df7d9eedb..fc611c4da 100644 --- a/tb/ariane_testharness.sv +++ b/tb/ariane_testharness.sv @@ -71,7 +71,8 @@ module ariane_testharness #( assign ndmreset_n = ~ndmreset ; localparam NB_SLAVE = 4; - localparam NB_MASTER = 3; + localparam NB_MASTER = 4; + localparam AXI_ID_WIDTH_SLAVES = AXI_ID_WIDTH + $clog2(NB_SLAVE); AXI_BUS #( @@ -180,7 +181,7 @@ module ariane_testharness #( .debug_req_o ( debug_req ), .unavailable_i ( '0 ), .axi_master ( slave[3] ), - .axi_slave ( master[2] ), + .axi_slave ( master[3] ), .dmi_rst_ni ( rst_ni ), .dmi_req_valid_i ( debug_req_valid ), .dmi_req_ready_o ( debug_req_ready ), @@ -208,7 +209,7 @@ module ariane_testharness #( ) i_axi2rom ( .clk_i ( clk_i ), .rst_ni ( ndmreset_n ), - .slave ( master[1] ), + .slave ( master[2] ), .req_o ( rom_req ), .we_o ( ), .addr_o ( rom_addr ), @@ -234,7 +235,7 @@ module ariane_testharness #( logic [AXI_DATA_WIDTH-1:0] wdata; logic [AXI_DATA_WIDTH-1:0] rdata; - + axi2mem #( .AXI_ID_WIDTH ( AXI_ID_WIDTH_SLAVES ), .AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ), @@ -278,13 +279,33 @@ module ariane_testharness #( .AXI_USER_WIDTH ( AXI_USER_WIDTH ), .AXI_ID_WIDTH ( AXI_ID_WIDTH ) ) i_axi_xbar ( - .clk ( clk_i ), - .rst_n ( ndmreset_n ), - .test_en_i ( test_en ), - .slave ( slave ), - .master ( master ), - .start_addr_i ( {64'h0, 64'h10000, CACHE_START_ADDR} ), - .end_addr_i ( {64'hFFF, 64'h1FFFF, CACHE_START_ADDR + 2**24} ) + .clk ( clk_i ), + .rst_n ( ndmreset_n ), + .test_en_i ( test_en ), + .slave ( slave ), + .master ( master ), + .start_addr_i ( {64'h0, 64'h10000, 64'h2000000, CACHE_START_ADDR} ), + .end_addr_i ( {64'hFFF, 64'h1FFFF, 64'h2FFFFFF, CACHE_START_ADDR + 2**24} ) + ); + + // --------------- + // CLINT + // --------------- + logic ipi; + logic timer_irq; + + clint #( + .AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ), + .AXI_DATA_WIDTH ( AXI_DATA_WIDTH ), + .AXI_ID_WIDTH ( AXI_ID_WIDTH_SLAVES ), + .NR_CORES ( 1 ) + ) i_clint ( + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .slave ( master[1] ), + .rtc_i ( 1'b0 ), + .timer_irq_o ( timer_irq ), + .ipi_o ( ipi ) ); // --------------- @@ -301,9 +322,9 @@ module ariane_testharness #( .boot_addr_i ( 64'h10000 ), // start fetching from ROM .core_id_i ( '0 ), .cluster_id_i ( '0 ), - .irq_i ( '0 ), - .ipi_i ( '0 ), - .time_irq_i ( '0 ), + .irq_i ( '0 ), // we do not specify other interrupts in this TB + .ipi_i ( ipi ), + .time_irq_i ( timer_irq ), .debug_req_i ( debug_req ), .data_if ( slave[2] ), .bypass_if ( slave[1] ),