#ifndef __BS_PRIM_MOD_WIRE_H__ #define __BS_PRIM_MOD_WIRE_H__ #include #include "bluesim_kernel_api.h" #include "bs_module.h" #include "bs_vcd.h" // This is the definition of the Wire primitive for <= 64 bits template class MOD_Wire : public Module { public: MOD_Wire(tSimStateHdl simHdl, const char* name, Module* parent, unsigned int width, const T& v, bool is_sync_wire) : Module(simHdl, name, parent), __clk_handle_0(BAD_CLOCK_HANDLE), bits(width), value(v), isValid(false), written(false), shift_vcd(!is_sync_wire) { symbol_count = 3; symbols = new tSym[symbol_count]; symbols[0].key = ""; symbols[0].info = SYM_DEF | bits << 4; symbols[0].value = (void*)(&value); symbols[1].key = "isValid"; symbols[1].info = SYM_DEF | 1 << 4; symbols[1].value = (void*)(&isValid); symbols[2].key = "value"; symbols[2].info = SYM_DEF | bits << 4; symbols[2].value = (void*)(&value); } MOD_Wire(tSimStateHdl simHdl, const char* name, Module* parent, unsigned int width, bool is_sync_wire=false) : Module(simHdl, name, parent), __clk_handle_0(BAD_CLOCK_HANDLE), bits(width), isValid(false), written(false), shift_vcd(!is_sync_wire) { init_val(value, width); write_undet(&value, width); symbol_count = 3; symbols = new tSym[symbol_count]; symbols[0].key = ""; symbols[0].info = SYM_DEF | bits << 4; symbols[0].value = (void*)(&value); symbols[1].key = "isValid"; symbols[1].info = SYM_DEF | 1 << 4; symbols[1].value = (void*)(&isValid); symbols[2].key = "value"; symbols[2].info = SYM_DEF | bits << 4; symbols[2].value = (void*)(&value); } public: bool METH_whas() const { return isValid; } const T& METH_wget() const { return value; } void METH_wset(const T& x) { value = x; isValid = true; } // for zero-width wires void METH_wset() { isValid = true; } public: void set_clk_0(const char* s) { __clk_handle_0 = bk_get_or_define_clock(sim_hdl, s); } void clk(tUInt8 /* clock_value */, tUInt8 gate_value = 1) { written = isValid; isValid = false; } void dump_state(unsigned int indent) { printf("%*s%s = ", indent, "", inst_name); if (!written) printf("Not set"); else dump_val(value, bits); putchar('\n'); } unsigned int dump_VCD_defs(unsigned int /* num */) { vcd_num = vcd_reserve_ids(sim_hdl, 1); if (shift_vcd) vcd_set_clock(sim_hdl, vcd_num, __clk_handle_0); if (bits > 0) vcd_write_def(sim_hdl, vcd_num, inst_name, bits); else vcd_write_def(sim_hdl, vcd_num, inst_name, 1); // pulse wire return (vcd_num + 1); } void dump_VCD(tVCDDumpType dt, MOD_Wire& backing) { if (dt == VCD_DUMP_XS) vcd_write_x(sim_hdl, vcd_num, bits); else if ((dt != VCD_DUMP_CHANGES) || (written != backing.written) || (written && backing.written && (value != backing.value))) { if (bits > 0) { if (written) vcd_write_val(sim_hdl, vcd_num, value, bits); else vcd_write_x(sim_hdl, vcd_num, bits); } else { /* Pulse wires should be displayed as just the whas() value */ vcd_write_val(sim_hdl, vcd_num, written, 1); } backing.value = value; backing.written = written; } } private: tClock __clk_handle_0; unsigned int bits; T value; bool isValid; bool written; bool shift_vcd; }; #endif /* __BS_PRIM_MOD_WIRE_H__ */