#include #include #include #include #include #include #include #include #include "sim_vhpi_c.h" #include "Vlitedram_core.h" #include "verilated_vcd_c.h" static Vlitedram_core *v; vluint64_t main_time = 0; #if VM_TRACE VerilatedVcdC *tfp; #endif static void cleanup(void) { #if VM_TRACE if (tfp) { tfp->flush(); tfp->close(); delete tfp; } #endif } static inline void check_init(bool traces) { if (v) return; // XX Catch exceptions ? v = new Vlitedram_core; if (!v) { fprintf(stderr, "Failure allocating litedram core\n"); exit(1); } #if VM_TRACE if (traces) { // init trace dump Verilated::traceEverOn(true); tfp = new VerilatedVcdC; v->trace(tfp, 99); tfp->open("litedram.vcd"); } #endif atexit(cleanup); } unsigned char get_bit(unsigned char **p) { unsigned char b = **p; *p = *p + 1; return b == vhpi1 ? 1 : 0; } uint64_t get_bits(unsigned char **p, int len) { uint64_t r = 0; while(len--) r = (r << 1) | get_bit(p); return r; } void set_bit(unsigned char **p, int bit) { **p = bit ? vhpi1 : vhpi0; *p = *p + 1; } void set_bits(unsigned char **p, uint64_t val, int len) { while(len--) set_bit(p, (val >> len) & 1); } double sc_time_stamp(void) { return main_time; } #define check_size(s, exp) \ do { \ int __s = (s); \ int __e = (exp); \ if (__s != __e) \ fprintf(stderr, "WARNING: %s exp %d got %d\n", __func__, __e, __s); \ } while(0) static void do_eval(void) { v->eval(); #if VM_TRACE if (tfp) tfp->dump((double) main_time); #endif main_time++; } extern "C" void litedram_set_wb(unsigned char *req) { unsigned char *orig = req; check_init(false); v->wb_ctrl_cti = get_bits(&req, 3); v->wb_ctrl_bte = get_bits(&req, 2); v->wb_ctrl_sel = get_bits(&req, 4); v->wb_ctrl_we = get_bit(&req); v->wb_ctrl_stb = get_bit(&req); v->wb_ctrl_cyc = get_bit(&req); v->wb_ctrl_adr = get_bits(&req, 30); v->wb_ctrl_dat_w = get_bits(&req, 32); check_size(req - orig, 74); do_eval(); } extern "C" void litedram_get_wb(unsigned char *req) { unsigned char *orig = req; check_init(false); set_bit(&req, v->init_error); set_bit(&req, v->init_done); set_bit(&req, v->wb_ctrl_err); set_bit(&req, v->wb_ctrl_ack); set_bits(&req, v->wb_ctrl_dat_r, 32); check_size(req - orig, 36); } extern "C" void litedram_set_user(unsigned char *req) { unsigned char *orig = req; check_init(false); v->user_port_native_0_cmd_valid = get_bit(&req); v->user_port_native_0_cmd_we = get_bit(&req); v->user_port_native_0_wdata_valid = get_bit(&req); v->user_port_native_0_rdata_ready = get_bit(&req); v->user_port_native_0_cmd_addr = get_bits(&req, 24); v->user_port_native_0_wdata_we = get_bits(&req, 16); v->user_port_native_0_wdata_data[3] = get_bits(&req, 32); v->user_port_native_0_wdata_data[2] = get_bits(&req, 32); v->user_port_native_0_wdata_data[1] = get_bits(&req, 32); v->user_port_native_0_wdata_data[0] = get_bits(&req, 32); check_size(req - orig, 172); do_eval(); } extern "C" void litedram_get_user(unsigned char *req) { unsigned char *orig = req; check_init(false); set_bit(&req, v->user_port_native_0_cmd_ready); set_bit(&req, v->user_port_native_0_wdata_ready); set_bit(&req, v->user_port_native_0_rdata_valid); set_bits(&req, v->user_port_native_0_rdata_data[3], 32); set_bits(&req, v->user_port_native_0_rdata_data[2], 32); set_bits(&req, v->user_port_native_0_rdata_data[1], 32); set_bits(&req, v->user_port_native_0_rdata_data[0], 32); check_size(req - orig, 131); } extern "C" void litedram_clock(void) { check_init(false); v->clk = 1; do_eval(); v->clk = 0; do_eval(); } extern "C" void litedram_init(int trace_on) { check_init(!!trace_on); }