diff --git a/Makefrag b/Makefrag index 7bcd3e06..14951cee 100644 --- a/Makefrag +++ b/Makefrag @@ -1,26 +1,61 @@ -# Makefile snippet used by emulator/vlsi/fpga backends -asm_timeout_cycles = 10000000 -bmark_timeout_cycles = 100000000 - MODEL := Top +FPGAMODEL := FPGATop CXX := g++ CXXFLAGS := -O1 SBT := java -Xmx2048M -Xss8M -XX:MaxPermSize=128M -jar sbt-launch.jar +src_path = src/main/scala +chisel_srcs = $(base_dir)/$(src_path)/*.scala $(base_dir)/rocket/$(src_path)/*.scala $(base_dir)/uncore/$(src_path)/*.scala $(base_dir)/hwacha/$(src_path)/*.scala + +disasm := 2> +which_disasm := $(shell which riscv-dis) +ifneq ($(which_disasm),) + disasm := 3>&1 1>&2 2>&3 | $(which_disasm) --extension=hwacha > +endif + +timeout_cycles = 100000000 + +#-------------------------------------------------------------------- +# Verilog Generation +#-------------------------------------------------------------------- + +# VLSI Backend +$(generated_dir)/$(MODEL).v: $(chisel_srcs) + cd $(base_dir) && mkdir -p $(generated_dir) && $(SBT) "project rocketchip" "elaborate $(MODEL) --backend rocketchip.RocketChipBackend --targetDir $(generated_dir) --noInlineMem" + cd $(generated_dir) && \ + if [ -a $(MODEL).conf ]; then \ + sed -i 's*^*$(vlsi_mem_gen) *' $(MODEL).conf && \ + sed -i 's*$$* >> $(MODEL).v*' $(MODEL).conf && \ + sh $(MODEL).conf; \ + fi + +# FPGA Backend +$(generated_dir)/$(FPGAMODEL).v: $(chisel_srcs) + cd $(base_dir) && mkdir -p $(generated_dir) && $(SBT) "project rocketchip" "elaborate $(FPGAMODEL) --backend fpga --targetDir $(generated_dir)" + +$(generated_dir)/$(FPGAMODEL)Mem.v: $(generated_dir)/$(FPGAMODEL).conf $(mem_gen) + $(mem_gen) $(generated_dir)/$(FPGAMODEL).conf > $(generated_dir)/$(FPGAMODEL)Mem.v + +$(generated_dir)/memdessertMemDessert.v: $(base_dir)/$(src_path)/*.scala $(base_dir)/uncore/$(src_path)/*.scala + cd $(base_dir) && mkdir -p $(generated_dir) && $(SBT) "project rocketchip" "elaborate MemDessert --backend v --targetDir $(generated_dir) --moduleNamePrefix memdessert" + +#-------------------------------------------------------------------- +# DRAMSim2 +#-------------------------------------------------------------------- + DRAMSIM_OBJS := $(patsubst %.cpp,%.o,$(wildcard $(base_dir)/dramsim2/*.cpp)) $(DRAMSIM_OBJS): %.o: %.cpp $(CXX) $(CXXFLAGS) -DNO_STORAGE -DNO_OUTPUT -Dmain=nomain -c -o $@ $< $(sim_dir)/libdramsim.a: $(DRAMSIM_OBJS) ar rcs $@ $^ -src_path = src/main/scala - #-------------------------------------------------------------------- -# Tests +# ISA Tests #-------------------------------------------------------------------- -tstdir = $(base_dir)/riscv-tests/isa +tests_isa_dir = $(base_dir)/riscv-tools/riscv-tests/isa + asm_p_tests = \ rv64ui-p-add \ rv64ui-p-addi \ @@ -523,9 +558,11 @@ vecasm_pt_tests = \ rv64uf-pt-vec-fcvt \ rv64uf-pt-vec-fcmp \ -# Globally installed benchmarks +#-------------------------------------------------------------------- +# Benchmark Tests +#-------------------------------------------------------------------- -bmarkdir = $(base_dir)/riscv-tests/benchmarks +tests_bmark_dir = $(base_dir)/riscv-tools/riscv-tests/benchmarks bmarks = \ median.riscv \ multiply.riscv \ @@ -541,85 +578,97 @@ bmarks = \ #mt-vvadd.riscv \ #mt-matmul.riscv \ -vec_bmarkdir = $(base_dir)/../../riscv-app/misc/build -vec_bmarks = \ - ubmark-vvadd \ - ubmark-bin-search \ - ubmark-cmplx-mult \ - ubmark-masked-filter \ +#-------------------------------------------------------------------- +# Multi-threaded Benchmark Tests +#-------------------------------------------------------------------- - -mt_bmarkdir = $(base_dir)/riscv-tests/mt +test_mt_bmark_dir = $(base_dir)/riscv-tools/riscv-tests/mt mt_bmarks = \ -ab_matmul.riscv\ -ab_vvadd.riscv\ -ad_matmul.riscv\ -ad_vvadd.riscv\ -ae_matmul.riscv\ -ae_vvadd.riscv\ -af_matmul.riscv\ -af_vvadd.riscv\ -ag_matmul.riscv\ -ag_vvadd.riscv\ -ai_matmul.riscv\ -ai_vvadd.riscv\ -aj_vvadd.riscv\ -ak_matmul.riscv\ -ak_vvadd.riscv\ -al_matmul.riscv\ -al_vvadd.riscv\ -am_matmul.riscv\ -am_vvadd.riscv\ -an_matmul.riscv\ -ap_matmul.riscv\ -ap_vvadd.riscv\ -aq_matmul.riscv\ -aq_vvadd.riscv\ -ar_matmul.riscv\ -ar_vvadd.riscv\ -as_matmul.riscv\ -as_vvadd.riscv\ -at_matmul.riscv\ -at_vvadd.riscv\ -av_matmul.riscv\ -av_vvadd.riscv\ -ay_matmul.riscv\ -ay_vvadd.riscv\ -az_matmul.riscv\ -az_vvadd.riscv\ -ba_matmul.riscv\ -ba_vvadd.riscv\ -bb_matmul.riscv\ -bb_vvadd.riscv\ -bc_matmul.riscv\ -bc_vvadd.riscv\ -be_matmul.riscv\ -be_vvadd.riscv\ -bf_matmul.riscv\ -bf_vvadd.riscv\ -bh_matmul.riscv\ -bh_vvadd.riscv\ -bj_matmul.riscv\ -bj_vvadd.riscv\ -bk_matmul.riscv\ -bk_vvadd.riscv\ -bm_matmul.riscv\ -bm_vvadd.riscv\ -bn_matmul.riscv\ -bn_vvadd.riscv\ -bo_matmul.riscv\ -bo_vvadd.riscv\ -bp_matmul.riscv\ -bp_vvadd.riscv\ -br_matmul.riscv\ -br_vvadd.riscv\ -bs_matmul.riscv\ -bs_vvadd.riscv\ -bt_matmul.riscv\ -bt_vvadd.riscv\ + ab_matmul.riscv \ + ab_vvadd.riscv \ + ad_matmul.riscv \ + ad_vvadd.riscv \ + ae_matmul.riscv \ + ae_vvadd.riscv \ + af_matmul.riscv \ + af_vvadd.riscv \ + ag_matmul.riscv \ + ag_vvadd.riscv \ + ai_matmul.riscv \ + ai_vvadd.riscv \ + aj_vvadd.riscv \ + ak_matmul.riscv \ + ak_vvadd.riscv \ + al_matmul.riscv \ + al_vvadd.riscv \ + am_matmul.riscv \ + am_vvadd.riscv \ + an_matmul.riscv \ + ap_matmul.riscv \ + ap_vvadd.riscv \ + aq_matmul.riscv \ + aq_vvadd.riscv \ + ar_matmul.riscv \ + ar_vvadd.riscv \ + as_matmul.riscv \ + as_vvadd.riscv \ + at_matmul.riscv \ + at_vvadd.riscv \ + av_matmul.riscv \ + av_vvadd.riscv \ + ay_matmul.riscv \ + ay_vvadd.riscv \ + az_matmul.riscv \ + az_vvadd.riscv \ + ba_matmul.riscv \ + ba_vvadd.riscv \ + bb_matmul.riscv \ + bb_vvadd.riscv \ + bc_matmul.riscv \ + bc_vvadd.riscv \ + be_matmul.riscv \ + be_vvadd.riscv \ + bf_matmul.riscv \ + bf_vvadd.riscv \ + bh_matmul.riscv \ + bh_vvadd.riscv \ + bj_matmul.riscv \ + bj_vvadd.riscv \ + bk_matmul.riscv \ + bk_vvadd.riscv \ + bm_matmul.riscv \ + bm_vvadd.riscv \ + bn_matmul.riscv \ + bn_vvadd.riscv \ + bo_matmul.riscv \ + bo_vvadd.riscv \ + bp_matmul.riscv \ + bp_vvadd.riscv \ + br_matmul.riscv \ + br_vvadd.riscv \ + bs_matmul.riscv \ + bs_vvadd.riscv \ + bt_matmul.riscv \ + bt_vvadd.riscv \ -disasm := 2> -which_disasm := $(shell which riscv-dis) -ifneq ($(which_disasm),) - disasm := 3>&1 1>&2 2>&3 | $(which_disasm) --extension=hwacha > -endif +#-------------------------------------------------------------------- +# Build Tests +#-------------------------------------------------------------------- + +%.hex: + $(MAKE) -C $(dir $@) $(notdir $@) + +%.riscv.hex: % + $(MAKE) -C $(dir $@) $(notdir $@) + +$(addprefix $(output_dir)/, $(addsuffix .hex, $(asm_p_tests) $(asm_v_tests) $(vecasm_p_tests) $(vecasm_v_tests) $(vecasm_pt_tests))): $(output_dir)/%.hex: $(tests_isa_dir)/%.hex + mkdir -p $(output_dir) + ln -fs $< $@ + +$(addprefix $(output_dir)/, $(addsuffix .hex, $(bmarks))): $(output_dir)/%.hex: $(tests_bmark_dir)/%.hex + mkdir -p $(output_dir) + ln -fs $< $@ + +$(addprefix $(output_dir)/, $(addsuffix .hex, $(mt_bmarks))): $(output_dir)/%.hex: $(test_mt_bmark_dir)/%.hex + mkdir -p $(output_dir) + ln -fs $< $@ diff --git a/csrc/emulator.cc b/csrc/emulator.cc index f7d73aaa..167a88ae 100644 --- a/csrc/emulator.cc +++ b/csrc/emulator.cc @@ -1,9 +1,7 @@ #include "htif_emulator.h" -#include "common.h" #include "emulator.h" #include "mm.h" #include "mm_dramsim2.h" -#include "disasm.h" #include "Top.h" // chisel-generated code... #include #include @@ -26,7 +24,6 @@ int main(int argc, char** argv) const char* vcd = NULL; const char* loadmem = NULL; FILE *vcdfile = NULL; - disassembler disasm; bool dramsim2 = false; bool log = false; diff --git a/emulator/Makefile b/emulator/Makefile index fba9d352..cc51d010 100644 --- a/emulator/Makefile +++ b/emulator/Makefile @@ -1,13 +1,14 @@ all: emulator -base_dir = .. +base_dir = $(abspath ..) sim_dir = . +output_dir = $(sim_dir)/output include $(base_dir)/Makefrag CXXFLAGS := $(CXXFLAGS) -std=c++11 -I$(RISCV)/include -CXXSRCS := emulator disasm mm mm_dramsim2 +CXXSRCS := emulator mm mm_dramsim2 CXXFLAGS := $(CXXFLAGS) -I$(base_dir)/csrc -I$(base_dir)/dramsim2 LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L. -ldramsim -lfesvr -lpthread @@ -18,11 +19,11 @@ DEBUG_OBJS := $(addsuffix -debug.o,$(CXXSRCS) $(MODEL)) CHISEL_ARGS := $(MODEL) --noIoDebug --backend c --targetDir emulator/generated-src CHISEL_ARGS_DEBUG := $(CHISEL_ARGS)-debug --debug --vcd --ioDebug -generated-src/$(MODEL).h: $(base_dir)/rocket/$(src_path)/*.scala $(base_dir)/hwacha/$(src_path)/*.scala $(base_dir)/uncore/$(src_path)/*.scala $(base_dir)/$(src_path)/*.scala - cd $(base_dir) && $(SBT) "project referencechip" "elaborate $(CHISEL_ARGS)" +generated-src/$(MODEL).h: $(chisel_srcs) + cd $(base_dir) && $(SBT) "project rocketchip" "elaborate $(CHISEL_ARGS)" -generated-src-debug/$(MODEL).h: $(base_dir)/rocket/$(src_path)/*.scala $(base_dir)/hwacha/$(src_path)/*.scala $(base_dir)/uncore/$(src_path)/*.scala $(base_dir)/$(src_path)/*.scala - cd $(base_dir) && $(SBT) "project referencechip" "elaborate $(CHISEL_ARGS_DEBUG)" +generated-src-debug/$(MODEL).h: $(chisel_srcs) + cd $(base_dir) && $(SBT) "project rocketchip" "elaborate $(CHISEL_ARGS_DEBUG)" $(MODEL).o: %.o: generated-src/%.h $(MAKE) -j $(patsubst %.cpp,%.o,$(shell ls generated-src/$(MODEL)-*.cpp)) @@ -51,7 +52,7 @@ emulator-debug: $(DEBUG_OBJS) libdramsim.a $(CXX) $(CXXFLAGS) -o $@ $(DEBUG_OBJS) $(LDFLAGS) clean: - rm -rf *.o *.a emulator emulator-debug generated-src generated-src-debug DVEfiles output + rm -rf *.o *.a emulator emulator-debug generated-src generated-src-debug DVEfiles $(output_dir) test: cd $(base_dir) && $(SBT) "~make $(CURDIR) run-fast $(CHISEL_ARGS)" @@ -60,60 +61,42 @@ test: # Run assembly tests and benchmarks #-------------------------------------------------------------------- -%.hex: - $(MAKE) -C $(dir $@) $(notdir $@) +$(output_dir)/%.run: $(output_dir)/%.hex emulator + ./emulator +dramsim +max-cycles=$(timeout_cycles) +loadmem=$< none 2> /dev/null 2> $@ && [ $$PIPESTATUS -eq 0 ] -%.riscv.hex: % - $(MAKE) -C $(dir $@) $(notdir $@) +$(output_dir)/%.out: $(output_dir)/%.hex emulator + ./emulator +dramsim +max-cycles=$(timeout_cycles) +verbose +loadmem=$< none $(disasm) $@ && [ $$PIPESTATUS -eq 0 ] -$(addprefix output/, $(addsuffix .hex, $(asm_p_tests) $(asm_v_tests) $(vecasm_p_tests) $(vecasm_v_tests) $(vecasm_pt_tests))): output/%.hex: $(tstdir)/%.hex - mkdir -p output - ln -fs ../$< $@ +$(output_dir)/%.vcd: $(output_dir)/%.hex emulator-debug + ./emulator-debug +dramsim +max-cycles=$(timeout_cycles) +verbose -v$@ +loadmem=$< none $(disasm) $(patsubst %.vcd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] -$(addprefix output/, $(addsuffix .hex, $(bmarks))): output/%.hex: $(bmarkdir)/%.hex - mkdir -p output - ln -fs ../$< $@ - -$(addprefix output/, $(addsuffix .hex, $(mt_bmarks))): output/%.hex: $(mt_bmarkdir)/%.hex - mkdir -p output - ln -fs ../$< $@ - -output: - mkdir -p $@ - -output/%.run: output/%.hex emulator - ./emulator +dramsim +max-cycles=$(bmark_timeout_cycles) +loadmem=$< none 2> /dev/null 2> $@ && [ $$PIPESTATUS -eq 0 ] - -output/%.out: output/%.hex emulator - ./emulator +dramsim +max-cycles=$(bmark_timeout_cycles) +verbose +coremap-random +loadmem=$< none $(disasm) $@ && [ $$PIPESTATUS -eq 0 ] - -output/%.vpd: output/%.hex emulator-debug +$(output_dir)/%.vpd: $(output_dir)/%.hex emulator-debug rm -rf $@.vcd && mkfifo $@.vcd vcd2vpd $@.vcd $@ > /dev/null & - ./emulator-debug +dramsim +max-cycles=$(bmark_timeout_cycles) +verbose -v$@.vcd +coremap-random +loadmem=$< none $(disasm) $(patsubst %.vpd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] + ./emulator-debug +dramsim +max-cycles=$(timeout_cycles) +verbose -v$@.vcd +loadmem=$< none $(disasm) $(patsubst %.vpd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] -run-asm-tests: $(addprefix output/, $(addsuffix .out, $(asm_p_tests) $(asm_v_tests))) +run-asm-tests: $(addprefix $(output_dir)/, $(addsuffix .out, $(asm_p_tests) $(asm_v_tests))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $^; echo; -run-vecasm-tests: $(addprefix output/, $(addsuffix .out, $(vecasm_p_tests) $(vecasm_v_tests))) +run-vecasm-tests: $(addprefix $(output_dir)/, $(addsuffix .out, $(vecasm_p_tests) $(vecasm_v_tests))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $^; echo; -run-vecasm-timer-tests: $(addprefix output/, $(addsuffix .out, $(vecasm_pt_tests))) +run-vecasm-timer-tests: $(addprefix $(output_dir)/, $(addsuffix .out, $(vecasm_pt_tests))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $^; echo; -run-bmarks-test: $(addprefix output/, $(addsuffix .out, $(bmarks))) +run-bmarks-test: $(addprefix $(output_dir)/, $(addsuffix .out, $(bmarks))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $^; echo; -run-mt-tests: $(addprefix output/, $(addsuffix .out, $(mt_bmarks))) +run-mt-tests: $(addprefix $(output_dir)/, $(addsuffix .out, $(mt_bmarks))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $^; echo; -run-asm-tests-debug: $(addprefix output/, $(addsuffix .vpd, $(asm_p_tests) $(asm_v_tests))) +run-asm-tests-debug: $(addprefix $(output_dir)/, $(addsuffix .vpd, $(asm_p_tests) $(asm_v_tests))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $(patsubst %.vpd,%.out,$^); echo; -run-vecasm-tests-debug: $(addprefix output/, $(addsuffix .vpd, $(vecasm_p_tests) $(vecasm_v_tests))) +run-vecasm-tests-debug: $(addprefix $(output_dir)/, $(addsuffix .vpd, $(vecasm_p_tests) $(vecasm_v_tests))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $(patsubst %.vpd,%.out,$^); echo; -run-vecasm-timer-tests-debug: $(addprefix output/, $(addsuffix .vpd, $(vecasm_pt_tests))) +run-vecasm-timer-tests-debug: $(addprefix $(output_dir)/, $(addsuffix .vpd, $(vecasm_pt_tests))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $(patsubst %.vpd,%.out,$^); echo; -run-bmarks-test-debug: $(addprefix output/, $(addsuffix .vpd, $(bmarks))) +run-bmarks-test-debug: $(addprefix $(output_dir)/, $(addsuffix .vpd, $(bmarks))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $(patsubst %.vpd,%.out,$^); echo; -run-mt-tests-debug: $(addprefix output/, $(addsuffix .vpd, $(mt_bmarks))) +run-mt-tests-debug: $(addprefix $(output_dir)/, $(addsuffix .vpd, $(mt_bmarks))) @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' $(patsubst %.vpd,%.out,$^); echo; run: run-asm-tests run-bmarks-test #run-vecasm-tests run-vecasm-timer-tests run-debug: run-asm-tests-debug run-bmarks-test-debug #run-vecasm-tests-debug run-vecasm-timer-tests-debug -run-fast: $(addprefix output/, $(addsuffix .run, $(asm_p_tests) $(asm_v_tests) $(bmarks))) +run-fast: $(addprefix $(output_dir)/, $(addsuffix .run, $(asm_p_tests) $(asm_v_tests) $(bmarks))) diff --git a/fsim/.gitignore b/fsim/.gitignore new file mode 100644 index 00000000..571b6166 --- /dev/null +++ b/fsim/.gitignore @@ -0,0 +1,18 @@ +simv* +csrc +*.vpd +*.key +DVE* +.vcs* +timestamp +*.out +*.h +*.log +*.cmd +*.daidir +*.ucli +*.a +*.vcd +dramsim2_ini +generated-src +output diff --git a/fsim/Makefile b/fsim/Makefile new file mode 100644 index 00000000..f4297646 --- /dev/null +++ b/fsim/Makefile @@ -0,0 +1,25 @@ +#======================================================================= +# Makefile for Verilog simulation w/ VCS +#----------------------------------------------------------------------- +# Yunsup Lee (yunsup@cs.berkeley.edu) +# +# This makefile will build a rtl simulator and run various tests to +# verify proper functionality. +# + +default: all + +base_dir = $(abspath ..) +generated_dir = $(abspath ./generated-src) +mem_gen = $(base_dir)/fsim/fpga_mem_gen +sim_dir = . +output_dir = $(sim_dir)/output + +include $(base_dir)/Makefrag +include $(sim_dir)/Makefrag +include $(base_dir)/vsim/Makefrag-sim + +all: $(simv) + +clean: + rm -rf $(junk) simv* csrc *.key DVE* *.h *.a *.daidir diff --git a/fsim/Makefrag b/fsim/Makefrag new file mode 100644 index 00000000..325bdd21 --- /dev/null +++ b/fsim/Makefrag @@ -0,0 +1,68 @@ + +#-------------------------------------------------------------------- +# Sources +#-------------------------------------------------------------------- + +# Verilog sources + +sim_vsrcs = \ + $(generated_dir)/$(FPGAMODEL).v \ + $(generated_dir)/$(FPGAMODEL)Mem.v \ + $(generated_dir)/memdessertMemDessert.v \ + $(base_dir)/vsrc/const.vh \ + $(base_dir)/vsrc/rocketTestHarness.v \ + $(base_dir)/vsrc/bram_mem.v \ + +# C sources + +sim_csrcs = \ + $(base_dir)/csrc/vcs_main.cc \ + $(base_dir)/csrc/mm.cc \ + $(base_dir)/csrc/mm_dramsim2.cc \ + +#-------------------------------------------------------------------- +# Build rules +#-------------------------------------------------------------------- + +VCS = vcs -full64 + +VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -timescale=1ns/10ps -quiet \ + +rad +v2k +vcs+lic+wait \ + +vc+list -CC "-I$(VCS_HOME)/include" \ + -CC "-I$(RISCV)/include" \ + -CC "-I$(realpath $(base_dir))/dramsim2" \ + -CC "-std=c++11" \ + -CC "-Wl,-rpath,$(RISCV)/lib" \ + -e vcs_main \ + $(RISCV)/lib/libfesvr.so \ + $(sim_dir)/libdramsim.a \ + +define+FPGA \ + +define+TOP=$(FPGAMODEL) \ + +define+CLOCK_PERIOD=0.5 $(sim_vsrcs) $(sim_csrcs) \ + +define+PRINTF_COND=rocketTestHarness.verbose \ + +libext+.v \ + +#-------------------------------------------------------------------- +# Build the simulator +#-------------------------------------------------------------------- + +simv = $(sim_dir)/simv +$(simv) : $(sim_vsrcs) $(sim_csrcs) $(sim_dir)/libdramsim.a + cd $(sim_dir) && \ + $(VCS) $(VCS_OPTS) -o $(simv) \ + +simv_debug = $(sim_dir)/simv-debug +$(simv_debug) : $(sim_vsrcs) $(sim_csrcs) $(sim_dir)/libdramsim.a + cd $(sim_dir) && \ + $(VCS) $(VCS_OPTS) -o $(simv_debug) \ + +define+DEBUG -debug_pp \ + +# +define+MEM_BACKUP_EN \ + +#-------------------------------------------------------------------- +# Run +#-------------------------------------------------------------------- + +seed = $(shell date +%s) +exec_simv = $(simv) -q +ntb_random_seed_automatic +exec_simv_debug = $(simv_debug) -q +ntb_random_seed_automatic diff --git a/fsim/fpga_mem_gen b/fsim/fpga_mem_gen new file mode 100755 index 00000000..80d8b6aa --- /dev/null +++ b/fsim/fpga_mem_gen @@ -0,0 +1,185 @@ +#!/usr/bin/env python +import sys +import math + +# This is based off of reference-chip/vlsi/src/vlsi_mem_gen + +use_latches = 1 + + +module_template = '''module %s( + %s +); +%s +%s +always @(posedge CLK) begin + %s +end +%s + +endmodule + +''' + + +mask_assert_template = ''' +`ifndef SYNTHESIS +integer i; +integer j; +always @(posedge CLK) begin%s +end +`endif +''' + + +assert_template = ''' + for (i=0; i<%d; i=i+%d) begin + for (j=1; j<%d; j=j+1) begin + if (%sM[i] != %sM[i+j]) begin + $fwrite(32'h80000002, "ASSERTION FAILED: write mask granularity\\n"); + $finish; + end + end + end''' + + +def parse_line(line): + name = '' + width = 0 + depth = 0 + ports = '' + mask_gran = 1 + tokens = line.split() + i = 0 + for i in xrange(0,len(tokens),2): + s = tokens[i] + if s == 'name': + name = tokens[i+1] + elif s == 'width': + width = int(tokens[i+1]) + elif s == 'depth': + depth = int(tokens[i+1]) + elif s == 'ports': + ports = tokens[i+1].split(',') + elif s == 'mask_gran': + mask_gran = int(tokens[i+1]) + else: + sys.exit('%s: unknown argument %s' % (sys.argv[0], a)) + return (name, width, depth, ports, mask_gran) + + + +def gen_range(mask_index, mask_gran, max_width): + return '%d:%d' % (min(mask_gran*(mask_index+1),max_width)-1, + min(mask_gran*(mask_index),max_width)) + + + +def gen_mem(name, width, depth, ports, mask_gran): + addr_width = max(math.ceil(math.log(depth)/math.log(2)),1) + mask_width = int(math.ceil(float(width) / mask_gran)) + port_spec = ['input CLK', 'input RST', 'input init'] + readports = [] + writeports = [] + latchports = [] + rwports = [] + decl = [] + combinational = [] + sequential = [] + maskedports = {} + mask_asserts = '' + for pid in range(len(ports)): + ptype = ports[pid] + if ptype[0:1] == 'm': + ptype = ptype[1:] + maskedports[pid] = pid + + if ptype == 'read': + port_spec += ['input [%d:0] R%dA' % (addr_width-1, pid)] + port_spec += ['input R%dE' % pid] + port_spec += ['output [%d:0] R%dO' % (width-1, pid)] + readports += [pid] + elif ptype == 'write': + port_spec += ['input [%d:0] W%dA' % (addr_width-1, pid)] + port_spec += ['input W%dE' % pid] + port_spec += ['input [%d:0] W%dI' % (width-1, pid)] + if pid in maskedports: + port_spec += ['input [%d:0] W%dM' % (width-1, pid)] + if not use_latches or pid in maskedports: + writeports += [pid] + else: + latchports += [pid] + elif ptype == 'rw': + port_spec += ['input [%d:0] RW%dA' % (addr_width-1, pid)] + port_spec += ['input RW%dE' % pid] + port_spec += ['input RW%dW' % pid] + if pid in maskedports: + port_spec += ['input [%d:0] RW%dM' % (width-1, pid)] + port_spec += ['input [%d:0] RW%dI' % (width-1, pid)] + port_spec += ['output [%d:0] RW%dO' % (width-1, pid)] + rwports += [pid] + else: + sys.exit('%s: unknown port type %s' % (sys.argv[0], ptype)) + + decl += ['reg [%d:0] ram [%d:0];' % (width-1, depth-1)] + + for pid in readports: + decl += ['reg [%d:0] reg_R%dA;' % (addr_width-1, pid)] + sequential += ['if (R%dE) reg_R%dA <= R%dA;' % (pid, pid, pid)] + combinational += ['assign R%dO = ram[reg_R%dA];' % (pid, pid)] + + for pid in rwports: + decl += ['reg [%d:0] reg_RW%dA;' % (addr_width-1, pid)] + sequential += ['if (RW%dE && !RW%dW) reg_RW%dA <= RW%dA;' % (pid, pid, pid, pid)] + combinational += ['assign RW%dO = ram[reg_RW%dA];' % (pid, pid)] + + for pid in latchports: + decl += ['reg [%d:0] latch_W%dA;' % (addr_width-1, pid)] + decl += ['reg [%d:0] latch_W%dI;' % (width-1, pid)] + decl += ['reg latch_W%dE;' % (pid)] + combinational += ['always @(*) begin'] + combinational += [' if (!CLK && W%dE) latch_W%dA <= W%dA;' % (pid, pid, pid)] + combinational += [' if (!CLK && W%dE) latch_W%dI <= W%dI;' % (pid, pid, pid)] + combinational += [' if (!CLK) latch_W%dE <= W%dE;' % (pid, pid)] + combinational += ['end'] + combinational += ['always @(*)'] + combinational += [' if (CLK && latch_W%dE)' % (pid)] + combinational += [' ram[latch_W%dA] <= latch_W%dI;' % (pid, pid)] + + for pid in writeports: + if pid not in maskedports: + sequential += ['if (W%dE) ram[W%dA] <= W%dI;' % (pid, pid, pid)] + else: + for mask_index in range(mask_width): + rs = gen_range(mask_index, mask_gran, width) + sequential += ['if (W%dE && W%dM[%d]) ram[W%dA][%s] <= W%dI[%s];' % + (pid, pid, mask_index*mask_gran, pid, rs, pid, rs)] + mask_asserts += assert_template % (mask_width, mask_gran, mask_gran, 'W'+str(pid), 'W'+str(pid)) + for pid in rwports: + if pid not in maskedports: + sequential += ['if (RW%dE && RW%dW) ram[RW%dA] <= RW%dI;' % (pid, pid, pid, pid)] + else: + for mask_index in range(mask_width): + rs = gen_range(mask_index, mask_gran, width) + sequential += ['if (RW%dE && RW%dW && RW%dM[%d]) ram[RW%dA][%s] <= RW%dI[%s];' % + (pid, pid, pid, mask_index*mask_gran, pid, rs, pid, rs)] + mask_asserts += assert_template % (mask_width, mask_gran, mask_gran, 'RW'+str(pid), 'RW'+str(pid)) + check_masks = '' if len(maskedports) == 0 else mask_assert_template % mask_asserts + return module_template % (name, + ',\n '.join(port_spec), + check_masks, + '\n '.join(decl), + '\n '.join(sequential), + '\n '.join(combinational)) + + + +def main(): + if len(sys.argv) < 2: + sys.exit('Please give a .conf file as input') + for line in open(sys.argv[1]): + print gen_mem(*parse_line(line)) + + +if __name__ == '__main__': + main() diff --git a/hardfloat b/hardfloat index 4a938b1a..1c8a6e68 160000 --- a/hardfloat +++ b/hardfloat @@ -1 +1 @@ -Subproject commit 4a938b1aae6df5609400235448583c5c34b47da4 +Subproject commit 1c8a6e6815eadebc1592c65e10a2ba87ecabb3c6 diff --git a/project/build.scala b/project/build.scala index 877c66a4..250b7f3f 100644 --- a/project/build.scala +++ b/project/build.scala @@ -31,8 +31,7 @@ object BuildSettings extends Build { lazy val uncore = Project("uncore", file("uncore"), settings = buildSettings) dependsOn(hardfloat) lazy val rocket = Project("rocket", file("rocket"), settings = buildSettings) dependsOn(uncore) lazy val hwacha = Project("hwacha", file("hwacha"), settings = buildSettings) dependsOn(uncore, rocket) - lazy val rekall = Project("rekall", file("rekall"), settings = buildSettings) dependsOn(chisel) - lazy val referencechip = Project("referencechip", file("."), settings = buildSettings ++ chipSettings) dependsOn(rocket, hwacha, rekall) + lazy val rocketchip = Project("rocketchip", file("."), settings = buildSettings ++ chipSettings) dependsOn(rocket, hwacha) val elaborateTask = InputKey[Unit]("elaborate", "convert chisel components into backend source code") val makeTask = InputKey[Unit]("make", "trigger backend-specific makefile command") diff --git a/riscv-tests b/riscv-tests deleted file mode 160000 index 83ed3f51..00000000 --- a/riscv-tests +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83ed3f519de9929b6551b98677047228a8ab4d0c diff --git a/riscv-tools b/riscv-tools index 1f62b9b6..94d91962 160000 --- a/riscv-tools +++ b/riscv-tools @@ -1 +1 @@ -Subproject commit 1f62b9b6b6503a6a179f5d7b12d5157437405c83 +Subproject commit 94d919625a75b1d3087f16c1b346cee3c2fb45a8 diff --git a/src/main/scala/Backends.scala b/src/main/scala/Backends.scala index e1157837..50315921 100644 --- a/src/main/scala/Backends.scala +++ b/src/main/scala/Backends.scala @@ -1,14 +1,14 @@ -package referencechip +package rocketchip import Chisel._ -import ReferenceChipBackend._ +import RocketChipBackend._ import scala.collection.mutable.HashMap -object ReferenceChipBackend { +object RocketChipBackend { val initMap = new HashMap[Module, Bool]() } -class ReferenceChipBackend extends VerilogBackend +class RocketChipBackend extends VerilogBackend { initMap.clear() override def emitPortDef(m: MemAccess, idx: Int) = { @@ -65,5 +65,5 @@ class ReferenceChipBackend extends VerilogBackend transforms += ((c: Module) => collectNodesIntoComp(initializeDFS)) } -class Fame1ReferenceChipBackend extends ReferenceChipBackend with Fame1Transform +class Fame1RocketChipBackend extends RocketChipBackend with Fame1Transform diff --git a/src/main/scala/RocketChip.scala b/src/main/scala/RocketChip.scala index c22a8eb7..15ca15fb 100644 --- a/src/main/scala/RocketChip.scala +++ b/src/main/scala/RocketChip.scala @@ -1,4 +1,4 @@ -package referencechip +package rocketchip import Chisel._ import uncore._ @@ -68,7 +68,7 @@ class OuterMemorySystem(htif_width: Int)(implicit conf: UncoreConfiguration) ext (llc, mes) } - val net = Module(new ReferenceChipCrossbarNetwork) + val net = Module(new RocketChipCrossbarNetwork) net.io.clients zip (io.tiles :+ io.htif) map { case (net, end) => net <> end } net.io.masters zip (masterEndpoints.map(_.io.inner)) map { case (net, end) => net <> end } masterEndpoints.map{ _.io.incoherent zip io.incoherent map { case (m, c) => m := c } } @@ -233,7 +233,7 @@ class Top extends Module { val hc = hwacha.HwachaConfiguration(as, vic, dc, 8, 256, ndtlb = 8, nptlb = 2) val fpu = if (HAS_FPU) Some(FPUConfig(sfmaLatency = 2, dfmaLatency = 3)) else None val rc = RocketConfiguration(tl, as, ic, dc, fpu - // rocc = (c: RocketConfiguration) => (new hwacha.Hwacha(hc, c)) + ,rocc = (c: RocketConfiguration) => (new hwacha.Hwacha(hc, c)) ) val io = new VLSITopIO(HTIF_WIDTH) diff --git a/src/main/scala/fpga.scala b/src/main/scala/fpga.scala index d473f61f..0e4d76da 100644 --- a/src/main/scala/fpga.scala +++ b/src/main/scala/fpga.scala @@ -1,10 +1,8 @@ -package referencechip +package rocketchip import Chisel._ import uncore._ import rocket._ -import DRAMModel._ -import DRAMModel.MemModelConstants._ import DesignSpaceConstants._ @@ -26,7 +24,7 @@ class FPGAOuterMemorySystem(htif_width: Int)(implicit conf: FPGAUncoreConfigurat refill_cycles=refill_cycles, tagLeaf=llc_tag_leaf, dataLeaf=llc_data_leaf)) val masterEndpoints = (0 until ln.nMasters).map(i => Module(new L2CoherenceAgent(i))) - val net = Module(new ReferenceChipCrossbarNetwork) + val net = Module(new RocketChipCrossbarNetwork) net.io.clients zip (io.tiles :+ io.htif) map { case (net, end) => net <> end } net.io.masters zip (masterEndpoints.map(_.io.inner)) map { case (net, end) => net <> end } masterEndpoints.map{ _.io.incoherent zip io.incoherent map { case (m, c) => m := c } } diff --git a/src/main/scala/network.scala b/src/main/scala/network.scala index 5deda918..45c795cd 100644 --- a/src/main/scala/network.scala +++ b/src/main/scala/network.scala @@ -1,4 +1,4 @@ -package referencechip +package rocketchip import Chisel._ import uncore._ @@ -22,7 +22,7 @@ object TileLinkHeaderOverwriter { } } -class ReferenceChipCrossbarNetwork(implicit conf: TileLinkConfiguration) +class RocketChipCrossbarNetwork(implicit conf: TileLinkConfiguration) extends LogicalNetwork[TileLinkIO]()(conf.ln) { implicit val (ln, co) = (conf.ln, conf.co) val io = new Bundle { diff --git a/vsim/.gitignore b/vsim/.gitignore new file mode 100644 index 00000000..571b6166 --- /dev/null +++ b/vsim/.gitignore @@ -0,0 +1,18 @@ +simv* +csrc +*.vpd +*.key +DVE* +.vcs* +timestamp +*.out +*.h +*.log +*.cmd +*.daidir +*.ucli +*.a +*.vcd +dramsim2_ini +generated-src +output diff --git a/vsim/Makefile b/vsim/Makefile new file mode 100644 index 00000000..abc3ac82 --- /dev/null +++ b/vsim/Makefile @@ -0,0 +1,25 @@ +#======================================================================= +# Makefile for Verilog simulation w/ VCS +#----------------------------------------------------------------------- +# Yunsup Lee (yunsup@cs.berkeley.edu) +# +# This makefile will build a rtl simulator and run various tests to +# verify proper functionality. +# + +default: all + +base_dir = $(abspath ..) +generated_dir = $(abspath ./generated-src) +vlsi_mem_gen = $(base_dir)/vsim/vlsi_mem_gen +sim_dir = . +output_dir = $(sim_dir)/output + +include $(base_dir)/Makefrag +include $(sim_dir)/Makefrag +include $(base_dir)/vsim/Makefrag-sim + +all: $(simv) + +clean: + rm -rf $(junk) simv* csrc *.key DVE* *.h *.a *.daidir diff --git a/vsim/Makefrag b/vsim/Makefrag new file mode 100644 index 00000000..fa27754f --- /dev/null +++ b/vsim/Makefrag @@ -0,0 +1,66 @@ + +#-------------------------------------------------------------------- +# Sources +#-------------------------------------------------------------------- + +# Verilog sources + +sim_vsrcs = \ + $(generated_dir)/$(MODEL).v \ + $(generated_dir)/memdessertMemDessert.v \ + $(base_dir)/vsrc/const.vh \ + $(base_dir)/vsrc/rocketTestHarness.v \ + $(base_dir)/vsrc/bram_mem.v \ + +# C sources + +sim_csrcs = \ + $(base_dir)/csrc/vcs_main.cc \ + $(base_dir)/csrc/mm.cc \ + $(base_dir)/csrc/mm_dramsim2.cc \ + +#-------------------------------------------------------------------- +# Build rules +#-------------------------------------------------------------------- + +VCS = vcs -full64 + +VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -timescale=1ns/10ps -quiet \ + +rad +v2k +vcs+lic+wait \ + +vc+list -CC "-I$(VCS_HOME)/include" \ + -CC "-I$(RISCV)/include" \ + -CC "-I$(realpath $(base_dir))/dramsim2" \ + -CC "-std=c++11" \ + -CC "-Wl,-rpath,$(RISCV)/lib" \ + -e vcs_main \ + $(RISCV)/lib/libfesvr.so \ + $(sim_dir)/libdramsim.a \ + +define+TOP=$(MODEL) \ + +define+CLOCK_PERIOD=0.5 $(sim_vsrcs) $(sim_csrcs) \ + +define+PRINTF_COND=rocketTestHarness.verbose \ + +libext+.v \ + +#-------------------------------------------------------------------- +# Build the simulator +#-------------------------------------------------------------------- + +simv = $(sim_dir)/simv +$(simv) : $(sim_vsrcs) $(sim_csrcs) $(sim_dir)/libdramsim.a + cd $(sim_dir) && \ + $(VCS) $(VCS_OPTS) -o $(simv) \ + +simv_debug = $(sim_dir)/simv-debug +$(simv_debug) : $(sim_vsrcs) $(sim_csrcs) $(sim_dir)/libdramsim.a + cd $(sim_dir) && \ + $(VCS) $(VCS_OPTS) -o $(simv_debug) \ + +define+DEBUG -debug_pp \ + +# +define+MEM_BACKUP_EN \ + +#-------------------------------------------------------------------- +# Run +#-------------------------------------------------------------------- + +seed = $(shell date +%s) +exec_simv = $(simv) -q +ntb_random_seed_automatic +exec_simv_debug = $(simv_debug) -q +ntb_random_seed_automatic diff --git a/vsim/Makefrag-sim b/vsim/Makefrag-sim new file mode 100644 index 00000000..c0405462 --- /dev/null +++ b/vsim/Makefrag-sim @@ -0,0 +1,91 @@ +#-------------------------------------------------------------------- +# Run +#-------------------------------------------------------------------- + +asm_tests_out = $(foreach test, $(asm_p_tests) $(asm_v_tests), $(output_dir)/$(test).out) +vecasm_tests_out = $(foreach test, $(vecasm_p_tests) $(vecasm_v_tests), $(output_dir)/$(test).out) +vecasm_t_tests_out = $(foreach test, $(vecasm_pt_tests), $(output_dir)/$(test).out) +bmarks_out = $(foreach test, $(bmarks), $(output_dir)/$(test).out) +mt_bmarks_out = $(foreach test, $(mt_bmarks), $(output_dir)/$(test).out) + +asm_tests_vcd = $(foreach test, $(asm_p_tests) $(asm_v_tests), $(output_dir)/$(test).vcd) +vecasm_tests_vcd = $(foreach test, $(vecasm_p_tests) $(vecasm_v_tests), $(output_dir)/$(test).vcd) +vecasm_t_tests_vcd = $(foreach test, $(vecasm_pt_tests), $(output_dir)/$(test).vcd) +bmarks_vcd = $(foreach test, $(bmarks), $(output_dir)/$(test).vcd) +mt_bmarks_vcd = $(foreach test, $(mt_bmarks), $(output_dir)/$(test).vcd) + +asm_tests_vpd = $(foreach test, $(asm_p_tests) $(asm_v_tests), $(output_dir)/$(test).vpd) +vecasm_tests_vpd = $(foreach test, $(vecasm_p_tests) $(vecasm_v_tests), $(output_dir)/$(test).vpd) +vecasm_t_tests_vpd = $(foreach test, $(vecasm_pt_tests), $(output_dir)/$(test).vpd) +bmarks_vpd = $(foreach test, $(bmarks), $(output_dir)/$(test).vpd) +mt_bmarks_vpd = $(foreach test, $(mt_bmarks), $(output_dir)/$(test).vpd) + +asm_tests_saif = $(foreach test, $(asm_p_tests) $(asm_v_tests), $(output_dir)/$(test).saif) +vecasm_tests_saif = $(foreach test, $(vecasm_p_tests) $(vecasm_v_tests), $(output_dir)/$(test).saif) +vecasm_t_tests_saif = $(foreach test, $(vecasm_pt_tests), $(output_dir)/$(test).saif) +bmarks_saif = $(foreach test, $(bmarks), $(output_dir)/$(test).saif) +mt_bmarks_saif = $(foreach test, $(mt_bmarks), $(output_dir)/$(test).saif) + +$(sim_dir)/dramsim2_ini: + ln -s $(base_dir)/emulator/dramsim2_ini $(sim_dir)/dramsim2_ini + +$(output_dir)/%.out: $(output_dir)/%.hex $(sim_dir)/dramsim2_ini $(simv) + cd $(sim_dir) && $(exec_simv) +dramsim +verbose +max-cycles=$(timeout_cycles) +loadmem=$< $(disasm) $@ && [ $$PIPESTATUS -eq 0 ] + +$(output_dir)/%.vcd: $(output_dir)/%.hex $(sim_dir)/dramsim2_ini $(simv_debug) + cd $(sim_dir) && $(exec_simv_debug) +dramsim +verbose +vcdfile=$@ +max-cycles=$(timeout_cycles) +loadmem=$< $(disasm) $(patsubst %.vcd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] + +$(output_dir)/%.vpd: $(output_dir)/%.hex $(sim_dir)/dramsim2_ini $(simv_debug) + cd $(sim_dir) && $(exec_simv_debug) +dramsim +verbose +vcdplusfile=$@ +max-cycles=$(timeout_cycles) +loadmem=$< $(disasm) $(patsubst %.vpd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] + +$(output_dir)/%.saif: $(output_dir)/%.hex $(sim_dir)/dramsim2_ini $(simv_debug) + cd $(sim_dir) && rm -f $(output_dir)/pipe-$*.vcd && vcd2saif -input $(output_dir)/pipe-$*.vcd -pipe "$(exec_simv_debug) +dramsim +verbose +vcdfile=$(output_dir)/pipe-$*.vcd +max-cycles=$(bmark_timeout_cycles) +loadmem=$<" -output $@ > $(patsubst %.saif,%.out,$@) 2>&1 + +run-asm-tests: $(asm_tests_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(asm_tests_out); echo; + +run-vecasm-tests: $(vecasm_tests_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(vecasm_tests_out); echo; + +run-vecasm-timer-tests: $(vecasm_t_tests_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(vecasm_t_tests_out); echo; + +run-bmarks-test: $(bmarks_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(bmarks_out); echo; + +run-mt-tests: $(mt_bmarks_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(mt_bmarks_out); echo; + +run-asm-tests-debug: $(asm_tests_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(asm_tests_out); echo; + +run-vecasm-tests-debug: $(vecasm_tests_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(vecasm_tests_out); echo; + +run-vecasm-timer-tests-debug: $(vecasm_t_tests_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(vecasm_t_tests_out); echo; + +run-bmarks-test-debug: $(bmarks_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(bmarks_out); echo; + +run-mt-tests-debug: $(mt_bmarks_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(mt_bmarks_out); echo; + +run: run-asm-tests run-vecasm-tests run-vecasm-timer-tests run-bmarks-test +run-debug: run-asm-tests-debug run-vecasm-tests-debug run-vecasm-timer-tests-debug run-bmarks-test-debug + +.PHONY: run-asm-tests run-vecasm-tests run-vecasm-timer-tests run-bmarks-test run-mt-tests +.PHONY: run-asm-tests-debug run-vecasm-tests-debug run-vecasm-timer-tests-debug run-bmarks-test-debug run-mt-tests-debug +.PHONY: run run-debug + +junk += $(output_dir) diff --git a/vsim/vlsi_mem_gen b/vsim/vlsi_mem_gen new file mode 100755 index 00000000..0366594e --- /dev/null +++ b/vsim/vlsi_mem_gen @@ -0,0 +1,136 @@ +#!/usr/bin/env python +import sys +import math + +use_latches = 0 + +def gen_mem(name, width, depth, ports): + addr_width = max(math.ceil(math.log(depth)/math.log(2)),1) + port_spec = ['input CLK', 'input RST', 'input init'] + readports = [] + writeports = [] + latchports = [] + rwports = [] + decl = [] + combinational = [] + sequential = [] + maskedports = {} + for pid in range(len(ports)): + ptype = ports[pid] + if ptype[0:1] == 'm': + ptype = ptype[1:] + maskedports[pid] = pid + + if ptype == 'read': + port_spec.append('input [%d:0] R%dA' % (addr_width-1, pid)) + port_spec.append('input R%dE' % pid) + port_spec.append('output [%d:0] R%dO' % (width-1, pid)) + readports.append(pid) + elif ptype == 'write': + port_spec.append('input [%d:0] W%dA' % (addr_width-1, pid)) + port_spec.append('input W%dE' % pid) + port_spec.append('input [%d:0] W%dI' % (width-1, pid)) + if pid in maskedports: + port_spec.append('input [%d:0] W%dM' % (width-1, pid)) + if not use_latches or pid in maskedports: + writeports.append(pid) + else: + latchports.append(pid) + elif ptype == 'rw': + port_spec.append('input [%d:0] RW%dA' % (addr_width-1, pid)) + port_spec.append('input RW%dE' % pid) + port_spec.append('input RW%dW' % pid) + if pid in maskedports: + port_spec.append('input [%d:0] RW%dM' % (width-1, pid)) + port_spec.append('input [%d:0] RW%dI' % (width-1, pid)) + port_spec.append('output [%d:0] RW%dO' % (width-1, pid)) + rwports.append(pid) + else: + sys.exit('%s: unknown port type %s' % (sys.argv[0], ptype)) + + nr = len(readports) + nw = len(writeports) + nrw = len(rwports) + masked = len(maskedports)>0 + tup = (depth, width, nr, nw, nrw, masked) + + decl.append('reg [%d:0] ram [%d:0];' % (width-1, depth-1)) + + for pid in readports: + decl.append('reg [%d:0] reg_R%dA;' % (addr_width-1, pid)) + sequential.append('if (R%dE) reg_R%dA <= R%dA;' % (pid, pid, pid)) + combinational.append('assign R%dO = ram[reg_R%dA];' % (pid, pid)) + + for pid in rwports: + decl.append('reg [%d:0] reg_RW%dA;' % (addr_width-1, pid)) + sequential.append('if (RW%dE && !RW%dW) reg_RW%dA <= RW%dA;' % (pid, pid, pid, pid)) + combinational.append('assign RW%dO = ram[reg_RW%dA];' % (pid, pid)) + + for pid in latchports: + decl.append('reg [%d:0] latch_W%dA;' % (addr_width-1, pid)) + decl.append('reg [%d:0] latch_W%dI;' % (width-1, pid)) + decl.append('reg latch_W%dE;' % (pid)) + combinational.append('always @(*) begin') + combinational.append(' if (!CLK && W%dE) latch_W%dA <= W%dA;' % (pid, pid, pid)) + combinational.append(' if (!CLK && W%dE) latch_W%dI <= W%dI;' % (pid, pid, pid)) + combinational.append(' if (!CLK) latch_W%dE <= W%dE;' % (pid, pid)) + combinational.append('end') + combinational.append('always @(*)') + combinational.append(' if (CLK && latch_W%dE)' % (pid)) + combinational.append(' ram[latch_W%dA] <= latch_W%dI;' % (pid, pid)) + + decl.append("integer i;") + sequential.append("for (i = 0; i < %d; i=i+1) begin" % width) + for pid in writeports: + mask = (' && W%dM[i]' % pid) if pid in maskedports else '' + sequential.append(" if (W%dE%s) ram[W%dA][i] <= W%dI[i];" % (pid, mask, pid, pid)) + for pid in rwports: + mask = (' && RW%dM[i]' % pid) if pid in maskedports else '' + sequential.append(" if (RW%dE && RW%dW%s) ram[RW%dA][i] <= RW%dI[i];" % (pid, pid, mask, pid, pid)) + sequential.append("end") + body = "\ + %s\n\ + always @(posedge CLK) begin\n\ + %s\n\ + end\n\ + %s\n" % ('\n '.join(decl), '\n '.join(sequential), '\n '.join(combinational)) + + s = "module %s(\n\ + %s\n\ +);\n\ +\n\ +%s\ +\n\ +endmodule\n" % (name, ',\n '.join(port_spec), body) + return s + +name = '' +width = 0 +depth = 0 +ports = '' + +tokens = sys.argv[1:len(sys.argv)] +i = 0 +while i < len(tokens): + a = tokens[i] + if a == 'name': + name = tokens[i+1] + i += 1 + elif a == 'width': + width = int(tokens[i+1]) + i += 1 + elif a == 'depth': + depth = int(tokens[i+1]) + i += 1 + elif a == 'ports': + ports = tokens[i+1].split(',') + i += 1 + elif a == 'mask_gran': + # currently used only for fpga, but here for .conf format compatability + mask_gran = int(tokens[i+1]) + i += 1 + else: + sys.exit('%s: unknown argument %s' % (sys.argv[0], a)) + i += 1 + +print gen_mem(name, width, depth, ports) diff --git a/vsrc/backup_mem.v b/vsrc/backup_mem.v new file mode 100644 index 00000000..10468639 --- /dev/null +++ b/vsrc/backup_mem.v @@ -0,0 +1,113 @@ +`define ceilLog2(x) ((x) > 2**30 ? 31 : \ +(x) > 2**29 ? 30 : \ +(x) > 2**28 ? 29 : \ +(x) > 2**27 ? 28 : \ +(x) > 2**26 ? 27 : \ +(x) > 2**25 ? 26 : \ +(x) > 2**24 ? 25 : \ +(x) > 2**23 ? 24 : \ +(x) > 2**22 ? 23 : \ +(x) > 2**21 ? 22 : \ +(x) > 2**20 ? 21 : \ +(x) > 2**19 ? 20 : \ +(x) > 2**18 ? 19 : \ +(x) > 2**17 ? 18 : \ +(x) > 2**16 ? 17 : \ +(x) > 2**15 ? 16 : \ +(x) > 2**14 ? 15 : \ +(x) > 2**13 ? 14 : \ +(x) > 2**12 ? 13 : \ +(x) > 2**11 ? 12 : \ +(x) > 2**10 ? 11 : \ +(x) > 2**9 ? 10 : \ +(x) > 2**8 ? 9 : \ +(x) > 2**7 ? 8 : \ +(x) > 2**6 ? 7 : \ +(x) > 2**5 ? 6 : \ +(x) > 2**4 ? 5 : \ +(x) > 2**3 ? 4 : \ +(x) > 2**2 ? 3 : \ +(x) > 2**1 ? 2 : \ +(x) > 2**0 ? 1 : 0) + +`ifdef MEM_BACKUP_EN +module BRAMMem +( + input clk, + input reset, + + input mem_req_valid, + output mem_req_ready, + input mem_req_rw, + input [`MEM_ADDR_BITS-1:0] mem_req_addr, + input [15:0] mem_req_tag, + + input mem_req_data_valid, + output mem_req_data_ready, + input [`MEM_DATA_BITS-1:0] mem_req_data_bits, + + output reg mem_resp_valid, + output reg [`MEM_DATA_BITS-1:0] mem_resp_data, + output reg [15:0] mem_resp_tag +); + + localparam DATA_CYCLES = 4; + localparam DEPTH = 2*1024*1024; + + reg [`ceilLog2(DATA_CYCLES)-1:0] cnt; + reg [15:0] tag; + reg state_busy, state_rw; + reg [`MEM_ADDR_BITS-1:0] addr; + + reg [`MEM_DATA_BITS-1:0] ram [DEPTH-1:0]; + wire [`ceilLog2(DEPTH)-1:0] ram_addr = state_busy ? {addr[`ceilLog2(DEPTH/DATA_CYCLES)-1:0], cnt} + : {mem_req_addr[`ceilLog2(DEPTH/DATA_CYCLES)-1:0], cnt}; + wire do_read = mem_req_valid && mem_req_ready && !mem_req_rw || state_busy && !state_rw; + wire do_write = mem_req_data_valid && mem_req_data_ready; + + initial + begin : zero + integer i; + for (i = 0; i < DEPTH; i = i+1) + ram[i] = 1'b0; + end + + always @(posedge clk) + begin + if (reset) + state_busy <= 1'b0; + else if ((do_read || do_write) && cnt == DATA_CYCLES-1) + state_busy <= 1'b0; + else if (mem_req_valid && mem_req_ready) + state_busy <= 1'b1; + + if (!state_busy && mem_req_valid) + begin + state_rw <= mem_req_rw; + tag <= mem_req_tag; + addr <= mem_req_addr; + end + + if (reset) + cnt <= 1'b0; + else if(do_read || do_write) + cnt <= cnt + 1'b1; + + if (do_write) + ram[ram_addr] <= mem_req_data_bits; + else + mem_resp_data <= ram[ram_addr]; + + if (reset) + mem_resp_valid <= 1'b0; + else + mem_resp_valid <= do_read; + + mem_resp_tag <= state_busy ? tag : mem_req_tag; + end + + assign mem_req_ready = !state_busy; + assign mem_req_data_ready = state_busy && state_rw; + +endmodule +`endif diff --git a/vsrc/const.vh b/vsrc/const.vh new file mode 100644 index 00000000..331b8a22 --- /dev/null +++ b/vsrc/const.vh @@ -0,0 +1,8 @@ +`ifndef CONST_VH +`define CONST_VH + +`define MEM_ADDR_BITS 34 +`define MEM_DATA_BITS 128 +`define MEM_TAG_BITS 10 + +`endif // CONST_VH diff --git a/vsrc/rocketTestHarness.v b/vsrc/rocketTestHarness.v new file mode 100644 index 00000000..b4e26f02 --- /dev/null +++ b/vsrc/rocketTestHarness.v @@ -0,0 +1,453 @@ +// Test harness for Rocket RISC-V Processor + +`define HTIF_WIDTH 16 + +extern "A" void htif_init +( + input reg [31:0] htif_width, + input reg [31:0] mem_width +); + +extern "A" void htif_fini(input reg failure); + +extern "A" void htif_tick +( + output reg htif_in_valid, + input reg htif_in_ready, + output reg [`HTIF_WIDTH-1:0] htif_in_bits, + + input reg htif_out_valid, + output reg htif_out_ready, + input reg [`HTIF_WIDTH-1:0] htif_out_bits, + + output reg [1:0] exit +); + +extern "A" void memory_tick +( + input reg mem_req_valid, + output reg mem_req_ready, + input reg mem_req_store, + input reg [`MEM_ADDR_BITS-1:0] mem_req_bits_addr, + input reg [`MEM_TAG_BITS-1:0] mem_req_bits_tag, + + input reg mem_req_data_valid, + output reg mem_req_data_ready, + input reg [`MEM_DATA_BITS-1:0] mem_req_data_bits, + + output reg mem_resp_valid, + input reg mem_resp_ready, + output reg [`MEM_TAG_BITS-1:0] mem_resp_bits_tag, + output reg [`MEM_DATA_BITS-1:0] mem_resp_bits_data +); + +module rocketTestHarness; + + reg [31:0] seed; + initial seed = $get_initial_random_seed(); + + //----------------------------------------------- + // Instantiate the processor + + reg clk = 0; + reg reset = 1; + reg r_reset; + reg start = 0; + + always #`CLOCK_PERIOD clk = ~clk; + + wire mem_req_valid; + reg mem_req_ready; + wire mem_req_bits_rw; + wire [`MEM_ADDR_BITS-1:0] mem_req_bits_addr; + wire [`MEM_TAG_BITS-1:0] mem_req_bits_tag; + + wire mem_req_data_valid; + reg mem_req_data_ready; + wire [`MEM_DATA_BITS-1:0] mem_req_data_bits; + + reg mem_resp_valid; + wire mem_resp_ready; + reg [`MEM_TAG_BITS-1:0] mem_resp_bits_tag; + reg [`MEM_DATA_BITS-1:0] mem_resp_bits_data; + + reg htif_out_ready; + wire htif_in_valid; + wire [`HTIF_WIDTH-1:0] htif_in_bits; + wire htif_in_ready, htif_out_valid; + wire [`HTIF_WIDTH-1:0] htif_out_bits; + + wire mem_bk_in_valid; + wire mem_bk_out_valid; + wire mem_bk_out_ready; + wire [`HTIF_WIDTH-1:0] mem_in_bits; + + wire htif_clk; + wire #0.1 htif_in_valid_delay = htif_in_valid; + wire htif_in_ready_delay; assign #0.1 htif_in_ready = htif_in_ready_delay; + wire [`HTIF_WIDTH-1:0] #0.1 htif_in_bits_delay = htif_in_bits; + + wire htif_out_valid_delay; assign #0.1 htif_out_valid = htif_out_valid_delay; + wire #0.1 htif_out_ready_delay = htif_out_ready; + wire [`HTIF_WIDTH-1:0] htif_out_bits_delay; assign #0.1 htif_out_bits = htif_out_bits_delay; + + wire htif_out_stats_delay; assign #0.1 htif_out_stats = htif_out_stats_delay; + + wire mem_req_valid_delay; assign #0.1 mem_req_valid = mem_req_valid_delay; + wire #0.1 mem_req_ready_delay = mem_req_ready; + wire [`MEM_TAG_BITS-1:0] mem_req_bits_tag_delay; assign #0.1 mem_req_bits_tag = mem_req_bits_tag_delay; + wire [`MEM_ADDR_BITS-1:0] mem_req_bits_addr_delay; assign #0.1 mem_req_bits_addr = mem_req_bits_addr_delay; + wire mem_req_bits_rw_delay; assign #0.1 mem_req_bits_rw = mem_req_bits_rw_delay; + + wire mem_req_data_valid_delay; assign #0.1 mem_req_data_valid = mem_req_data_valid_delay; + wire #0.1 mem_req_data_ready_delay = mem_req_data_ready; + wire [`MEM_DATA_BITS-1:0] mem_req_data_bits_delay; assign #0.1 mem_req_data_bits = mem_req_data_bits_delay; + + wire #0.1 mem_resp_valid_delay = mem_resp_valid; + wire mem_resp_ready_delay; assign #0.1 mem_resp_ready = mem_resp_ready_delay; + wire [`MEM_TAG_BITS-1:0] #0.1 mem_resp_bits_tag_delay = mem_resp_bits_tag; + wire [`MEM_DATA_BITS-1:0] #0.1 mem_resp_bits_data_delay = mem_resp_bits_data; + + wire #0.1 mem_bk_out_ready_delay = mem_bk_out_ready; + wire #0.1 mem_bk_in_valid_delay = mem_bk_in_valid; + wire mem_bk_out_valid_delay; assign #0.1 mem_bk_out_valid = mem_bk_out_valid_delay; + + `TOP dut + ( + .clk(clk), + .reset(reset), + + .io_host_in_valid(htif_in_valid_delay), + .io_host_in_ready(htif_in_ready_delay), + .io_host_in_bits(htif_in_bits_delay), + .io_host_out_valid(htif_out_valid_delay), + .io_host_out_ready(htif_out_ready_delay), + .io_host_out_bits(htif_out_bits_delay), + +`ifndef FPGA + .io_host_clk(htif_clk), + .io_host_clk_edge(), + .io_host_debug_stats_pcr(htif_out_stats_delay), + +`ifdef MEM_BACKUP_EN + .io_mem_backup_en(1'b1), +`else + .io_mem_backup_en(1'b0), +`endif + .io_in_mem_ready(), + .io_in_mem_valid(mem_bk_in_valid_delay), + .io_out_mem_ready(mem_bk_out_ready_delay), + .io_out_mem_valid(mem_bk_out_valid_delay), +`endif + + .io_mem_req_cmd_valid(mem_req_valid_delay), + .io_mem_req_cmd_ready(mem_req_ready_delay), + .io_mem_req_cmd_bits_rw(mem_req_bits_rw_delay), + .io_mem_req_cmd_bits_addr(mem_req_bits_addr_delay), + .io_mem_req_cmd_bits_tag(mem_req_bits_tag_delay), + + .io_mem_req_data_valid(mem_req_data_valid_delay), + .io_mem_req_data_ready(mem_req_data_ready_delay), + .io_mem_req_data_bits_data(mem_req_data_bits_delay), + + .io_mem_resp_valid(mem_resp_valid_delay), + .io_mem_resp_ready(mem_resp_ready_delay), + .io_mem_resp_bits_tag(mem_resp_bits_tag_delay), + .io_mem_resp_bits_data(mem_resp_bits_data_delay) + ); + +`ifdef FPGA + assign htif_clk = clk; +`endif + + //----------------------------------------------- + // Memory interface + + always @(negedge clk) + begin + r_reset <= reset; + if (reset || r_reset) + begin + mem_req_ready <= 0; + mem_req_data_ready <= 0; + mem_resp_valid <= 0; + mem_resp_bits_tag <= 0; + mem_resp_bits_data <= 0; + end + else + begin + memory_tick + ( + mem_req_valid, + mem_req_ready, + mem_req_bits_rw, + mem_req_bits_addr, + mem_req_bits_tag, + + mem_req_data_valid, + mem_req_data_ready, + mem_req_data_bits, + + mem_resp_valid, + mem_resp_ready, + mem_resp_bits_tag, + mem_resp_bits_data + ); + end + end + + wire mem_bk_req_valid, mem_bk_req_rw, mem_bk_req_data_valid; + wire [`MEM_TAG_BITS-1:0] mem_bk_req_tag; + wire [`MEM_ADDR_BITS-1:0] mem_bk_req_addr; + wire [`MEM_DATA_BITS-1:0] mem_bk_req_data_bits; + wire mem_bk_req_ready, mem_bk_req_data_ready, mem_bk_resp_valid; + wire [`MEM_TAG_BITS-1:0] mem_bk_resp_tag; + wire [`MEM_DATA_BITS-1:0] mem_bk_resp_data; + +`ifdef MEM_BACKUP_EN + memdessertMemDessert dessert + ( + .clk(htif_clk), + .reset(reset), + + .io_narrow_req_valid(mem_bk_out_valid), + .io_narrow_req_ready(mem_bk_out_ready), + .io_narrow_req_bits(htif_out_bits), + + .io_narrow_resp_valid(mem_bk_in_valid), + .io_narrow_resp_bits(mem_in_bits), + + .io_wide_req_cmd_valid(mem_bk_req_valid), + .io_wide_req_cmd_ready(mem_bk_req_ready), + .io_wide_req_cmd_bits_rw(mem_bk_req_rw), + .io_wide_req_cmd_bits_addr(mem_bk_req_addr), + .io_wide_req_cmd_bits_tag(mem_bk_req_tag), + + .io_wide_req_data_valid(mem_bk_req_data_valid), + .io_wide_req_data_ready(mem_bk_req_data_ready), + .io_wide_req_data_bits_data(mem_bk_req_data_bits), + + .io_wide_resp_valid(mem_bk_resp_valid), + .io_wide_resp_ready(), + .io_wide_resp_bits_data(mem_bk_resp_data), + .io_wide_resp_bits_tag(mem_bk_resp_tag) + ); + + BRAMMem mem + ( + .clk(htif_clk), + .reset(reset), + + .mem_req_valid(mem_bk_req_valid), + .mem_req_ready(mem_bk_req_ready), + .mem_req_rw(mem_bk_req_rw), + .mem_req_addr(mem_bk_req_addr), + .mem_req_tag(mem_bk_req_tag), + + .mem_req_data_valid(mem_bk_req_data_valid), + .mem_req_data_ready(mem_bk_req_data_ready), + .mem_req_data_bits(mem_bk_req_data_bits), + + .mem_resp_valid(mem_bk_resp_valid), + .mem_resp_data(mem_bk_resp_data), + .mem_resp_tag(mem_bk_resp_tag) + ); +`else + // set dessert outputs to zero when !backupmem_en + assign mem_bk_out_ready = 0; + assign mem_bk_in_valid = 0; + assign mem_in_bits = 0; + assign mem_bk_req_valid = 0; + assign mem_bk_req_addr = 0; + assign mem_bk_req_rw = 0; + assign mem_bk_req_tag = 0; + assign mem_bk_req_data_valid = 0; + assign mem_bk_req_data_bits = 0; +`endif + + reg htif_in_valid_premux; + reg [`HTIF_WIDTH-1:0] htif_in_bits_premux; + assign htif_in_bits = mem_bk_in_valid ? mem_in_bits : htif_in_bits_premux; + assign htif_in_valid = htif_in_valid_premux && !mem_bk_in_valid; + wire htif_in_ready_premux = htif_in_ready && !mem_bk_in_valid; + reg [1:0] exit = 0; + + always @(posedge htif_clk) + begin + if (reset || r_reset) + begin + htif_in_valid_premux <= 0; + htif_out_ready <= 0; + exit <= 0; + end + else + begin + htif_tick + ( + htif_in_valid_premux, + htif_in_ready_premux, + htif_in_bits_premux, + htif_out_valid, + htif_out_ready, + htif_out_bits, + exit + ); + end + end + + //----------------------------------------------- + // Start the simulation + reg [ 31:0] htif_width = `HTIF_WIDTH; + reg [ 31:0] mem_width = `MEM_DATA_BITS; + reg [ 63:0] max_cycles = 0; + reg [ 63:0] trace_count = 0; + reg [1023:0] loadmem = 0; + reg [1023:0] vcdplusfile = 0; + reg [1023:0] vcdfile = 0; + reg stats_active = 0; + reg stats_tracking = 0; + reg verbose = 0; + integer stderr = 32'h80000002; + + // Some helper functions for turning on, stopping, and finishing stat tracking + task start_stats; + begin + if(!reset || !stats_active) + begin +`ifdef DEBUG + if(vcdplusfile) + begin + $vcdpluson(0); + $vcdplusmemon(0); + end + if(vcdfile) + begin + $dumpon; + end +`endif + assign stats_tracking = 1; + end + end + endtask + task stop_stats; + begin +`ifdef DEBUG + $vcdplusoff; $dumpoff; +`endif + assign stats_tracking = 0; + end + endtask +`ifdef DEBUG +`define VCDPLUSCLOSE $vcdplusclose; $dumpoff; +`else +`define VCDPLUSCLOSE +`endif + + // Read input arguments and initialize + initial + begin + $value$plusargs("max-cycles=%d", max_cycles); +`ifdef MEM_BACKUP_EN + $value$plusargs("loadmem=%s", loadmem); + if (loadmem) + $readmemh(loadmem, mem.ram); +`endif + verbose = $test$plusargs("verbose"); + htif_init(htif_width, mem_width); +`ifdef DEBUG + stats_active = $test$plusargs("stats"); + if ($value$plusargs("vcdplusfile=%s", vcdplusfile)) + begin + $vcdplusfile(vcdplusfile); + end + if ($value$plusargs("vcdfile=%s", vcdfile)) + begin + $dumpfile(vcdfile); + $dumpvars(0, dut); + end + if (!stats_active) + begin + start_stats; + end + else + begin + if(vcdfile) + begin + $dumpoff; + end + end +`endif + + // Strobe reset + #777.7 reset = 0; + + end + + reg [255:0] reason = 0; + always @(posedge clk) + begin + if (max_cycles > 0 && trace_count > max_cycles) + reason = "timeout"; + if (exit > 1) + $sformat(reason, "tohost = %d", exit >> 1); + + if (reason) + begin + $fdisplay(stderr, "*** FAILED *** (%s) after %d simulation cycles", reason, trace_count); + `VCDPLUSCLOSE + htif_fini(1); + end + + if (exit == 1) + begin + `VCDPLUSCLOSE + htif_fini(0); + end + end + + //----------------------------------------------- + // Tracing code + + always @(posedge clk) + begin + if(stats_active) + begin + if(!stats_tracking && htif_out_stats) + begin + start_stats; + end + if(stats_tracking && !htif_out_stats) + begin + stop_stats; + end + end + end + + always @(posedge htif_clk) + begin + if (verbose && mem_bk_req_valid && mem_bk_req_ready) + begin + $fdisplay(stderr, "MB: rw=%d addr=%x", mem_bk_req_rw, {mem_bk_req_addr,6'd0}); + end + end + + always @(posedge clk) + begin + if (verbose && mem_req_valid && mem_req_ready) + begin + $fdisplay(stderr, "MC: rw=%d addr=%x", mem_req_bits_rw, {mem_req_bits_addr,6'd0}); + end + end + + always @(posedge clk) + begin + trace_count = trace_count + 1; +`ifdef GATE_LEVEL + if (verbose) + begin + $fdisplay(stderr, "C: %10d", trace_count-1); + end +`endif + end + +endmodule