/// <summary> /// Writes the testbench code that instantiates the module and writes out the /// inputs and outputs /// </summary> /// <param name="dir">String containing directory path of where the circuit should /// be saved</param> /// <returns>int containing the required width of the testvectors</returns> private int instantiate(String dir) { //Sets the file writer to append mode FileStream fs = new FileStream(dir + "\\test.v", FileMode.Append, FileAccess.Write); TextWriter tw = new StreamWriter(fs); //puts the inputs into a temp value so that once the clock is removed, it doesn't //remove it from the class object PinList tempInputs = new PinList(); tempInputs.AddRange(inputs.Pins); tw.Write("module test; \n\n\t//inputs\n"); int i = 0; //Gets the name of the clock variable Pin clkVar = tempInputs.clk_var(); //Console.WriteLine(clkVar); //Removes the clock variable from the inputs and insizes tempInputs.clk_rm(clkVar); tw.Write("\treg " + clkVar.PinName + ";\n"); //Writes out the module inputs foreach (Pin datain in tempInputs.Pins) { if (datain.bussize > 1) { tw.Write("\treg ["); tw.Write(datain.bussize - 1); tw.Write(":0] " + datain.PinName + ";\n"); } else { tw.Write("\treg " + datain.PinName + ";\n"); } } tw.Write("\n\t//expected results\n"); //Writes the expected module outputs foreach (Pin dataout in outputs.Pins) { if (dataout.bussize > 1) { tw.Write("\treg ["); tw.Write(dataout.bussize - 1); tw.Write(":0] " + dataout.PinName + "Expected;\n"); } else { tw.Write("\treg " + dataout.PinName + "Expected;\n"); } } tw.Write("\n\t//outputs\n"); //Writes the module outputs foreach (Pin dataout in outputs.Pins) { if (dataout.bussize > 1) { tw.Write("\twire ["); tw.Write(dataout.bussize - 1); tw.Write(":0] " + dataout.PinName + ";\n"); } else { tw.Write("\twire " + dataout.PinName + ";\n"); } } tw.Write("\tinteger error, ch;"); int tv_count = 0; //Adds the bus sizes of each input and output to generate the width of the //expected test vectors foreach (Pin instance in tempInputs.Pins) { tv_count += instance.bussize; } foreach (Pin instance in outputs.Pins) { tv_count += instance.bussize; } tw.Write("\n\n\n\treg[31:0] vectornum, errors;\n"); tw.Write("\n\treg[" + (tv_count - 1) + ":0] testvectors[10000:0];\n"); tw.Write("\n\t//Instantiate the Unit Under Test (UUT)\n\t" + moduleName + " uut(\n"); i = 0; //System.Windows.Forms.MessageBox.Show(clkVar.PinName + !clkVar.PinName.Equals("auto_clk")); //Lists the inputs and outputs for module instantiation if (!clkVar.PinName.Equals("auto_clock")) { tw.Write("\t\t." + clkVar.PinName + "(" + clkVar.PinName + ")"); } foreach (Pin datain in tempInputs.Pins) { if ((clkVar.PinName.Equals("auto_clock")) && (i == 0)) { tw.Write("\t\t." + datain.PinName + "(" + datain.PinName + ")"); } else { tw.Write(",\n\t\t." + datain.PinName + "(" + datain.PinName + ")"); } i++; } foreach (Pin dataout in outputs.Pins) { tw.Write(",\n\t\t." + dataout.PinName + "(" + dataout.PinName + ")"); } tw.Close(); fs.Close(); return(tv_count); }
/// <summary> /// Writes the initialization code for reading in the test vectors /// </summary> /// <param name="dir">String containing directory path of where the circuit should /// be saved</param> private void initTest(String dir) { //Sets the file writer to append mode FileStream fs = new FileStream(dir + "\\test.v", FileMode.Append, FileAccess.Write); TextWriter tw = new StreamWriter(fs); int i; PinList tempInputs = new PinList(); tempInputs.AddRange(inputs.Pins); Pin clkVar = tempInputs.clk_var(); tempInputs.clk_rm(clkVar); tw.Write("\n\t);\n\n"); tw.Write("\talways\n\t\tbegin\n\t\t\t" + clkVar.PinName + "=1; #5; " + clkVar.PinName + "=0; #5;\n\t\tend\n"); tw.Write("\n\tinitial\n\t\tbegin\n" + "\t\t\terror = $fopen(\"error.log\");\n" + "\t\t\tif(error==0) $stop(2);\n" + "\t\t\tch = error|1;\n" + "\t\t\t$readmemb(\"testVect.tv\", testvectors);\n" + "\t\t\tvectornum=0; errors=0;\n\t\tend\n"); tw.Write("\n\talways @ (posedge " + clkVar.PinName + ")\n\t\tbegin\n" + "\t\t\t#1; {"); i = 0; //Writes out the inputs for testvector assignment foreach (Pin datain in tempInputs.Pins) { if (datain.bussize > 1) { if (i == 0) { tw.Write(datain.PinName + "[" + (datain.bussize - 1) + ":0]"); } else { tw.Write(", " + datain.PinName + "[" + (datain.bussize - 1) + ":0]"); } } else { if (i == 0) { tw.Write(datain.PinName); } else { tw.Write(", " + datain.PinName); } } i++; } //Writes out the expected outputs for testvector assignment foreach (Pin dataout in outputs.Pins) { if (dataout.bussize > 1) { tw.Write(", " + dataout.PinName + "Expected[" + (dataout.bussize - 1) + ":0]"); } else { tw.Write(", " + dataout.PinName + "Expected"); } } tw.Write("}=\n\t\t\ttestvectors[vectornum];\n\t\tend\n"); tw.Write("\n\talways @ (negedge " + clkVar.PinName + ")\n\t\tbegin\n"); tw.Close(); fs.Close(); }
/// <summary> /// Method compares inputs and outputs generated by the circuit and truthtable /// recognizers, attempts to reconcile the order and generated an appropriate /// Verilog testbench /// </summary> /// <param name="tv">List of Pins containing circuit input/outputs recognized /// by the truthtable recognizer</param> /// <param name="circ">List of superwires contained in the CircuitRec object</param> /// <returns>List of pins containing the correct pin order</param> /// <param name="filename">Name of the xml/verilog file that contains the /// circuit whose inputs/outputs are to be rectified</param> /// <returns>List of pins containing the correct pin order</returns> public List <Pin> inOutRectify(List <Pin> tv, List <Mesh> circ, String filename) { //get the input/output pins from circuitrec PinList synthPins = new PinList(MeshToPins(circ)); //initialize output list List <Pin> order = new List <Pin>(); Pin clkPin; String dir = Path.GetDirectoryName(filename); String module = Path.GetFileNameWithoutExtension(filename); int i = 0; //Get the clock variable clkPin = synthPins.clk_var(); //Remove the clock variable from synthPins synthPins.clk_rm(clkPin); //foreach (Pin instance in synthPins.Pins) //{ // Console.WriteLine(instance.PinName + " " + instance.bussize); //} order.Add(clkPin); //If there is a mismatch between number of inputs/outputs //return an error if (tv.Count != synthPins.Count) { MessageBox.Show("Mismatch between number of truth table and circuit inputs/outputs", "In/Out Mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } int flipped = 0; //Looks for each pin that exists in the testvector file in the circuit //if it exists in the circuit, it is added to this list of pin outputs foreach (Pin instance in tv) { i = indexFind(synthPins.Pins, instance); if (i < synthPins.Pins.Count) { if (instance.Polarity.Equals(synthPins.Pins[i].Polarity)) { //if the pins have the same input/output type, add it to the //return list and remove it from synthpins order.Add(instance); synthPins.RemoveAt(i); } else { flipped++; } } } //if all inputs/outputs match except every input/output has the wrong //polarity, return an error if (flipped == synthPins.Count) { MessageBox.Show("Truthtable inputs/outputs appear to have been flipped", "Input/Output Mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } //if some inputs/outputs could not be matched up, return an error if (synthPins.Pins.Count > 0) { //MessageBox.Show("here"); //foreach (Pin instance in synthPins.Pins) //{ // Console.WriteLine(instance.PinName + " " + instance.bussize); //} //MessageBox.Show("there"); MessageBox.Show("Input/Output lists could not be rectified", "Input/Output Mismatch", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } Module mod = new Module("testBench"); //write out a testbench with inputs/outputs in the appropriate order TestBenchWriter tbw = new TestBenchWriter(dir, pins2mod(order, module)); tbw.writeBench(); return(order); }