diff --git a/csrc/emulator.cc b/csrc/emulator.cc index c1671831..97cc50dd 100644 --- a/csrc/emulator.cc +++ b/csrc/emulator.cc @@ -10,6 +10,10 @@ #include #include +#define MEM_SIZE_BITS 3 +#define MEM_LEN_BITS 8 +#define MEM_RESP_BITS 2 + htif_emulator_t* htif; void handle_sigterm(int sig) { @@ -29,6 +33,7 @@ int main(int argc, char** argv) bool dramsim2 = false; bool log = false; uint64_t memsz_mb = MEM_SIZE / (1024*1024); + mm_t *mm[N_MEM_CHANNELS]; for (int i = 1; i < argc; i++) { @@ -69,22 +74,25 @@ int main(int argc, char** argv) srand(random_seed); tile.init(random_seed); - uint64_t mem_width = tile.Top__io_mem_0_r_bits_data.width() / 8; + uint64_t mem_width = MEM_DATA_BITS / 8; // Instantiate and initialize main memory - mm_t* mm = dramsim2 ? (mm_t*)(new mm_dramsim2_t) : (mm_t*)(new mm_magic_t); - try { - mm->init(memsz_mb*1024*1024, mem_width, LINE_SIZE); + for (int i = 0; i < N_MEM_CHANNELS; i++) { + mm[i] = dramsim2 ? (mm_t*)(new mm_dramsim2_t) : (mm_t*)(new mm_magic_t); + try { + mm[i]->init(memsz_mb*1024*1024, mem_width, LINE_SIZE); + } catch (const std::bad_alloc& e) { + fprintf(stderr, + "Failed to allocate %ld bytes (%ld MiB) of memory\n" + "Set smaller amount of memory using +memsize= (in MiB)\n", + memsz_mb*1024*1024, memsz_mb); + exit(-1); + } + + if (loadmem) + load_mem(mm[i]->get_data(), loadmem); } - catch (const std::bad_alloc& e) { - fprintf(stderr, - "Failed to allocate %ld bytes (%ld MiB) of memory\n" - "Set smaller amount of memory using +memsize= (in MiB)\n" , memsz_mb*1024*1024, memsz_mb - ); - exit(-1); - } - if (loadmem) - load_mem(mm->get_data(), loadmem); + // Instantiate HTIF htif = new htif_emulator_t(memsz_mb, @@ -104,21 +112,58 @@ int main(int argc, char** argv) tile.clock_hi(LIT<1>(1)); } + dat_t<1> *mem_ar_valid[N_MEM_CHANNELS]; + dat_t<1> *mem_ar_ready[N_MEM_CHANNELS]; + dat_t *mem_ar_bits_addr[N_MEM_CHANNELS]; + dat_t *mem_ar_bits_id[N_MEM_CHANNELS]; + dat_t *mem_ar_bits_size[N_MEM_CHANNELS]; + dat_t *mem_ar_bits_len[N_MEM_CHANNELS]; + + dat_t<1> *mem_aw_valid[N_MEM_CHANNELS]; + dat_t<1> *mem_aw_ready[N_MEM_CHANNELS]; + dat_t *mem_aw_bits_addr[N_MEM_CHANNELS]; + dat_t *mem_aw_bits_id[N_MEM_CHANNELS]; + dat_t *mem_aw_bits_size[N_MEM_CHANNELS]; + dat_t *mem_aw_bits_len[N_MEM_CHANNELS]; + + dat_t<1> *mem_w_valid[N_MEM_CHANNELS]; + dat_t<1> *mem_w_ready[N_MEM_CHANNELS]; + dat_t *mem_w_bits_data[N_MEM_CHANNELS]; + dat_t *mem_w_bits_strb[N_MEM_CHANNELS]; + dat_t<1> *mem_w_bits_last[N_MEM_CHANNELS]; + + dat_t<1> *mem_b_valid[N_MEM_CHANNELS]; + dat_t<1> *mem_b_ready[N_MEM_CHANNELS]; + dat_t *mem_b_bits_resp[N_MEM_CHANNELS]; + dat_t *mem_b_bits_id[N_MEM_CHANNELS]; + + dat_t<1> *mem_r_valid[N_MEM_CHANNELS]; + dat_t<1> *mem_r_ready[N_MEM_CHANNELS]; + dat_t *mem_r_bits_resp[N_MEM_CHANNELS]; + dat_t *mem_r_bits_id[N_MEM_CHANNELS]; + dat_t *mem_r_bits_data[N_MEM_CHANNELS]; + dat_t<1> *mem_r_bits_last[N_MEM_CHANNELS]; + +#include TBFRAG + while (!htif->done() && trace_count < max_cycles && ret == 0) { - tile.Top__io_mem_0_ar_ready = LIT<1>(mm->ar_ready()); - tile.Top__io_mem_0_aw_ready = LIT<1>(mm->aw_ready()); - tile.Top__io_mem_0_w_ready = LIT<1>(mm->w_ready()); + for (int i = 0; i < N_MEM_CHANNELS; i++) { + *mem_ar_ready[i] = LIT<1>(mm[i]->ar_ready()); + *mem_aw_ready[i] = LIT<1>(mm[i]->aw_ready()); + *mem_w_ready[i] = LIT<1>(mm[i]->w_ready()); - tile.Top__io_mem_0_b_valid = LIT<1>(mm->b_valid()); - tile.Top__io_mem_0_b_bits_resp = LIT<64>(mm->b_resp()); - tile.Top__io_mem_0_b_bits_id = LIT<64>(mm->b_id()); + *mem_b_valid[i] = LIT<1>(mm[i]->b_valid()); + *mem_b_bits_resp[i] = LIT<64>(mm[i]->b_resp()); + *mem_b_bits_id[i] = LIT<64>(mm[i]->b_id()); - tile.Top__io_mem_0_r_valid = LIT<1>(mm->r_valid()); - tile.Top__io_mem_0_r_bits_resp = LIT<64>(mm->r_resp()); - tile.Top__io_mem_0_r_bits_id = LIT<64>(mm->r_id()); - tile.Top__io_mem_0_r_bits_last = LIT<1>(mm->r_last()); - memcpy(tile.Top__io_mem_0_r_bits_data.values, mm->r_data(), mem_width); + *mem_r_valid[i] = LIT<1>(mm[i]->r_valid()); + *mem_r_bits_resp[i] = LIT<64>(mm[i]->r_resp()); + *mem_r_bits_id[i] = LIT<64>(mm[i]->r_id()); + *mem_r_bits_last[i] = LIT<1>(mm[i]->r_last()); + + memcpy(mem_r_bits_data[i]->values, mm[i]->r_data(), mem_width); + } try { tile.clock_lo(LIT<1>(0)); @@ -128,27 +173,29 @@ int main(int argc, char** argv) std::cerr << e.what() << std::endl; } - mm->tick( - tile.Top__io_mem_0_ar_valid.lo_word(), - tile.Top__io_mem_0_ar_bits_addr.lo_word(), - tile.Top__io_mem_0_ar_bits_id.lo_word(), - tile.Top__io_mem_0_ar_bits_size.lo_word(), - tile.Top__io_mem_0_ar_bits_len.lo_word(), + for (int i = 0; i < N_MEM_CHANNELS; i++) { + mm[i]->tick( + mem_ar_valid[i]->to_bool(), + mem_ar_bits_addr[i]->lo_word(), + mem_ar_bits_id[i]->lo_word(), + mem_ar_bits_size[i]->lo_word(), + mem_ar_bits_len[i]->lo_word(), - tile.Top__io_mem_0_aw_valid.lo_word(), - tile.Top__io_mem_0_aw_bits_addr.lo_word(), - tile.Top__io_mem_0_aw_bits_id.lo_word(), - tile.Top__io_mem_0_aw_bits_size.lo_word(), - tile.Top__io_mem_0_aw_bits_len.lo_word(), + mem_aw_valid[i]->to_bool(), + mem_aw_bits_addr[i]->lo_word(), + mem_aw_bits_id[i]->lo_word(), + mem_aw_bits_size[i]->lo_word(), + mem_aw_bits_len[i]->lo_word(), - tile.Top__io_mem_0_w_valid.lo_word(), - tile.Top__io_mem_0_w_bits_strb.lo_word(), - tile.Top__io_mem_0_w_bits_data.values, - tile.Top__io_mem_0_w_bits_last.lo_word(), + mem_w_valid[i]->to_bool(), + mem_w_bits_strb[i]->lo_word(), + mem_w_bits_data[i]->values, + mem_w_bits_last[i]->to_bool(), - tile.Top__io_mem_0_r_ready.to_bool(), - tile.Top__io_mem_0_b_ready.to_bool() - ); + mem_r_ready[i]->to_bool(), + mem_b_ready[i]->to_bool() + ); + } if (tile.Top__io_host_clk_edge.to_bool()) { diff --git a/emulator/Makefile b/emulator/Makefile index 98e77e1b..c5601575 100644 --- a/emulator/Makefile +++ b/emulator/Makefile @@ -32,11 +32,11 @@ $(generated_dir)/%.o: $(generated_dir)/%.cpp $(generated_dir)/%.h $(generated_dir_debug)/%.o: $(generated_dir_debug)/%.cpp $(generated_dir_debug)/%.h $(CXX) $(CXXFLAGS) -I$(generated_dir_debug) -c -o $@ $< -$(addsuffix .o,$(CXXSRCS)): %.o: $(base_dir)/csrc/%.cc $(base_dir)/csrc/*.h $(generated_dir)/$(MODEL).$(CONFIG).h - $(CXX) $(CXXFLAGS) -include $(generated_dir)/$(MODEL).$(CONFIG).h -I$(generated_dir) -c -o $@ $< +$(addsuffix .o,$(CXXSRCS)): %.o: $(base_dir)/csrc/%.cc $(base_dir)/csrc/*.h $(generated_dir)/$(MODEL).$(CONFIG).h $(generated_dir)/consts.$(CONFIG).h + $(CXX) $(CXXFLAGS) -include $(generated_dir)/$(MODEL).$(CONFIG).h -include $(generated_dir)/consts.$(CONFIG).h -I$(generated_dir) -c -o $@ $< -$(addsuffix .debug.o,$(CXXSRCS)): %.debug.o: $(base_dir)/csrc/%.cc $(base_dir)/csrc/*.h $(generated_dir_debug)/$(MODEL).$(CONFIG).h - $(CXX) $(CXXFLAGS) -include $(generated_dir_debug)/$(MODEL).$(CONFIG).h -I$(generated_dir_debug) -c -o $@ $< +$(addsuffix .debug.o,$(CXXSRCS)): %.debug.o: $(base_dir)/csrc/%.cc $(base_dir)/csrc/*.h $(generated_dir_debug)/$(MODEL).$(CONFIG).h $(generated_dir_debug)/consts.$(CONFIG).h + $(CXX) $(CXXFLAGS) -include $(generated_dir_debug)/$(MODEL).$(CONFIG).h -include $(generated_dir_debug)/consts.$(CONFIG).h -I$(generated_dir_debug) -c -o $@ $< $(generated_dir)/$(MODEL).$(CONFIG).d $(generated_dir)/$(MODEL).$(CONFIG).h : $(chisel_srcs) cd $(base_dir) && $(SBT) "project $(PROJECT)" "run $(CHISEL_ARGS) --noIoDebug" @@ -44,6 +44,19 @@ $(generated_dir)/$(MODEL).$(CONFIG).d $(generated_dir)/$(MODEL).$(CONFIG).h : $( $(generated_dir_debug)/$(MODEL).$(CONFIG).h : $(chisel_srcs) cd $(base_dir) && $(SBT) "project $(PROJECT)" "run $(CHISEL_ARGS)-debug --debug --vcd --ioDebug" +$(generated_dir)/consts.$(CONFIG).h: $(generated_dir)/$(MODEL).$(CONFIG).h + echo "#ifndef __CONST_H__" > $@ + echo "#define __CONST_H__" >> $@ + sed -r 's/\(([A-Za-z0-9_]+),([A-Za-z0-9_]+)\)/#define \1 \2/' $(patsubst %.h,%.prm,$<) >> $@ + echo "#define TBFRAG \"$(MODEL).$(CONFIG).tb.cpp\"" >> $@ + echo "#endif // __CONST_H__" >> $@ + +$(generated_dir_debug)/consts.$(CONFIG).h: $(generated_dir_debug)/$(MODEL).$(CONFIG).h + echo "#ifndef __CONST_H__" > $@ + echo "#define __CONST_H__" >> $@ + sed -r 's/\(([A-Za-z0-9_]+),([A-Za-z0-9_]+)\)/#define \1 \2/' $(patsubst %.h,%.prm,$<) >> $@ + echo "#endif // __CONST_H__" >> $@ + emu = emulator-$(MODEL)-$(CONFIG) $(emu): $(generated_dir)/$(MODEL).$(CONFIG).h $(OBJS) libdramsim.a $(CXX) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) diff --git a/src/main/scala/Configs.scala b/src/main/scala/Configs.scala index 89b4c4aa..2d5fd6a9 100644 --- a/src/main/scala/Configs.scala +++ b/src/main/scala/Configs.scala @@ -280,3 +280,5 @@ class ExampleSmallConfig extends Config(new SmallConfig ++ new DefaultConfig) class MultibankConfig extends Config(new With2Banks ++ new DefaultConfig) class MultibankL2Config extends Config( new With2Banks ++ new WithL2Cache ++ new DefaultConfig) + +class MultichannelConfig extends Config(new With2MemoryChannels ++ new DefaultConfig) diff --git a/src/main/scala/TestBench.scala b/src/main/scala/TestBench.scala index 40800e18..21f75019 100644 --- a/src/main/scala/TestBench.scala +++ b/src/main/scala/TestBench.scala @@ -5,7 +5,7 @@ package rocketchip import Chisel._ object TestBenchGeneration extends FileSystemUtilities { - def generateVerilogFragement( + def generateVerilogFragment( topModuleName: String, configClassName: String, nMemChannel: Int) = { @@ -322,4 +322,47 @@ object TestBenchGeneration extends FileSystemUtilities { f.write(defs + nasti_defs + delays + nasti_delays + instantiation + ticks) f.close } + + def generateCPPFragment( + topModuleName: String, configClassName: String, nMemChannel: Int) { + + val assigns = (0 until nMemChannel).map { i => s""" + mem_ar_valid[$i] = &tile.Top__io_mem_${i}_ar_valid; + mem_ar_ready[$i] = &tile.Top__io_mem_${i}_ar_ready; + mem_ar_bits_addr[$i] = &tile.Top__io_mem_${i}_ar_bits_addr; + mem_ar_bits_id[$i] = &tile.Top__io_mem_${i}_ar_bits_id; + mem_ar_bits_size[$i] = &tile.Top__io_mem_${i}_ar_bits_size; + mem_ar_bits_len[$i] = &tile.Top__io_mem_${i}_ar_bits_len; + + mem_aw_valid[$i] = &tile.Top__io_mem_${i}_aw_valid; + mem_aw_ready[$i] = &tile.Top__io_mem_${i}_aw_ready; + mem_aw_bits_addr[$i] = &tile.Top__io_mem_${i}_aw_bits_addr; + mem_aw_bits_id[$i] = &tile.Top__io_mem_${i}_aw_bits_id; + mem_aw_bits_size[$i] = &tile.Top__io_mem_${i}_aw_bits_size; + mem_aw_bits_len[$i] = &tile.Top__io_mem_${i}_aw_bits_len; + + mem_w_valid[$i] = &tile.Top__io_mem_${i}_w_valid; + mem_w_ready[$i] = &tile.Top__io_mem_${i}_w_ready; + mem_w_bits_data[$i] = &tile.Top__io_mem_${i}_w_bits_data; + mem_w_bits_strb[$i] = &tile.Top__io_mem_${i}_w_bits_strb; + mem_w_bits_last[$i] = &tile.Top__io_mem_${i}_w_bits_last; + + mem_b_valid[$i] = &tile.Top__io_mem_${i}_b_valid; + mem_b_ready[$i] = &tile.Top__io_mem_${i}_b_ready; + mem_b_bits_resp[$i] = &tile.Top__io_mem_${i}_b_bits_resp; + mem_b_bits_id[$i] = &tile.Top__io_mem_${i}_b_bits_id; + + mem_r_valid[$i] = &tile.Top__io_mem_${i}_r_valid; + mem_r_ready[$i] = &tile.Top__io_mem_${i}_r_ready; + mem_r_bits_resp[$i] = &tile.Top__io_mem_${i}_r_bits_resp; + mem_r_bits_id[$i] = &tile.Top__io_mem_${i}_r_bits_id; + mem_r_bits_data[$i] = &tile.Top__io_mem_${i}_r_bits_data; + mem_r_bits_last[$i] = &tile.Top__io_mem_${i}_r_bits_last; + + """ }.mkString + + val f = createOutputFile(s"$topModuleName.$configClassName.tb.cpp") + f.write(assigns) + f.close + } } diff --git a/src/main/scala/Testing.scala b/src/main/scala/Testing.scala index df66abf4..96550383 100644 --- a/src/main/scala/Testing.scala +++ b/src/main/scala/Testing.scala @@ -152,7 +152,10 @@ object TestGenerator extends App with FileSystemUtilities { //Driver.elaborate(gen, configName = configClassName) TestGeneration.generateMakefrag(topModuleName, configClassName) - TestBenchGeneration.generateVerilogFragement( + TestBenchGeneration.generateVerilogFragment( + topModuleName, configClassName, + paramsFromConfig(NMemoryChannels)) + TestBenchGeneration.generateCPPFragment( topModuleName, configClassName, paramsFromConfig(NMemoryChannels))