1
0
Fork 0

update for rocket-chip release

This commit is contained in:
Yunsup Lee 2014-08-31 20:26:55 -07:00
parent 83380053de
commit c03c09ec31
23 changed files with 1386 additions and 155 deletions

227
Makefrag
View File

@ -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 $< $@

View File

@ -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 <fcntl.h>
#include <signal.h>
@ -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;

View File

@ -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)))

18
fsim/.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
simv*
csrc
*.vpd
*.key
DVE*
.vcs*
timestamp
*.out
*.h
*.log
*.cmd
*.daidir
*.ucli
*.a
*.vcd
dramsim2_ini
generated-src
output

25
fsim/Makefile Normal file
View File

@ -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

68
fsim/Makefrag Normal file
View File

@ -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

185
fsim/fpga_mem_gen Executable file
View File

@ -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()

@ -1 +1 @@
Subproject commit 4a938b1aae6df5609400235448583c5c34b47da4
Subproject commit 1c8a6e6815eadebc1592c65e10a2ba87ecabb3c6

View File

@ -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")

@ -1 +0,0 @@
Subproject commit 83ed3f519de9929b6551b98677047228a8ab4d0c

@ -1 +1 @@
Subproject commit 1f62b9b6b6503a6a179f5d7b12d5157437405c83
Subproject commit 94d919625a75b1d3087f16c1b346cee3c2fb45a8

View File

@ -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

View File

@ -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)

View File

@ -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 } }

View File

@ -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 {

18
vsim/.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
simv*
csrc
*.vpd
*.key
DVE*
.vcs*
timestamp
*.out
*.h
*.log
*.cmd
*.daidir
*.ucli
*.a
*.vcd
dramsim2_ini
generated-src
output

25
vsim/Makefile Normal file
View File

@ -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

66
vsim/Makefrag Normal file
View File

@ -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

91
vsim/Makefrag-sim Normal file
View File

@ -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)

136
vsim/vlsi_mem_gen Executable file
View File

@ -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)

113
vsrc/backup_mem.v Normal file
View File

@ -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

8
vsrc/const.vh Normal file
View File

@ -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

453
vsrc/rocketTestHarness.v Normal file
View File

@ -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