diff --git a/Makefrag b/Makefrag new file mode 100644 index 00000000..c8188b7e --- /dev/null +++ b/Makefrag @@ -0,0 +1,502 @@ +# Makefile snippet used by emulator/vlsi/fpga backends + +MODEL := Top +CXX := g++ +CXXFLAGS := -O2 + +SBT := java -Xmx1024M -Xss8M -XX:MaxPermSize=128M -jar sbt-launch.jar + +#-------------------------------------------------------------------- +# Tests +#-------------------------------------------------------------------- + +# Globally installed assembly tests +global_tstdir = $(basedir)/riscv-asmtests-bmarks/riscv-tests +global_asm_tests = \ + riscv_ipi \ + riscv_add \ + riscv_addi \ + riscv_amoadd_d \ + riscv_amoadd_w \ + riscv_amoand_d \ + riscv_amoand_w \ + riscv_amoor_d \ + riscv_amoor_w \ + riscv_amoswap_d \ + riscv_amoswap_w \ + riscv_amomax_d \ + riscv_amomax_w \ + riscv_amomaxu_d \ + riscv_amomaxu_w \ + riscv_amomin_d \ + riscv_amomin_w \ + riscv_amominu_d \ + riscv_amominu_w \ + riscv_fence_i \ + riscv_sb \ + riscv_sd \ + riscv_sh \ + riscv_sw \ + riscv_addiw \ + riscv_addw \ + riscv_and \ + riscv_andi \ + riscv_beq \ + riscv_bge \ + riscv_bgeu \ + riscv_blt \ + riscv_bltu \ + riscv_bne \ + riscv_div \ + riscv_divu \ + riscv_divuw \ + riscv_divw \ + riscv_j \ + riscv_jal \ + riscv_jalr \ + riscv_jalr_j \ + riscv_jalr_r \ + riscv_lb \ + riscv_lbu \ + riscv_ld \ + riscv_lh \ + riscv_lhu \ + riscv_lui \ + riscv_lw \ + riscv_lwu \ + riscv_mul \ + riscv_mulh \ + riscv_mulhsu \ + riscv_mulhu \ + riscv_mulw \ + riscv_or \ + riscv_ori \ + riscv_rdnpc \ + riscv_rem \ + riscv_remu \ + riscv_remuw \ + riscv_remw \ + riscv_simple \ + riscv_sll \ + riscv_slli \ + riscv_slliw \ + riscv_sllw \ + riscv_slt \ + riscv_slti \ + riscv_sltiu \ + riscv_sltu \ + riscv_sra \ + riscv_srai \ + riscv_sraiw \ + riscv_sraw \ + riscv_srliw \ + riscv_srlw \ + riscv_sub \ + riscv_subw \ + riscv_xor \ + riscv_xori \ + riscv_fp_ldst \ + riscv_fp_move \ + riscv_fsgnj \ + riscv_fcmp \ + riscv_fcvt \ + riscv_fcvt_w \ + riscv_fadd \ + riscv_fmin \ + riscv_fmadd \ + riscv_fp_structural \ + +global_asm_vm_tests = \ + riscv_add_vm \ + riscv_addi_vm \ + riscv_amoadd_d_vm \ + riscv_amoadd_w_vm \ + riscv_amoand_d_vm \ + riscv_amoand_w_vm \ + riscv_amoor_d_vm \ + riscv_amoor_w_vm \ + riscv_amoswap_d_vm \ + riscv_amoswap_w_vm \ + riscv_amomax_d_vm \ + riscv_amomax_w_vm \ + riscv_amomaxu_d_vm \ + riscv_amomaxu_w_vm \ + riscv_amomin_d_vm \ + riscv_amomin_w_vm \ + riscv_amominu_d_vm \ + riscv_amominu_w_vm \ + riscv_fence_i_vm \ + riscv_sb_vm \ + riscv_sd_vm \ + riscv_sh_vm \ + riscv_sw_vm \ + riscv_addiw_vm \ + riscv_addw_vm \ + riscv_and_vm \ + riscv_andi_vm \ + riscv_beq_vm \ + riscv_bge_vm \ + riscv_bgeu_vm \ + riscv_blt_vm \ + riscv_bltu_vm \ + riscv_bne_vm \ + riscv_div_vm \ + riscv_divu_vm \ + riscv_divuw_vm \ + riscv_divw_vm \ + riscv_j_vm \ + riscv_jal_vm \ + riscv_jalr_vm \ + riscv_jalr_j_vm \ + riscv_jalr_r_vm \ + riscv_lb_vm \ + riscv_lbu_vm \ + riscv_ld_vm \ + riscv_lh_vm \ + riscv_lhu_vm \ + riscv_lui_vm \ + riscv_lw_vm \ + riscv_lwu_vm \ + riscv_mul_vm \ + riscv_mulh_vm \ + riscv_mulhsu_vm \ + riscv_mulhu_vm \ + riscv_mulw_vm \ + riscv_or_vm \ + riscv_ori_vm \ + riscv_rdnpc_vm \ + riscv_rem_vm \ + riscv_remu_vm \ + riscv_remuw_vm \ + riscv_remw_vm \ + riscv_sll_vm \ + riscv_slli_vm \ + riscv_slliw_vm \ + riscv_sllw_vm \ + riscv_slt_vm \ + riscv_slti_vm \ + riscv_sltiu_vm \ + riscv_sltu_vm \ + riscv_sra_vm \ + riscv_srai_vm \ + riscv_sraiw_vm \ + riscv_sraw_vm \ + riscv_srliw_vm \ + riscv_srlw_vm \ + riscv_sub_vm \ + riscv_subw_vm \ + riscv_xor_vm \ + riscv_xori_vm \ + riscv_fp_ldst_vm \ + riscv_fp_move_vm \ + riscv_fsgnj_vm \ + riscv_fcmp_vm \ + riscv_fcvt_vm \ + riscv_fcvt_w_vm \ + riscv_fadd_vm \ + riscv_fmin_vm \ + riscv_fmadd_vm \ + riscv_fp_structural_vm \ + +global_vecasm_tests = \ + riscv_vec_wakeup_vec \ + riscv_vec_fence_vec \ + riscv_vec_utidx_vec \ + riscv_vec_vmsv_vec \ + riscv_vec_vmvv_vec \ + riscv_vec_vfmvv_vec \ + riscv_vec_movz_vec \ + riscv_vec_movn_vec \ + riscv_vec_fmovz_vec \ + riscv_vec_fmovn_vec \ + riscv_vec_ld_vec \ + riscv_vec_lw_vec \ + riscv_vec_lwu_vec \ + riscv_vec_lh_vec \ + riscv_vec_lhu_vec \ + riscv_vec_lb_vec \ + riscv_vec_lbu_vec \ + riscv_vec_sd_vec \ + riscv_vec_sw_vec \ + riscv_vec_sh_vec \ + riscv_vec_sb_vec \ + riscv_vec_fld_vec \ + riscv_vec_flw_vec \ + riscv_vec_fsd_vec \ + riscv_vec_fsw_vec \ + riscv_vec_fcvt-d-l_vec \ + riscv_vec_vvadd_d_vec \ + riscv_vec_vvadd_fw_vec \ + riscv_vec_vvadd_fd_vec \ + riscv_vec_vvadd_w_vec \ + riscv_vec_vvmul_d_vec \ + riscv_vec_amoadd_d_vec \ + riscv_vec_amoswap_d_vec \ + riscv_vec_amoand_d_vec \ + riscv_vec_amoor_d_vec \ + riscv_vec_amomax_d_vec \ + riscv_vec_amomin_d_vec \ + riscv_vec_amomaxu_d_vec \ + riscv_vec_amominu_d_vec \ + riscv_vec_amoadd_w_vec \ + riscv_vec_amoswap_w_vec \ + riscv_vec_amoand_w_vec \ + riscv_vec_amoor_w_vec \ + riscv_vec_amomax_w_vec \ + riscv_vec_amomin_w_vec \ + riscv_vec_amomaxu_w_vec \ + riscv_vec_amominu_w_vec \ + riscv_vec_imul_vec \ + riscv_vec_fma_vec \ + riscv_mul_vec \ + riscv_mulw_vec \ + riscv_mulh_vec \ + riscv_mulhu_vec \ + riscv_mulhsu_vec \ + riscv_addi_vec \ + riscv_add_vec \ + riscv_addiw_vec \ + riscv_addw_vec \ + riscv_and_vec \ + riscv_andi_vec \ + riscv_lui_vec \ + riscv_or_vec \ + riscv_ori_vec \ + riscv_slt_vec \ + riscv_sltu_vec \ + riscv_slti_vec \ + riscv_sltiu_vec \ + riscv_slli_vec \ + riscv_sll_vec \ + riscv_slliw_vec \ + riscv_sllw_vec \ + riscv_srai_vec \ + riscv_sra_vec \ + riscv_sraiw_vec \ + riscv_sraw_vec \ + riscv_srli_vec \ + riscv_srl_vec \ + riscv_srliw_vec \ + riscv_srlw_vec \ + riscv_sub_vec \ + riscv_subw_vec \ + riscv_xor_vec \ + riscv_xori_vec \ + riscv_fadd_vec \ + riscv_fsgnj_vec \ + riscv_fmin_vec \ + riscv_fmadd_vec \ + riscv_fcvt_w_vec \ + riscv_fcvt_vec \ + riscv_fcmp_vec \ + riscv_vec_xcpt_ma_inst \ + riscv_vec_xcpt_illegal \ + riscv_vec_xcpt_illegal_vt_regid \ + riscv_vec_xcpt_illegal_tvec_regid \ + riscv_vec_ma_vld \ + riscv_vec_ma_vsd \ + riscv_vec_ma_utld \ + riscv_vec_ma_utsd \ + riscv_vec_illegal_tvec \ + +global_vecasm_vm_tests = \ + riscv_vec_wakeup_vec_vm \ + riscv_vec_fence_vec_vm \ + riscv_vec_utidx_vec_vm \ + riscv_vec_vmsv_vec_vm \ + riscv_vec_vmvv_vec_vm \ + riscv_vec_vfmvv_vec_vm \ + riscv_vec_movz_vec_vm \ + riscv_vec_movn_vec_vm \ + riscv_vec_fmovz_vec_vm \ + riscv_vec_fmovn_vec_vm \ + riscv_vec_ld_vec_vm \ + riscv_vec_lw_vec_vm \ + riscv_vec_lwu_vec_vm \ + riscv_vec_lh_vec_vm \ + riscv_vec_lhu_vec_vm \ + riscv_vec_lb_vec_vm \ + riscv_vec_lbu_vec_vm \ + riscv_vec_sd_vec_vm \ + riscv_vec_sw_vec_vm \ + riscv_vec_sh_vec_vm \ + riscv_vec_sb_vec_vm \ + riscv_vec_fld_vec_vm \ + riscv_vec_flw_vec_vm \ + riscv_vec_fsd_vec_vm \ + riscv_vec_fsw_vec_vm \ + riscv_vec_fcvt-d-l_vec_vm \ + riscv_vec_vvadd_d_vec_vm \ + riscv_vec_vvadd_fw_vec_vm \ + riscv_vec_vvadd_fd_vec_vm \ + riscv_vec_vvadd_w_vec_vm \ + riscv_vec_vvmul_d_vec_vm \ + riscv_vec_amoadd_d_vec_vm \ + riscv_vec_amoswap_d_vec_vm \ + riscv_vec_amoand_d_vec_vm \ + riscv_vec_amoor_d_vec_vm \ + riscv_vec_amomax_d_vec_vm \ + riscv_vec_amomin_d_vec_vm \ + riscv_vec_amomaxu_d_vec_vm \ + riscv_vec_amominu_d_vec_vm \ + riscv_vec_amoadd_w_vec_vm \ + riscv_vec_amoswap_w_vec_vm \ + riscv_vec_amoand_w_vec_vm \ + riscv_vec_amoor_w_vec_vm \ + riscv_vec_amomax_w_vec_vm \ + riscv_vec_amomin_w_vec_vm \ + riscv_vec_amomaxu_w_vec_vm \ + riscv_vec_amominu_w_vec_vm \ + riscv_vec_imul_vec_vm \ + riscv_vec_fma_vec_vm \ + riscv_mul_vec_vm \ + riscv_mulw_vec_vm \ + riscv_mulh_vec_vm \ + riscv_mulhu_vec_vm \ + riscv_mulhsu_vec_vm \ + riscv_addi_vec_vm \ + riscv_add_vec_vm \ + riscv_addiw_vec_vm \ + riscv_addw_vec_vm \ + riscv_and_vec_vm \ + riscv_andi_vec_vm \ + riscv_lui_vec_vm \ + riscv_or_vec_vm \ + riscv_ori_vec_vm \ + riscv_slt_vec_vm \ + riscv_sltu_vec_vm \ + riscv_slti_vec_vm \ + riscv_sltiu_vec_vm \ + riscv_slli_vec_vm \ + riscv_sll_vec_vm \ + riscv_slliw_vec_vm \ + riscv_sllw_vec_vm \ + riscv_srai_vec_vm \ + riscv_sra_vec_vm \ + riscv_sraiw_vec_vm \ + riscv_sraw_vec_vm \ + riscv_srli_vec_vm \ + riscv_srl_vec_vm \ + riscv_srliw_vec_vm \ + riscv_srlw_vec_vm \ + riscv_sub_vec_vm \ + riscv_subw_vec_vm \ + riscv_xor_vec_vm \ + riscv_xori_vec_vm \ + riscv_fadd_vec_vm \ + riscv_fsgnj_vec_vm \ + riscv_fmin_vec_vm \ + riscv_fmadd_vec_vm \ + riscv_fcvt_w_vec_vm \ + riscv_fcvt_vec_vm \ + riscv_fcmp_vec_vm \ + +global_vecasm_timer_tests = \ + riscv_vec_wakeup_vec_timer \ + riscv_vec_fence_vec_timer \ + riscv_vec_vvadd_d_vec_timer \ + riscv_vec_vvadd_fw_vec_timer \ + riscv_vec_vvadd_fd_vec_timer \ + riscv_vec_vvadd_w_vec_timer \ + riscv_vec_vvmul_d_vec_timer \ + riscv_vec_fcvt-d-l_vec_timer \ + riscv_vec_utidx_vec_timer \ + riscv_vec_vmvv_vec_timer \ + riscv_vec_vmsv_vec_timer \ + riscv_vec_vfmvv_vec_timer \ + riscv_vec_movz_vec_timer \ + riscv_vec_movn_vec_timer \ + riscv_vec_fmovz_vec_timer \ + riscv_vec_fmovn_vec_timer \ + riscv_vec_ld_vec_timer \ + riscv_vec_lw_vec_timer \ + riscv_vec_lwu_vec_timer \ + riscv_vec_lh_vec_timer \ + riscv_vec_lhu_vec_timer \ + riscv_vec_lb_vec_timer \ + riscv_vec_lbu_vec_timer \ + riscv_vec_sd_vec_timer \ + riscv_vec_sw_vec_timer \ + riscv_vec_sh_vec_timer \ + riscv_vec_sb_vec_timer \ + riscv_vec_fld_vec_timer \ + riscv_vec_flw_vec_timer \ + riscv_vec_fsd_vec_timer \ + riscv_vec_fsw_vec_timer \ + riscv_vec_amoadd_d_vec_timer \ + riscv_vec_amoswap_d_vec_timer \ + riscv_vec_amoand_d_vec_timer \ + riscv_vec_amoor_d_vec_timer \ + riscv_vec_amomax_d_vec_timer \ + riscv_vec_amomin_d_vec_timer \ + riscv_vec_amomaxu_d_vec_timer \ + riscv_vec_amominu_d_vec_timer \ + riscv_vec_amoadd_w_vec_timer \ + riscv_vec_amoswap_w_vec_timer \ + riscv_vec_amoand_w_vec_timer \ + riscv_vec_amoor_w_vec_timer \ + riscv_vec_amomax_w_vec_timer \ + riscv_vec_amomin_w_vec_timer \ + riscv_vec_amomaxu_w_vec_timer \ + riscv_vec_amominu_w_vec_timer \ + riscv_vec_imul_vec_timer \ + riscv_vec_fma_vec_timer \ + riscv_mul_vec_timer \ + riscv_mulw_vec_timer \ + riscv_mulh_vec_timer \ + riscv_mulhu_vec_timer \ + riscv_mulhsu_vec_timer \ + riscv_addi_vec_timer \ + riscv_add_vec_timer \ + riscv_addiw_vec_timer \ + riscv_addw_vec_timer \ + riscv_and_vec_timer \ + riscv_andi_vec_timer \ + riscv_lui_vec_timer \ + riscv_or_vec_timer \ + riscv_ori_vec_timer \ + riscv_slt_vec_timer \ + riscv_sltu_vec_timer \ + riscv_slti_vec_timer \ + riscv_sltiu_vec_timer \ + riscv_slli_vec_timer \ + riscv_sll_vec_timer \ + riscv_slliw_vec_timer \ + riscv_sllw_vec_timer \ + riscv_srai_vec_timer \ + riscv_sra_vec_timer \ + riscv_sraiw_vec_timer \ + riscv_sraw_vec_timer \ + riscv_srli_vec_timer \ + riscv_srl_vec_timer \ + riscv_srliw_vec_timer \ + riscv_srlw_vec_timer \ + riscv_sub_vec_timer \ + riscv_subw_vec_timer \ + riscv_xor_vec_timer \ + riscv_xori_vec_timer \ + riscv_fadd_vec_timer \ + riscv_fsgnj_vec_timer \ + riscv_fmin_vec_timer \ + riscv_fmadd_vec_timer \ + riscv_fcvt_w_vec_timer \ + riscv_fcvt_vec_timer \ + riscv_fcmp_vec_timer \ + +# Globally installed benchmarks + +global_bmarkdir = $(basedir)/riscv-asmtests-bmarks/riscv-bmarks +global_bmarks = \ + median.riscv \ + multiply.riscv \ + qsort.riscv \ + towers.riscv \ + vvadd.riscv \ + dgemm.riscv \ + +global_vec_bmarkdir = $(basedir)/../../riscv-app/misc/build +global_vec_bmarks = \ + ubmark-vvadd \ + ubmark-bin-search \ + ubmark-cmplx-mult \ + ubmark-masked-filter \ diff --git a/csrc/emulator.cc b/csrc/emulator.cc new file mode 100644 index 00000000..b6c22c4e --- /dev/null +++ b/csrc/emulator.cc @@ -0,0 +1,218 @@ +#include "htif_phy.h" +#include +#include +#include +#include +#include "common.h" +#include "emulator.h" +#include "mm_emulator.cc" +#include "Top.h" // chisel-generated code... +#include "disasm.h" + +int main(int argc, char** argv) +{ + int fromhost_fd = -1, tohost_fd = -1; + unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid(); + uint64_t max_cycles = 0; + uint64_t trace_count = 0; + int start = 0; + bool log = false; + bool quiet = false; + const char* vcd = NULL; + const char* loadmem = NULL; + FILE *vcdfile = NULL, *logfile = stderr; + const char* failure = NULL; + + // for disassembly + disassembler disasm; + char if_inst_str[1024]; + char id_inst_str[1024]; + char ex_inst_str[1024]; + char mem_inst_str[1024]; + char wb_inst_str[1024]; + + // used to register values from EX stage for trace + uint64_t mem_reg_raddr1 = 0, mem_reg_raddr2 = 0; + uint64_t wb_reg_raddr1 = 0, wb_reg_raddr2 = 0; + uint64_t mem_reg_rs1 = 0, mem_reg_rs2 = 0, mem_reg_inst = 0, ex_reg_inst = 0; + uint64_t wb_reg_rs1 = 0, wb_reg_rs2 = 0, wb_reg_inst = 0; + uint64_t id_icache_miss = 0, if_icache_req = 0, id_itlb_miss = 0; + + for (int i = 1; i < argc; i++) + { + std::string arg = argv[i]; + if (arg == "-l") + log = true; + else if (arg == "-q") + quiet = true; + else if (arg.substr(0, 2) == "-v") + vcd = argv[i]+2; + else if (arg.substr(0, 2) == "-m") + max_cycles = atoll(argv[i]+2); + else if (arg.substr(0, 2) == "-s") + random_seed = atoi(argv[i]+2); + else if (arg.substr(0, 10) == "+fromhost=") + fromhost_fd = atoi(argv[i]+10); + else if (arg.substr(0, 8) == "+tohost=") + tohost_fd = atoi(argv[i]+8); + else if (arg.substr(0, 9) == "+loadmem=") + loadmem = argv[i]+9; + else + { + fprintf(stderr, "unknown option: %s\n", argv[i]); + exit(1); + } + } + + demand(fcntl(fromhost_fd,F_GETFD) >= 0, "fromhost file not open"); + demand(fcntl(tohost_fd,F_GETFD) >= 0, "tohost file not open"); + + if (vcd) + { + // Create a VCD file + vcdfile = strcmp(vcd, "-") == 0 ? stdout : fopen(vcd, "w"); + assert(vcdfile); + fprintf(vcdfile, "$scope module Testbench $end\n"); + fprintf(vcdfile, "$var reg 256 NDISASM_IF if_instruction $end\n"); + fprintf(vcdfile, "$var reg 256 NDISASM_ID id_instruction $end\n"); + fprintf(vcdfile, "$var reg 256 NDISASM_EX ex_instruction $end\n"); + fprintf(vcdfile, "$var reg 256 NDISASM_MEM mem_instruction $end\n"); + fprintf(vcdfile, "$var reg 16 NCYCLE cycle $end\n"); + fprintf(vcdfile, "$upscope $end\n"); + } + + // basic fixed latency memory model + uint64_t* mem = mm_init(); + if (loadmem != NULL) + load_mem(mem, loadmem); + + // The chisel generated code + Top_t tile; + srand(random_seed); + tile.init(random_seed != 0); + + // reset for a few cycles to support pipelined reset + tile.Top__io_host_in_valid = LIT<1>(0); + tile.Top__io_host_out_ready = LIT<1>(0); + for (int i = 0; i < 10; i++) + { + tile.clock_lo(LIT<1>(1)); + tile.clock_hi(LIT<1>(1)); + } + + htif_phy_t htif_phy(tile.Top__io_host_in_bits.width(), fromhost_fd, tohost_fd); + + while (max_cycles == 0 || trace_count < max_cycles) + { + // memory model + mm_tick_emulator ( + tile.Top__io_mem_req_cmd_valid.lo_word(), + &tile.Top__io_mem_req_cmd_ready.values[0], + tile.Top__io_mem_req_cmd_bits_rw.lo_word(), + tile.Top__io_mem_req_cmd_bits_addr.lo_word(), + tile.Top__io_mem_req_cmd_bits_tag.lo_word(), + + tile.Top__io_mem_req_data_valid.lo_word(), + &tile.Top__io_mem_req_data_ready.values[0], + &tile.Top__io_mem_req_data_bits_data.values[0], + + &tile.Top__io_mem_resp_valid.values[0], + &tile.Top__io_mem_resp_bits_tag.values[0], + &tile.Top__io_mem_resp_bits_data.values[0] + ); + + tile.Top__io_host_in_valid = LIT<1>(htif_phy.in_valid()); + tile.Top__io_host_in_bits = LIT<64>(htif_phy.in_bits()); + tile.Top__io_host_out_ready = LIT<1>(htif_phy.out_ready()); + + tile.clock_lo(LIT<1>(0)); + + htif_phy.tick(tile.Top__io_host_in_ready.lo_word(), + tile.Top__io_host_out_valid.lo_word(), + tile.Top__io_host_out_bits.lo_word()); + + + if (tile.Top__io_debug_error_mode.lo_word()) + { + failure = "entered error mode"; + break; + } + + if (log || (quiet && trace_count % 10000 == 0)) + { + insn_t insn; + insn.bits = wb_reg_inst; + strcpy(wb_inst_str, disasm.disassemble(insn).c_str()); + + fprintf(logfile, "C: %10lld [%ld] pc=[%011lx] W[r%2ld=%016lx][%ld] R[r%2ld=%016lx] R[r%2ld=%016lx] inst=[%08lx] %-32s\n", \ + (long long)trace_count, tile.Top_Tile_cpu_ctrl__wb_reg_valid.lo_word(), tile.Top_Tile_cpu_dpath__wb_reg_pc.lo_word(), \ + tile.Top_Tile_cpu_dpath_rfile__io_w0_addr.lo_word(), tile.Top_Tile_cpu_dpath_rfile__io_w0_data.lo_word(), tile.Top_Tile_cpu_dpath_rfile__io_w0_en.lo_word(), + wb_reg_raddr1, wb_reg_rs1, wb_reg_raddr2, wb_reg_rs2, wb_reg_inst, wb_inst_str); + } + + if (vcd) + { + tile.dump(vcdfile, trace_count); // dump all signals to vcd + + #define dump_disasm(inst, name) do { \ + insn_t insn; \ + insn.bits = inst; \ + std::string dasm = disasm.disassemble(insn); \ + int namelen = strlen(name), pos = 0; \ + char str[1 + dasm.length()*8 + 1 + namelen + 1 + 1]; \ + str[pos++] = 'b'; \ + for (size_t i = 0; i < dasm.length()*8; i++) \ + str[pos++] = ((dasm[i/8] >> (7-(i%8))) & 1) + '0'; \ + str[pos++] = ' '; \ + memcpy(str + pos, name, namelen); pos += namelen; \ + str[pos++] = '\n'; \ + str[pos] = 0; \ + fputs(str, vcdfile); \ + } while(0) + dump_disasm(tile.Top_Tile_cpu_dpath__id_reg_inst_shadow.lo_word(), "NDISASM_IF"); + dump_disasm(tile.Top_Tile_cpu_dpath__id_reg_inst.lo_word(), "NDISASM_ID"); + dump_disasm(ex_reg_inst, "NDISASM_EX"); + dump_disasm(mem_reg_inst, "NDISASM_MEM"); + + dat_dump(vcdfile, dat_t<64>(trace_count), "NCYCLE\n"); + } + + // delay values from ex stage for trace output on the following cycle + wb_reg_inst = mem_reg_inst; + wb_reg_raddr1 = mem_reg_raddr1; + wb_reg_raddr2 = mem_reg_raddr2; + wb_reg_rs1 = mem_reg_rs1; + wb_reg_rs2 = mem_reg_rs2; + + mem_reg_inst = ex_reg_inst; + mem_reg_raddr1 = (mem_reg_inst >> 22) & 0x1f; + mem_reg_raddr2 = (mem_reg_inst >> 17) & 0x1f; + mem_reg_rs1 = tile.Top_Tile_cpu_dpath__ex_reg_rs1.lo_word(); + mem_reg_rs2 = tile.Top_Tile_cpu_dpath__ex_reg_rs2.lo_word(); + + ex_reg_inst = tile.Top_Tile_cpu_dpath__id_reg_inst.lo_word(); + + tile.clock_hi(LIT<1>(0)); + trace_count++; + + if (trace_count == max_cycles) + { + failure = "timeout"; + break; + } + } + + if (vcd) + fclose(vcdfile); + + if (failure) + { + fprintf(logfile, "*** FAILED *** (%s) after %lld cycles\n", failure, (long long)trace_count); + return -1; + } + + close(tohost_fd); + close(fromhost_fd); + + return 0; +} diff --git a/csrc/vcs_main.cc b/csrc/vcs_main.cc new file mode 100644 index 00000000..594c4c63 --- /dev/null +++ b/csrc/vcs_main.cc @@ -0,0 +1,112 @@ +#include "mm_model.h" +#include "htif_phy.h" +#include "mm_types.h" +#include "mm_emulator.cc" +#include + +htif_phy_t* htif_phy = NULL; + +extern "C" { + +void memory_tick( + vc_handle mem_req_val, + vc_handle mem_req_rdy, + vc_handle mem_req_store, + vc_handle mem_req_addr, + vc_handle mem_req_tag, + + vc_handle mem_req_data_val, + vc_handle mem_req_data_rdy, + vc_handle mem_req_data_bits, + + vc_handle mem_resp_val, + vc_handle mem_resp_tag, + vc_handle mem_resp_data) +{ + uint64_t req_data[MM_WORD_SIZE*refill_size/sizeof(uint64_t)]; + for (size_t i = 0; i < MM_WORD_SIZE*refill_size/sizeof(uint32_t); i++) + ((uint32_t*)req_data)[i] = vc_4stVectorRef(mem_req_data_bits)[i].d; + + uint64_t req_rdy, req_data_rdy, resp_val, resp_tag; + uint64_t resp_data[MM_WORD_SIZE*refill_size/sizeof(uint64_t)]; + + mm_tick_emulator( + vc_getScalar(mem_req_val), + &req_rdy, + vc_getScalar(mem_req_store), + vc_4stVectorRef(mem_req_addr)->d, + vc_4stVectorRef(mem_req_tag)->d, + + vc_getScalar(mem_req_data_val), + &req_data_rdy, + req_data, + + &resp_val, + &resp_tag, + resp_data + ); + + vc_putScalar(mem_req_rdy, req_rdy); + vc_putScalar(mem_req_data_rdy, req_data_rdy); + vc_putScalar(mem_resp_val, resp_val); + + vec32 t; + t.c = 0; + t.d = resp_tag; + vc_put4stVector(mem_resp_tag, &t); + + vec32 d[MM_WORD_SIZE*refill_size/sizeof(uint32_t)]; + for (size_t i = 0; i < MM_WORD_SIZE*refill_size/sizeof(uint32_t); i++) + { + d[i].c = 0; + d[i].d = ((uint32_t*)resp_data)[i]; + } + vc_put4stVector(mem_resp_data, d); +} + +void htif_init +( + vc_handle fromhost, + vc_handle tohost, + vc_handle width, + vc_handle loadmem +) +{ + uint64_t* mem = mm_init(); + + vec32* fh = vc_4stVectorRef(fromhost); + vec32* th = vc_4stVectorRef(tohost); + vec32* w = vc_4stVectorRef(width); + + char loadmem_str[1024]; + vc_VectorToString(loadmem, loadmem_str); + if (*loadmem_str) + load_mem(mem, loadmem_str); + + assert(w->d <= 32); // htif_tick assumes data fits in a vec32 + htif_phy = new htif_phy_t(w->d, fh->d, th->d); +} + +void htif_tick +( + vc_handle htif_in_valid, + vc_handle htif_in_ready, + vc_handle htif_in_bits, + vc_handle htif_out_valid, + vc_handle htif_out_ready, + vc_handle htif_out_bits +) +{ + vec32* ob = vc_4stVectorRef(htif_out_bits); + htif_phy->tick(vc_getScalar(htif_in_ready), vc_getScalar(htif_out_valid), ob->d); + + vc_putScalar(htif_in_valid, htif_phy->in_valid()); + vc_putScalar(htif_out_ready, htif_phy->out_ready()); + + vec32 ib; + ib.c = 0; + ib.d = htif_phy->in_bits(); + vc_put4stVector(htif_in_bits, &ib); +} + +} diff --git a/emulator/.gitignore b/emulator/.gitignore new file mode 100644 index 00000000..928c1ccd --- /dev/null +++ b/emulator/.gitignore @@ -0,0 +1,11 @@ +*~ +*.o +*.out +*.vcd +*.vpd +*.log +emulator +generated-src +emulator-debug +generated-src-debug +kernel diff --git a/emulator/Makefile b/emulator/Makefile new file mode 100644 index 00000000..1c1d4657 --- /dev/null +++ b/emulator/Makefile @@ -0,0 +1,111 @@ +basedir = .. +include ../Makefrag + +CXX := g++ +CXXFLAGS := -O1 + +all: emulator + +CXXSRCS := emulator disasm +CXXFLAGS := $(CXXFLAGS) -Itestbench -I$(basedir)/chisel/csrc + +generated-src/$(MODEL).cpp: $(basedir)/riscv-rocket/src/*.scala $(basedir)/riscv-hwacha/src/*.scala $(basedir)/chisel/src/main/scala/* $(basedir)/uncore/src/*.scala + cd $(basedir)/sbt && $(SBT) "project rocket" "run rocket.Top --backend c --noIoDebug --targetDir ../emulator/generated-src" + +generated-src-debug/$(MODEL).cpp: $(basedir)/riscv-rocket/src/*.scala $(basedir)/riscv-hwacha/src/*.scala $(basedir)/chisel/src/main/scala/* $(basedir)/uncore/src/*.scala + cd $(basedir)/sbt && $(SBT) "project rocket" "run rocket.Top --backend c --debug --vcd --targetDir ../emulator/generated-src-debug" + +$(MODEL).o: %.o: generated-src/%.cpp + $(CXX) $(CXXFLAGS) -Igenerated-src -c -o $@ $< + +$(MODEL)-debug.o: %-debug.o: generated-src-debug/%.cpp + $(CXX) $(CXXFLAGS) -Igenerated-src-debug -c -o $@ $< + +$(addsuffix .o,$(CXXSRCS)): %.o: testbench/%.cc testbench/* generated-src/$(MODEL).cpp + $(CXX) $(CXXFLAGS) -Igenerated-src -c -o $@ $< + +$(addsuffix -debug.o,$(CXXSRCS)): %-debug.o: testbench/%.cc testbench/* generated-src-debug/$(MODEL).cpp + $(CXX) $(CXXFLAGS) -Igenerated-src-debug -c -o $@ $< + +emulator: $(addsuffix .o,$(CXXSRCS)) $(MODEL).o + $(CXX) $(CXXFLAGS) -o $@ $^ + +emulator-debug: $(addsuffix -debug.o,$(CXXSRCS)) $(MODEL)-debug.o + $(CXX) $(CXXFLAGS) -o $@ $^ + +all: emulator + +clean: + rm -rf *.o emulator emulator-debug generated-src generated-src-debug DVEfiles + +#-------------------------------------------------------------------- +# Run assembly tests and benchmarks +#-------------------------------------------------------------------- + +global_asm_tests_out = $(addsuffix .out, $(global_asm_tests) $(global_asm_vm_tests)) +global_vecasm_tests_out = $(addsuffix .out, $(global_vecasm_tests) $(global_vecasm_vm_tests)) +global_vecasm_timer_tests_out = $(addsuffix .out, $(global_vecasm_timer_tests)) +global_bmarks_out = $(addsuffix .out, $(global_bmarks)) +global_asm_tests_vpd = $(addsuffix .vpd, $(global_asm_tests)) +global_vecasm_tests_vpd = $(addsuffix .vpd, $(global_vecasm_tests)) +global_vecasm_timer_tests_vpd = $(addsuffix .vpd, $(global_vecasm_timer_tests)) +global_bmarks_vpd = $(addsuffix .vpd, $(global_bmarks)) + +$(global_asm_tests_out): %.out: $(global_tstdir)/%.hex emulator + fesvr -c -testrun -m1000000 -l +loadmem=$< none 2> $@ + +$(global_vecasm_tests_out): %.out: $(global_tstdir)/%.hex emulator + fesvr -c -testrun -m1000000 -l +loadmem=$< none 2> $@ + +$(global_vecasm_timer_tests_out): %.out: $(global_tstdir)/%.hex emulator + fesvr -c -testrun -m3000000 -l +loadmem=$< none 2> $@ + +$(global_bmarks_out): %.out: $(global_bmarkdir)/%.hex emulator + fesvr -c -testrun -m1000000 -l +loadmem=$< none 2> $@ + +$(global_asm_tests_vpd): %.vpd: $(global_tstdir)/%.hex emulator-debug + fesvr -c./emulator-debug -testrun -m1000000 -l -v- +loadmem=$< none 2> $(patsubst %.vpd,%.out,$@) | vcd2vpd - $@ > /dev/null + +$(global_vecasm_tests_vpd): %.vpd: $(global_tstdir)/%.hex emulator-debug + fesvr -c./emulator-debug -testrun -m1000000 -l -v- +loadmem=$< none 2> $(patsubst %.vpd,%.out,$@) | vcd2vpd - $@ > /dev/null + +$(global_vecasm_timer_tests_vpd): %.vpd: $(global_tstdir)/%.hex emulator-debug + fesvr -c./emulator-debug -testrun -m3000000 -l -v- +loadmem=$< none 2> $(patsubst %.vpd,%.out,$@) | vcd2vpd - $@ > /dev/null + +$(global_bmarks_vpd): %.vpd: $(global_bmarkdir)/%.hex emulator-debug + fesvr -c./emulator-debug -testrun -m1000000 -l -v- +loadmem=$< none 2> $(patsubst %.vpd,%.out,$@) | vcd2vpd - $@ > /dev/null + +run-asm-tests: $(global_asm_tests_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_asm_tests_out); echo; + +run-vecasm-tests: $(global_vecasm_tests_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_vecasm_tests_out); echo; + +run-vecasm-timer-tests: $(global_vecasm_timer_tests_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_vecasm_timer_tests_out); echo; + +run-bmarks-test: $(global_bmarks_out) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_bmarks_out); echo; + +run-asm-tests-debug: $(global_asm_tests_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_asm_tests_out); echo; + +run-vecasm-tests-debug: $(global_vecasm_tests_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_vecasm_tests_out); echo; + +run-vecasm-timer-tests-debug: $(global_vecasm_timer_tests_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_vecasm_timer_tests_out); echo; + +run-bmarks-test-debug: $(global_bmarks_vpd) + @echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \ + $(global_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 diff --git a/project/build.scala b/project/build.scala new file mode 100644 index 00000000..f9e92199 --- /dev/null +++ b/project/build.scala @@ -0,0 +1,25 @@ +import sbt._ +import Keys._ + +object BuildSettings { + val buildOrganization = "berkeley" + val buildVersion = "1.1" + val buildScalaVersion = "2.9.2" + + val buildSettings = Defaults.defaultSettings ++ Seq ( + //unmanagedBase <<= baseDirectory { base => base / ".." / custom_lib" }, + organization := buildOrganization, + version := buildVersion, + scalaVersion := buildScalaVersion + ) +} + +object ChiselBuild extends Build{ + import BuildSettings._ + + lazy val chisel = Project("chisel", file("chisel"), settings = buildSettings) + lazy val hardfloat = Project("hardfloat", file("hardfloat"), settings = buildSettings) dependsOn(chisel) + lazy val hwacha = Project("hwacha", file("hwacha"), settings = buildSettings) dependsOn(hardfloat,chisel) + lazy val uncore = Project("uncore", file("uncore"), settings = buildSettings) dependsOn(chisel) + lazy val rocket = Project("rocket", file("rocket"), settings = buildSettings) dependsOn(uncore,hwacha,hardfloat,chisel) +} diff --git a/sbt-launch.jar b/sbt-launch.jar new file mode 100644 index 00000000..070ecb01 Binary files /dev/null and b/sbt-launch.jar differ