[MIDAS] refactor test code

This commit is contained in:
Donggyu Kim 2016-10-17 21:48:08 -07:00
parent beacd34b09
commit 9272a8d457
22 changed files with 244 additions and 19 deletions

3
.gitmodules vendored
View File

@ -0,0 +1,3 @@
[submodule "src/main/cc/dramsim"]
path = src/main/cc/dramsim2
url = https://github.com/dramninjasUMD/DRAMSim2.git

108
src/main/cc/Makefile Normal file
View File

@ -0,0 +1,108 @@
base_dir = $(abspath .)
util_dir = $(base_dir)/utils
v_dir = $(abspath ../verilog)
r_dir = $(abspath ../resources)
CXXFLAGS := $(CXXFLAGS) -std=c++11 -Wall -I$(base_dir)/dramsim2
include $(util_dir)/Makefrag
########################################################################
# Parameters:
# 1) DESIGN: Target design of strober
# 2) GEN_DIR: Directory for generated source code
# 3) OUT_DIR: Directory for binary files (by default GEN_DIR)
# 4) TESTBENCH: C++ testbench written by user (not necessary for replay)
# 5) CLOCK_PERIOD(optional): clock period of tests
########################################################################
OUT_DIR ?= $(GEN_DIR)
CLOCK_PERIOD ?= 0.5
CXXFLAGS := $(CXXFLAGS) -I$(base_dir) -I$(util_dir) $(if $(TESTBENCH),-I$(dir $(TESTBENCH)))
LDFLAGS := $(LDFLAGS) -L$(util_dir) -lstdc++
zynq_files := sample simif simif_zynq
zynq_h := $(addprefix $(base_dir)/, $(addsuffix .h, $(zynq_files)))
zynq_cc := $(addprefix $(base_dir)/, $(addsuffix .cc, $(zynq_files)))
$(OUT_DIR)/$(DESIGN)-zynq: $(TESTBENCH) $(util_dir)/biguint.cc $(util_dir)/biguint.h $(zynq_cc) $(zynq_h)
mkdir -p $(OUT_DIR)
$(CXX) $(CXXFLAGS) -include $(GEN_DIR)/$(DESIGN)-const.h -o $@ $< $(word 2, $^) $(zynq_cc)
zynq: $(OUT_DIR)/$(DESIGN)-zynq
$(OUT_DIR)/dramsim2_ini: $(r_dir)/dramsim2_ini
ln -sf $< $@
$(OUT_DIR)/$(DESIGN).chain: $(GEN_DIR)/$(DESIGN).chain
cp -n $< $@
emul_files := sample simif simif_emul
emul_h := $(addprefix $(base_dir)/, $(addsuffix .h, $(emul_files)))
emul_cc := $(addprefix $(base_dir)/, $(addsuffix .cc, $(emul_files)))
# Compile verilator emulation binary
VERILATOR := verilator --cc --exe
VERILATOR_FLAGS := --assert -Wno-STMTDLY -O3 -CFLAGS "$(CXXFLAGS)"
$(OUT_DIR)/V$(DESIGN): $(GEN_DIR)/ZynqShim.v $(TESTBENCH) $(util_dir)/libemul.a $(emul_cc) $(emul_h)
mkdir -p $(OUT_DIR)
$(VERILATOR) $(VERILATOR_FLAGS) --top-module ZynqShim -Mdir $(GEN_DIR)/V$(DESIGN).csrc \
-CFLAGS "-include $(GEN_DIR)/$(DESIGN)-const.h" \
-CFLAGS "-include $(GEN_DIR)/V$(DESIGN).csrc/VZynqShim.h" \
-LDFLAGS "$(LDFLAGS) -lemul -lpthread" \
-o $@ $< $(TESTBENCH) $(emul_cc)
$(MAKE) -C $(GEN_DIR)/V$(DESIGN).csrc -f VZynqShim.mk
$(OUT_DIR)/V$(DESIGN)-debug: $(GEN_DIR)/ZynqShim.v $(TESTBENCH) $(util_dir)/libemul.a $(emul_cc) $(emul_h)
mkdir -p $(OUT_DIR)
$(VERILATOR) $(VERILATOR_FLAGS) --trace --top-module ZynqShim -Mdir $(GEN_DIR)/V$(DESIGN)-debug.csrc \
-CFLAGS "-include $(GEN_DIR)/$(DESIGN)-const.h" \
-CFLAGS "-include $(GEN_DIR)/V$(DESIGN)-debug.csrc/VZynqShim.h" \
-LDFLAGS "$(LDFLAGS) -lemul -lpthread" \
-o $@ $< $(TESTBENCH) $(emul_cc)
$(MAKE) -C $(GEN_DIR)/V$(DESIGN)-debug.csrc -f VZynqShim.mk
verilator: $(OUT_DIR)/V$(DESIGN) $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
verilator-debug: $(OUT_DIR)/V$(DESIGN)-debug $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
# Compile VCS emulation binary
VCS := vcs -full64
VCS_FLAGS := -quiet -timescale=1ns/1ps +v2k +rad +vcs+initreg+random +vcs+lic+wait \
-e vcs_main -cpp $(CXX) -CFLAGS "$(CXXFLAGS) -I$(VCS_HOME)/include -DVCS" \
+define+CLOCK_PERIOD=$(CLOCK_PERIOD)
$(OUT_DIR)/$(DESIGN): $(GEN_DIR)/ZynqShim.v $(v_dir)/emul.v $(TESTBENCH) $(util_dir)/libemul.a $(emul_cc) $(emul_h)
mkdir -p $(OUT_DIR)
$(VCS) $(VCS_FLAGS) -Mdir=$(GEN_DIR)/$(DESIGN).csrc +vc+list \
-CFLAGS "-include $(GEN_DIR)/$(DESIGN)-const.h" -LDFLAGS "$(LDFLAGS) -lemul -lpthread" \
-o $@ $< $(GEN_DIR)/$(DESIGN)-const.vh $(word 2, $^) $(TESTBENCH) $(emul_cc) $(word 4, $^)
$(OUT_DIR)/$(DESIGN)-debug: $(GEN_DIR)/ZynqShim.v $(v_dir)/emul.v $(TESTBENCH) $(util_dir)/libemul.a $(emul_cc) $(emul_h)
mkdir -p $(OUT_DIR)
$(VCS) $(VCS_FLAGS) -Mdir=$(GEN_DIR)/$(DESIGN)-debug.csrc +vc+list -debug_pp +define+DEBUG \
-CFLAGS "-include $(GEN_DIR)/$(DESIGN)-const.h" -LDFLAGS "$(LDFLAGS) -lemul -lpthread" \
-o $@ $< $(GEN_DIR)/$(DESIGN)-const.vh $(word 2, $^) $(TESTBENCH) $(emul_cc) $(word 4, $^)
vcs: $(OUT_DIR)/$(DESIGN) $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
vcs-debug: $(OUT_DIR)/$(DESIGN)-debug $(OUT_DIR)/$(DESIGN).chain $(OUT_DIR)/dramsim2_ini
# Compile VCS replay binary
replay_files := sample replay_vpi
replay_h := $(addprefix $(base_dir)/, $(addsuffix .h, $(replay_files) replay))
replay_cc := $(addprefix $(base_dir)/, $(addsuffix .cc, $(replay_files)))
$(OUT_DIR)/$(DESIGN)-replay: $(GEN_DIR)/$(DESIGN).v $(v_dir)/replay.v $(util_dir)/libreplay.a $(replay_cc) $(replay_h)
mkdir -p $(OUT_DIR)
$(VCS) $(VCS_FLAGS) -Mdir=$(GEN_DIR)/$(DESIGN)-replay.csrc \
+define+VFRAG=\"$(GEN_DIR)/$(DESIGN).vfrag\" \
-debug_pp +vpi -P $(r_dir)/vpi.tab -LDFLAGS "$(LDFLAGS) -lreplay" \
-o $@ $< $(word 2, $^) $(replay_cc) $(word 3, $^)
vcs-replay: $(OUT_DIR)/$(DESIGN)-replay
clean:
rm -rf $(util_dir)/*.o $(util_dir)/*.a
.PHONY: zynq verilator verilator-debug vcs vcs-debug vcs-replay clean

1
src/main/cc/dramsim2 Submodule

@ -0,0 +1 @@
Subproject commit 2fa5ab55dbb639fa5991218f7b959061f19f590c

View File

@ -163,22 +163,22 @@ private:
}
inline void force(const std::string& node, biguint_t& data) {
check_signal(node);
if (log) std::cerr << " * FORCE " << node << " <- 0x" << data << " *" << std::endl;
check_signal(node);
size_t id = replay_data.signal_map[node];
put_value(replay_data.signals[id], data, true);
}
inline void load(const std::string& node, biguint_t& data) {
check_signal(node);
if (log) std::cerr << " * LOAD " << node << " <- 0x" << data << " *" << std::endl;
check_signal(node);
size_t id = replay_data.signal_map[node];
put_value(replay_data.signals[id], data, false);
}
inline void poke(const std::string& node, biguint_t& data) {
check_signal(node);
if (log) std::cerr << " * POKE " << node << " <- 0x" << data << " *" << std::endl;
check_signal(node);
size_t id = replay_data.signal_map[node];
put_value(replay_data.signals[id], data, false);
}

View File

@ -12,6 +12,7 @@
#include <iostream>
static const size_t MEM_WIDTH = MEM_DATA_BITS / 8;
static const size_t MMIO_WIDTH = CHANNEL_DATA_BITS / 8;
static uint64_t main_time = 0;
static mmio_t* master = NULL;
static mm_t* slave = NULL;
@ -367,6 +368,7 @@ void simif_emul_t::init(int argc, char** argv, bool log, bool fast_loadmem) {
const char* loadmem = NULL;
const char* waveform = "dump.vcd";
bool dramsim = false;
size_t memsize = 1 << 30;
for (auto &arg: args) {
if (arg.find("+loadmem=") == 0) {
loadmem = arg.c_str() + 9;
@ -377,10 +379,13 @@ void simif_emul_t::init(int argc, char** argv, bool log, bool fast_loadmem) {
if (arg.find("+dramsim") == 0) {
dramsim = true;
}
if (arg.find("+memsize=") == 0) {
memsize = strtol(arg.c_str() + 9, NULL, 10);
}
}
size_t memsize = 1 << 30;
master = (mmio_t*) new mmio_t;
master->init(CHANNEL_DATA_BITS / 8);
slave = dramsim ? (mm_t*) new mm_dramsim2_t : (mm_t*) new mm_magic_t;
slave->init(memsize, MEM_DATA_BITS / 8, 64);
@ -426,8 +431,9 @@ int simif_emul_t::finish() {
}
void simif_emul_t::write(size_t addr, uint32_t data) {
static const size_t CHANNEL_STRB = (1 << CHANNEL_STRB_BITS) - 1;
try {
master->write_req(addr, &data);
master->write_req(addr << CHANNEL_SIZE, CHANNEL_SIZE, &data, CHANNEL_STRB);
while(!master->write_resp()) {
#ifdef VCS
target->switch_to();
@ -449,7 +455,7 @@ void simif_emul_t::write(size_t addr, uint32_t data) {
uint32_t simif_emul_t::read(size_t addr) {
uint32_t data;
try {
master->read_req(addr);
master->read_req(addr << CHANNEL_SIZE, CHANNEL_SIZE);
while(!master->read_resp(&data)) {
#ifdef VCS
target->switch_to();

2
src/main/cc/utils/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.o
*.a

View File

@ -0,0 +1,18 @@
# compile 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 $@ $<
# Compile utility code
emul_files := biguint context mmio mm mm_dramsim2
replay_files := biguint context
UTIL_OBJS = $(patsubst %.cc, %.o, $(wildcard $(utils_dir)/*.cc))
$(UTIL_OBJS): %.o: %.cc %.h
$(CXX) $(CXXFLAGS) -I$(util_dir) -I$(base_dir)/dramsim2 -c -o $@ $<
$(util_dir)/libemul.a: $(DRAMSIM_OBJS) $(addprefix $(util_dir)/, $(addsuffix .o, $(emul_files)))
ar rcs $@ $^
$(util_dir)/libreplay.a: $(addprefix $(util_dir)/, $(addsuffix .o, $(replay_files)))
ar rcs $@ $^

View File

@ -1,16 +1,19 @@
#include "mmio.h"
#include <cassert>
#include <cmath>
const size_t CHANNEL_STRB = (1 << CHANNEL_STRB_BITS) - 1;
void mmio_t::init(size_t word_size) {
dummy_data.resize(word_size);
}
void mmio_t::read_req(uint64_t addr) {
mmio_req_addr_t ar(0, addr << CHANNEL_SIZE, CHANNEL_SIZE, 0);
void mmio_t::read_req(uint64_t addr, size_t size) {
mmio_req_addr_t ar(0, addr, size, 0);
this->ar.push(ar);
}
void mmio_t::write_req(uint64_t addr, void* data) {
mmio_req_addr_t aw(0, addr << CHANNEL_SIZE, CHANNEL_SIZE, 0);
mmio_req_data_t w((char*) data, CHANNEL_STRB, true);
void mmio_t::write_req(uint64_t addr, size_t size, void* data, size_t strb) {
mmio_req_addr_t aw(0, addr, size, 0);
mmio_req_data_t w((char*) data, strb, true);
this->aw.push(aw);
this->w.push(w);
}

View File

@ -6,8 +6,6 @@
#include <vector>
#include <queue>
const size_t MMIO_WIDTH = CHANNEL_DATA_BITS / 8;
struct mmio_req_addr_t
{
size_t id;
@ -46,6 +44,8 @@ public:
read_inflight = false;
write_inflight = false;
}
void init(size_t data_bits);
bool aw_valid() { return !aw.empty() && !write_inflight; }
size_t aw_id() { return aw_valid() ? aw.front().id : 0; }
@ -62,13 +62,13 @@ public:
bool w_valid() { return !w.empty(); }
size_t w_strb() { return w_valid() ? w.front().strb : 0; }
bool w_last() { return w_valid() ? w.front().last : false; }
void* w_data() { return w_valid() ? w.front().data : dummy_data; }
void* w_data() { return w_valid() ? w.front().data : &dummy_data[0]; }
bool r_ready() { return read_inflight; }
bool b_ready() { return write_inflight; }
void read_req(uint64_t addr);
void write_req(uint64_t addr, void* data);
void read_req(uint64_t addr, size_t size);
void write_req(uint64_t addr, size_t size, void* data, size_t strb);
void tick
(
@ -96,7 +96,7 @@ private:
bool read_inflight;
bool write_inflight;
char dummy_data[MMIO_WIDTH];
std::vector<char> dummy_data;
};
#endif // __MMIO_H

View File

@ -0,0 +1,58 @@
NUM_BANKS=8
NUM_ROWS=32768
NUM_COLS=2048
DEVICE_WIDTH=4
;in nanoseconds
;#define REFRESH_PERIOD 7800
REFRESH_PERIOD=7800
tCK=1.5 ;*
CL=10 ;*
AL=0 ;*
;AL=3; needs to be tRCD-1 or 0
;RL=(CL+AL)
;WL=(RL-1)
BL=8 ;*
tRAS=24;*
tRCD=10 ;*
tRRD=4 ;*
tRC=34 ;*
tRP=10 ;*
tCCD=4 ;*
tRTP=5 ;*
tWTR=5 ;*
tWR=10 ;*
tRTRS=1; -- RANK PARAMETER, TODO
tRFC=107;*
tFAW=20;*
tCKE=4 ;*
tXP=4 ;*
tCMD=1 ;*
IDD0=100;
IDD1=130;
IDD2P=10;
IDD2Q=70;
IDD2N=70;
IDD3Pf=60;
IDD3Ps=60;
IDD3N=90;
IDD4W=255;
IDD4R=230;
IDD5=305;
IDD6=9;
IDD6L=12;
IDD7=415;
;same bank
;READ_TO_PRE_DELAY=(AL+BL/2+max(tRTP,2)-2)
;WRITE_TO_PRE_DELAY=(WL+BL/2+tWR)
;READ_TO_WRITE_DELAY=(RL+BL/2+tRTRS-WL)
;READ_AUTOPRE_DELAY=(AL+tRTP+tRP)
;WRITE_AUTOPRE_DELAY=(WL+BL/2+tWR+tRP)
;WRITE_TO_READ_DELAY_B=(WL+BL/2+tWTR);interbank
;WRITE_TO_READ_DELAY_R=(WL+BL/2+tRTRS-RL);interrank
Vdd=1.5 ; TODO: double check this

View File

@ -0,0 +1,25 @@
; COPY THIS FILE AND MODIFY IT TO SUIT YOUR NEEDS
NUM_CHANS=1 ; number of *logically independent* channels (i.e. each with a separate memory controller); should be a power of 2
JEDEC_DATA_BUS_BITS=64 ; Always 64 for DDRx; if you want multiple *ganged* channels, set this to N*64
TRANS_QUEUE_DEPTH=32 ; transaction queue, i.e., CPU-level commands such as: READ 0xbeef
CMD_QUEUE_DEPTH=32 ; command queue, i.e., DRAM-level commands such as: CAS 544, RAS 4
EPOCH_LENGTH=100000 ; length of an epoch in cycles (granularity of simulation)
ROW_BUFFER_POLICY=open_page ; close_page or open_page
ADDRESS_MAPPING_SCHEME=scheme2 ;valid schemes 1-7; For multiple independent channels, use scheme7 since it has the most parallelism
SCHEDULING_POLICY=rank_then_bank_round_robin ; bank_then_rank_round_robin or rank_then_bank_round_robin
QUEUING_STRUCTURE=per_rank ;per_rank or per_rank_per_bank
;for true/false, please use all lowercase
DEBUG_TRANS_Q=false
DEBUG_CMD_Q=false
DEBUG_ADDR_MAP=false
DEBUG_BUS=false
DEBUG_BANKSTATE=false
DEBUG_BANKS=false
DEBUG_POWER=false
VIS_FILE_OUTPUT=false
USE_LOW_POWER=true ; go into low power mode when idle?
VERIFICATION_OUTPUT=false ; should be false for normal operation
TOTAL_ROW_ACCESSES=4 ; maximum number of open page requests to send to the same row before forcing a row close (to prevent starvation)

View File

@ -23,6 +23,7 @@ private class Compiler(conf: File) extends firrtl.Compiler {
object Compiler {
def apply[T <: chisel3.Module](w: => T, dir: File): firrtl.ir.Circuit = {
dir.mkdirs
lazy val dut = w
val chirrtl = firrtl.Parser.parse(chisel3.Driver.emit(() => dut))
val conf = new File(dir, s"${chirrtl.main}.conf")

View File

@ -69,7 +69,7 @@ extern "A" void tick
output reg [`MEM_ID_BITS-1:0] slave_b_id
);
module vcsHarness;
module emul;
reg clock = 1'b0;
reg reset = 1'b1;
reg exit = 1'b0;