#include "module.h" #include "netlist.h" #include "simulator.h" #include #include #include namespace SIM{ std::vector * generate_circuit(std::vector & mods, std::vector & pn, std::vector & cn, std::string filename){ std::vector wires; for(std::vector::iterator p = pn.begin(); p < pn.end(); ++p){ Wire * tmp = new Wire((*p)->name, (*p)->position); wires.push_back(tmp); } std::vector ands; std::vector ors; std::vector xors; std::vector nots; std::vector ones; std::vector zeroes; std::vector dffs; std::vector trises; std::vector inputs; std::vector outputs; std::vector buffers; std::vector luts; for(std::vector::iterator c = cn.begin(); c < cn.end(); ++c){ switch((*c)->type_enum){ case NETLIST::AND: ands.push_back(buildAnd(new And((*c)->name), *c, wires)); break; case NETLIST::OR: ors.push_back(buildOr(new Or((*c)->name), *c, wires)); break; case NETLIST::XOR: xors.push_back(buildXor(new Xor((*c)->name), *c, wires)); break; case NETLIST::NOT: nots.push_back(buildNot(new Not((*c)->name), *c, wires)); break; case NETLIST::ONE: ones.push_back(buildOne(new One((*c)->name), *c, wires)); break; case NETLIST::ZERO: zeroes.push_back(buildZero(new Zero((*c)->name), *c, wires)); break; case NETLIST::DFF: dffs.push_back(buildDff(new Dff((*c)->name), *c, wires)); break; case NETLIST::BUF: buffers.push_back(buildBuffer(new Buffer((*c)->name), *c, wires)); break; case NETLIST::TRIS: trises.push_back(buildTris(new Tris((*c)->name), *c, wires)); break; case NETLIST::INPUT: gen_inputs(inputs, *c, wires, filename); break; case NETLIST::LUT: gen_luts(luts, *c, wires, filename); break; case NETLIST::OUTPUT: outputs.push_back(buildOutput(new Output((*c)->name, filename), *c, wires)); break; default: if((*c)->type.compare("evl_clock")){ abort(); } } } std::cerr << "Starting Sim" << std::endl; for(std::vector::iterator out = outputs.begin(); out < outputs.end(); ++out){ for(int i = 0; i < 1000; ++i){ (*out)->genOutput(); for(std::vector::iterator d = dffs.begin(); d < dffs.end(); ++d){ (*d)->genOutput(); } for(std::vector::iterator d = dffs.begin(); d < dffs.end(); ++d){ (*d)->clock(); } for(std::vector::iterator i = inputs.begin();i < inputs.end(); ++i){ (*i)->clock(); } for(std::vector::iterator w = wires.begin();w < wires.end(); ++w){ (*w)->clock(); } } } return NULL; } void gen_inputs(std::vector & inputs, NETLIST::CompNet * c, std::vector & wires, std::string filename){ //generate filename std::string in_filename = filename + "." + (c)->name + ".evl_input"; std::ifstream infile(in_filename.c_str()); std::string line; //grab the first line, which gives num_pins pin_1 pin_2 ... pin_n getline(infile, line); char * parse_pointer = (char *)line.c_str(); //get num pins long pins = strtol(parse_pointer, &parse_pointer, 10); long widths[pins]; long temp_pins = 0; while(temp_pins < pins){ widths[temp_pins] = strtol(parse_pointer, &parse_pointer , 10); ++temp_pins; } std::vector temp_vect; long sum = 0; for(temp_pins = 0; temp_pins < pins; ++temp_pins){ sum += widths[temp_pins]; } for(long temp_sum = 0; temp_sum < sum; ++temp_sum){ temp_vect.push_back(new Input(c->name)); } while(getline(infile, line)){ bool first_int = true; long line_count = 0; int widths_index = 0; int input_bit_index = 0; for(temp_pins = 0; temp_pins <= pins; ++temp_pins){ if(first_int){ parse_pointer = (char *)line.c_str(); } long curr_int = strtol(parse_pointer, &parse_pointer, first_int?10:16); if(first_int){ line_count = curr_int; } else { for(int bit_index = 0; bit_index < widths[widths_index]; bit_index++){ STATE curr; if(curr_int & (1<add_state(curr); } ++input_bit_index; } ++widths_index; } first_int = false; } } unsigned int input_index = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ for(int curr_pin = p->bus_lsb; curr_pin <= p->bus_msb; ++curr_pin){ Wire * conn = findWire(wires, p->name, curr_pin); if(conn == NULL){ abort(); } conn->addDriver((Component *)temp_vect[input_index]); input_index++; } } //TODO: link inputs to wires inputs.insert(inputs.end(),temp_vect.begin(),temp_vect.end()); } void gen_luts(std::vector & lut, NETLIST::CompNet * c, std::vector & wire, std::string filename){ //generate filename std::string in_filename = filename + "." + (c)->name + ".evl_lut"; std::cerr << in_filename << std::endl; std::ifstream infile(in_filename.c_str()); std::string line; //grab the first line, which gives num_pins pin_1 pin_2 ... pin_n getline(infile, line); char * parse_pointer = (char *)line.c_str(); //get num pins long word_width = strtol(parse_pointer, &parse_pointer, 10); //long address_width = strtol(parse_pointer, &parse_pointer, 10); std::vector temp_vect; for(long i = 0; i < word_width; ++i){ temp_vect.push_back(new Lut(c->name)); } while(getline(infile, line)){ parse_pointer = (char *) line.c_str(); long curr_int = strtol(parse_pointer, &parse_pointer, 16); std::cerr << std::hex <add_state(curr); } } unsigned int lut_index = 0; unsigned int pin_index = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ for(int curr_pin = p->bus_lsb; curr_pin <= p->bus_msb; ++curr_pin){ Wire * conn = findWire(wire, p->name, curr_pin); if(conn == NULL){ abort(); } if(pin_index == 0){ conn->addDriver((Component *)temp_vect[lut_index]); lut_index++; } else { for(std::vector::iterator l = temp_vect.begin(); l < temp_vect.end(); ++l){ (*l)->add_addressLine((Component *)conn); } } } ++pin_index; } //TODO: put back in main vector lut.insert(lut.end(),temp_vect.begin(),temp_vect.end()); } And * buildAnd(And * a, NETLIST::CompNet * c, std::vector & wires){ int pin_count = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ if(p->bus_msb == p->bus_lsb){ Wire * conn = findWire(wires, p->name, p->bus_msb); if(pin_count == 0){ a->setOutput((Component *)conn); conn->addDriver((Component *)a); } else { a->addInput((Component *)conn); conn->addListener((Component *)a); } } else { abort(); } ++pin_count; } return a; } Or * buildOr(Or * a, NETLIST::CompNet * c, std::vector & wires){ int pin_count = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ if(p->bus_msb == p->bus_lsb){ Wire * conn = findWire(wires, p->name, p->bus_msb); if(pin_count == 0){ a->setOutput((Component *)conn); conn->addDriver((Component *)a); } else { a->addInput((Component *)conn); conn->addListener((Component *)a); } } else { abort(); } ++pin_count; } return a; } Xor * buildXor(Xor * a, NETLIST::CompNet * c, std::vector & wires){ int pin_count = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ if(p->bus_msb == p->bus_lsb){ Wire * conn = findWire(wires, p->name, p->bus_msb); if(pin_count == 0){ a->setOutput((Component *)conn); conn->addDriver((Component *)a); } else { a->addInput((Component *)conn); conn->addListener((Component *)a); } } else { abort(); } ++pin_count; } return a; } Tris * buildTris(Tris * t, NETLIST::CompNet * c, std::vector & wires){ int pin_count = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ if(p->bus_msb == p->bus_lsb){ Wire * conn = findWire(wires, p->name, p->bus_msb); if(pin_count == 0){ t->setOutput((Component *)conn); conn->addDriver((Component *)t); } if(pin_count == 1){ t->setInput((Component *)conn); conn->addListener((Component *)t); } if(pin_count == 2){ t->setEnable((Component *)conn); conn->addListener((Component *)t); } } else { abort(); } ++pin_count; } return t; } Not * buildNot(Not * n, NETLIST::CompNet * c, std::vector & wires){ int pin_count = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ if(p->bus_msb == p->bus_lsb){ Wire * conn = findWire(wires, p->name, p->bus_msb); if(pin_count == 0){ n->setOutput((Component *)conn); conn->addDriver((Component *)n); } else { n->setInput((Component *)conn); conn->addListener((Component *)n); } } else { abort(); } ++pin_count; } return n; } Output * buildOutput(Output * o, NETLIST::CompNet * c, std::vector & wires){ for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ for(int curr_pin = p->bus_lsb; curr_pin <= p->bus_msb; ++curr_pin){ Wire * conn = findWire(wires, p->name, curr_pin); if(conn == NULL){ abort(); } o->add_component(p->name, (Component *)conn); conn->addListener((Component *)o); } o->complete_pin(p->name); } return o; } One * buildOne(One * o, NETLIST::CompNet * c, std::vector & wires){ for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ for(int curr_pin = p->bus_lsb; curr_pin <= p->bus_msb; ++curr_pin){ Wire * conn = findWire(wires, p->name, curr_pin); if(conn == NULL){ abort(); } conn->addDriver((Component *)o); } } return o; } Zero * buildZero(Zero * o, NETLIST::CompNet * c, std::vector & wires){ for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ for(int curr_pin = p->bus_lsb; curr_pin <= p->bus_msb; ++curr_pin){ Wire * conn = findWire(wires, p->name, curr_pin); if(conn == NULL){ abort(); } conn->addDriver((Component *)o); } } return o; } Dff * buildDff(Dff * d, NETLIST::CompNet * c, std::vector & wires){ if(c->pins.size() != 3){ abort(); } int curr_pin = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ if(p->bus_msb != p->bus_lsb){ abort(); } Wire * conn = findWire(wires, p->name, p->bus_msb); if(curr_pin == 0){ conn->addDriver((Component *)d); d->setOutput((Component *)conn); } if(curr_pin == 1){ conn->addListener((Component *)d); d->setInput((Component *)conn); } if(curr_pin == 2){ } curr_pin++; } return d; } Buffer * buildBuffer(Buffer * buf, NETLIST::CompNet * c, std::vector & wires){ if(c->pins.size() != 2){ abort(); } int curr_pin = 0; for(std::vector< ::Pin >::iterator p = c->pins.begin(); p < c->pins.end(); ++p){ if(p->bus_msb != p->bus_lsb){ abort(); } Wire * conn = findWire(wires, p->name, p->bus_msb); if(curr_pin == 0){ conn->addDriver((Component *)buf); buf->setOutput((Component *)conn); } if(curr_pin == 1){ conn->addListener((Component *)buf); buf->setInput((Component *)conn); } curr_pin++; } return buf; } Wire * findWire(std::vector & wires, std::string name, int position){ for(std::vector::iterator w = wires.begin(); w < wires.end(); ++w){ if((*w)->match(name, position)){ return *w; } } abort(); return NULL; } }