#pragma once #include namespace SIM{ enum STATE{ HIGH = 1, LOW = 0, Z = -1 }; class Component{ public: Component(std::string n){ name = n;} std::string name; virtual STATE genOutput() = 0; }; class And: Component{ public: And(std::string n) : Component(n){}; void setOutput(Component * o){ out = o; } void addInput(Component * o){ inputs.push_back(o); } STATE genOutput(){ for(std::vector::iterator i = inputs.begin(); i < inputs.end(); ++i){ if((*i)->genOutput() != HIGH){ return LOW; } if((*i)->genOutput() == Z){ std::cerr << "High Z input on AND" << std::endl; } } return HIGH; } private: Component * out; std::vector inputs; }; class Or: Component{ public: Or(std::string n) : Component(n){}; void setOutput(Component * o){ out = o; } void addInput(Component * o){ inputs.push_back(o); } STATE genOutput(){ for(std::vector::iterator i = inputs.begin(); i < inputs.end(); ++i){ if((*i)->genOutput() == HIGH){ return HIGH; } if((*i)->genOutput() == Z){ std::cerr << "High Z input on OR" << std::endl; } } return LOW; } private: Component * out; std::vector inputs; }; class Xor: Component{ public: Xor(std::string n) : Component(n){}; void setOutput(Component * o){ out = o; } void addInput(Component * o){ inputs.push_back(o); } STATE genOutput(){ int high_count = 0; for(std::vector::iterator i = inputs.begin(); i < inputs.end(); ++i){ if((*i)->genOutput() == HIGH){ ++high_count; } if((*i)->genOutput() == Z){ std::cerr << "High Z input on XOR" << std::endl; } } return high_count%2?HIGH:LOW; } private: Component * out; std::vector inputs; }; class Not: Component{ public: Not(std::string n) : Component(n){}; void setOutput(Component * o){ out = o; } void setInput(Component * i){ in = i; } STATE genOutput(){ if(in->genOutput() == HIGH){ return LOW; } else { if((in)->genOutput() == Z){ std::cerr << "High Z input on NOT" << std::endl; } return HIGH; } } private: Component * out; Component * in; }; class One: Component{ public: One(std::string n) : Component(n){}; STATE genOutput(){ return HIGH; } }; class Zero: Component{ public: Zero(std::string n) : Component(n){}; STATE genOutput(){ return LOW; } }; class Dff: Component{ private: Component * out; Component * in; STATE q; STATE d; bool done_for_cycle; public: Dff(std::string n) : Component(n) { q = LOW; d = LOW; done_for_cycle = false; } Dff() : Component("") { q = LOW; d = LOW; done_for_cycle = false; } STATE genOutput(){ if(!done_for_cycle){ done_for_cycle = true; d = in->genOutput(); if(d == Z){ std::cerr << "HighZ on Dff input" << std::endl; } } return q; } void setOutput(Component * o){ out = o; } void setInput(Component * i){ in = i; } void clock(){ q = d; done_for_cycle = false; } }; class Tris: Component{ private: Component * out; Component * in; Component * en; public: Tris(std::string n) : Component(n){}; STATE genOutput(){ STATE out = in->genOutput(); STATE enable = en->genOutput(); if(out == Z){ std::cerr << "HighZ on Tris input" << std::endl; } if(enable == Z){ std::cerr << "HighZ on Tris enable" << std::endl; } if(enable == LOW){ return Z; } else { return out; } } void setOutput(Component * o){ out = o; } void setInput(Component * i){ in = i; } void setEnable(Component * i){ en = i; } }; class Input: Component{ private: std::vector states; std::vector::iterator i; public: Input(std::string n) : Component(n){}; STATE genOutput(){ return *i; } void clock(){ if(i < states.end()){ ++i; } } void add_state(STATE st){ states.push_back(st); i = states.begin(); } }; class Lut: Component{ private: std::vector states; std::vector address_lines; public: Lut(std::string n) : Component(n){}; STATE genOutput(){ unsigned long index = 0; int shift_index = 0; for(std::vector::iterator c = address_lines.begin(); c < address_lines.end(); ++c){ index += ((*c)->genOutput() == HIGH)?1<=0 && indexinputs; bool isComplete(){ return done; } void complete(){ done = true; } }; std::vector pins; std::ofstream * output_file; public: Output(std::string n, std::string filename_base): Component(n){ name = n; std::string filename = filename_base + "."+n+".evl_output"; output_file = new std::ofstream(filename.c_str()); if(!output_file){ abort(); } init=false; } void add_component(std::string pin, Component * c){ for(std::vector::iterator p = pins.begin(); p < pins.end(); ++p){ if(!((p->name).compare(pin)) and !p->isComplete()){ (p->inputs).push_back(c); return; } } pins.push_back(Pin(pin, c)); } void complete_pin(std::string pin){ for(std::vector::iterator p = pins.begin(); p < pins.end(); ++p){ if(!((p->name).compare(pin)) and !p->isComplete()){ p->complete(); return; } } } STATE genOutput(){ if(init == false){ init = true; *output_file << pins.size() << "\n"; for(std::vector::iterator p = pins.begin(); p < pins.end(); ++p){ *output_file << p->inputs.size() << "\n"; } output_file->flush(); } for(std::vector::iterator p = pins.begin(); p < pins.end(); ++p){ std::vector::iterator c = p->inputs.end() -1; uint8_t hex_conv = 0; uint8_t hex_index = 0; switch(p->inputs.size() % 4){ case 1: hex_index = 0; break; case 2: hex_index = 1; break; case 3: hex_index = 2; break; case 0: hex_index = 3; break; } while(c >= p->inputs.begin()){ STATE pinout = (*c)->genOutput(); if(pinout == Z){ std::cerr << "HighZ on output" << std::endl; } hex_conv |= (pinout == HIGH)?(1<flush(); return HIGH; } }; class Buffer: Component{ private: Component * in; Component * out; public: Buffer(std::string n) : Component(n){} void setInput(Component * i){ in = i; } void setOutput(Component * o){ out = o; } STATE genOutput(){ return in->genOutput(); } }; class Wire: Component{ private: bool cached; STATE cached_state; int position; std::vector listeners; std::vector drivers; public: Wire(std::string name, int p) : Component(name){ position = p; cached = false; } void addListener(Component * comp){ listeners.push_back(comp); } void addDriver(Component * comp){ drivers.push_back(comp); } bool match(std::string n, int p){ return !(name.compare(n)) && (position == p); } void clock(){ cached = false; } STATE genOutput(){ if(cached){ return cached_state; } for(std::vector::iterator d = drivers.begin(); d < drivers.end(); ++d){ STATE temp; if((temp = (*d)->genOutput()) != Z){ cached = true; return cached_state = temp; } } std::cerr << "No drivers on "<< name << " pin " << position << std::endl; return Z; } }; std::vector * generate_circuit(std::vector & mods, std::vector & pn, std::vector & cn, std::string filename); Wire * findWire(std::vector & wires, std::string name, int position); And * buildAnd(And * a, NETLIST::CompNet * c, std::vector & wires); Or * buildOr(Or * a, NETLIST::CompNet * c, std::vector & wires); Xor * buildXor(Xor * a, NETLIST::CompNet * c, std::vector & wires); Not * buildNot(Not * n, NETLIST::CompNet * c, std::vector & wires); Tris * buildTris(Tris * t, NETLIST::CompNet * c, std::vector & wires); Output * buildOutput(Output * o, NETLIST::CompNet * c, std::vector & wires); Zero * buildZero(Zero * o, NETLIST::CompNet * c, std::vector & wires); One * buildOne(One * o, NETLIST::CompNet * c, std::vector & wires); Dff * buildDff(Dff * d, NETLIST::CompNet * c, std::vector & wires); Buffer * buildBuffer(Buffer * buf, NETLIST::CompNet * c, std::vector & wires); void gen_inputs(std::vector & in, NETLIST::CompNet * c, std::vector & wire, std::string filename); void gen_luts(std::vector & lut, NETLIST::CompNet * c, std::vector & wire, std::string filename); }