update for rocket-chip release
This commit is contained in:
18
vsim/.gitignore
vendored
Normal file
18
vsim/.gitignore
vendored
Normal 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
25
vsim/Makefile
Normal 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
66
vsim/Makefrag
Normal 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
91
vsim/Makefrag-sim
Normal 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
136
vsim/vlsi_mem_gen
Executable 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)
|
Reference in New Issue
Block a user