📄 vhdlcircuit.java
字号:
built = true; } VHDLNet findNet(String name) { return (VHDLNet)getNetHash().getNet(name); } Architecture makeTestBenchTop(DesignUnit du, Circuit c) { addLibraries(du); // need some more libraries! du.addLibrary("std_developerskit"); // this won't work in general because the library is not available everywhere. :P du.addUse(new Use("std_developerskit.std_iopak.all")); LibraryUnit lu = du.getLibraryUnit(); //Entity is empty ... //Entity e = lu.getEntity(); Architecture a = lu.getArchitecture(); // build component Component comp = addComponent(a, c); // make instance (and build signals) Instance inst = new Instance(new SimpleName("dut"), comp); for (Iterator iter=c.getPorts().iterator(); iter.hasNext();) { Port p = (Port)iter.next(); String ref_name = p.getRefName(); int width = p.getWidth(); // maps "port" -> "signal" HashSet infos = null; if (p.getDirection() == PortTag.IN) { infos = p.getInPorts(); } else if (p.getDirection() == PortTag.OUT) { infos = p.getOutPorts(); } else { System.out.println(" VHDLCircuit: makeTestBench(): This is complicated -- fix me."); System.exit(-1); } // build test signals SimpleName vhdl_port = new SimpleName(((VHDLPort)p).getIdentifier()); SimpleName vhdl_net = new SimpleName("w_"+ref_name); // kind of a kludge if (ref_name.equals("clk")) { a.addItem(new Signal(vhdl_net, SubType.STD_LOGIC, new Expression(Char.ZERO) )); } else { if (width == 1) { a.addItem(new Signal(vhdl_net, SubType.STD_LOGIC)); } else { a.addItem(new Signal(vhdl_net, SubType.STD_LOGIC_VECTOR(width - 1, 0))); } addVarToMap(p,ref_name,vhdl_net,width); } inst.addPortMap(vhdl_port, vhdl_net); } SimpleName period = new SimpleName("PERIOD"); a.addItem(new ConstantItem(period, SubType.TIME, new Expression(new NumericLiteral(10, new SimpleName("ns"))))); a.addStatement(inst); return a; } public void addVarToMap(Port p, String ref_name, SimpleName vhdl_net, int width) { String short_name=""; if(ref_name.startsWith("i_") || ref_name.startsWith("o_")) short_name = ref_name.substring(2); else short_name="."+ref_name; widths.put(short_name, new Integer(width)); if (p.getDirection() == PortTag.IN) { if(!inputs.containsKey(short_name)) inputs.put(short_name, vhdl_net); } else if(!outputs.containsKey(short_name)) outputs.put(short_name, vhdl_net); } // public void addVarToMap(Port p, String ref_name, String short_name) {// if (p.getDirection() == PortTag.IN) {// //if it is an input port// if(ref_name.startsWith("i_")) { // //update the array if one exists// if(inputs.containsKey(short_name))// if(ref_name.endsWith("_we"))// inputs.get(short_name)[1]=vhdl_net;// else// inputs.get(short_name)[0]=vhdl_net;// // else create a new key,value pair// else {// String s[2];// if(ref_name.endsWith("_we"))// s[1]=vhdl_net;// else// s[0]=vhdl_net;// inputs.put(short_name,s); // } // }// //it must be a special named input port eg 'reset'// else// if(inputs.containsKey(short_name))// break;// else// inputs.put(short_name, vhdl_net);// }// //it must be an output port// else// if(outputs.containsKey(short_name))// break;// else// outputs.put(short_name, vhdl_net);// } // this does not handle illegal top level port names void makeTestBench(String name, Circuit c) { // we need to get just the file basename and path from it int index = name.lastIndexOf(System.getProperty("file.separator")); int last_dot = name.lastIndexOf("."); String basename = name.substring(index+1,last_dot); String path = name.substring(0, index+1); // now create the changed file name String file_name = path + "tb_" + basename + ".vhd"; // prevent tb blotto ... index = 0; while (new File(file_name).exists()) { file_name = path + "tb_" + basename + "_"+ index + ".vhd"; index++; } FabIn fab=null; ParseTestbench ptb; if(GlobalOptions.testBenchFile != null) { ptb = new ParseTestbench(GlobalOptions.testBenchFile); fab = ptb.getFabIn(); } DesignFile design_file = new DesignFile(); DesignUnit design_unit = new DesignUnit("tb_"+getName()); DesignUnit du = design_unit; design_file.addDesignUnit(du); Architecture a = makeTestBenchTop(du, c); // duplicated from above SimpleName period = new SimpleName("PERIOD"); /* a.addItem(new ConstantItem(period, SubType.TIME, new Expression(new NumericLiteral(10, new SimpleName("ns"))))); a.addStatement(inst); */ // add clk SimpleName w_clk = new SimpleName("w_clk"); ConditionalSignalAssignment csa = new ConditionalSignalAssignment(w_clk); a.addStatement(csa); csa.addCondition(new Waveform(new Not(w_clk), new Div(period, new NumericLiteral(2))), null); // add process ProcessStatement p = new ProcessStatement(new SimpleName("STIMULI")); // add it early, does not matter much. a.addStatement(p); //Initialize everything to zero. for(Iterator i=inputs.keySet().iterator(); i.hasNext();){ String port_name=(String)i.next(); p.addStatement(new SignalAssignment((SimpleName)inputs.get(port_name), new Waveform(VHDLConstant.genConstant(BigInteger.ZERO, ((Integer)widths.get(port_name)).intValue())))); } a.addFooterComment("\b- @ asim -lib work tb_"+getName()); //if no command list is present, construct a default list if(fab == null) { addDummyCommands(p); a.addFooterComment("\b- @ run 8000ns"); } //else construct the testbench else { addCommands(p, fab, file_name); if (fab.run != null) a.addFooterComment("\b- @ run "+fab.run.time+fab.run.unit); else // sometimes there is no run command ... a.addFooterComment("\b- @ run 8000ns"); } a.addFooterComment("\b- @ exit"); DesignFile.write(design_file, file_name); } void addDummyCommands(ProcessStatement p) { SimpleName period = new SimpleName("PERIOD"); SimpleName w_reset = new SimpleName("w_reset"); SimpleName w_start = new SimpleName("w_start"); p.addStatement(new SignalAssignment(w_reset, new Waveform(Char.ZERO))); p.addStatement(new SignalAssignment(w_start, new Waveform(Char.ZERO))); p.addStatement(new WaitStatement((Expression)null, new Expression(period))); // the end p.addStatement(new WaitStatement()); } void addCommands(ProcessStatement p, FabIn fab, String name) { Command prev_c = null; for(ListIterator i=fab.commands.listIterator(); i.hasNext();){ Command c = (Command)i.next(); if(c instanceof Write) addWrite(p,(Write)c); else if(c instanceof Read) { if (prev_c instanceof Write){ System.err.println("WARNING: "+name.substring(0, name.length()-3)+"in contains a read directly after a write."); System.err.println("This will most likely cause the read to report failure during execution."); System.err.println("Consider changing it so there is a wait between the two."); System.err.println("A wait has been automatically placed for you.\n"); addWait(p, null); } addRead(p, (Read)c, name); } else if(c instanceof Wait) addWait(p, (Wait)c); else System.err.println("Unknown Command type in "+name.substring(0, name.length()-3)+"in."); prev_c = c; } p.addStatement(new AssertionStatement(new Expression(new SimpleName("false")), new Expression(new StringLiteral("Done signal found.")), AssertionStatement.NOTE)); p.addStatement(new WaitStatement()); } void addWrite(ProcessStatement p, Write w) { SimpleName period = new SimpleName("PERIOD"); String port_name = w.sector; //This currently only takes the first element and // ignores any others that might be there. //Right now, writing to arrays is not supported String wv = w.value[0].toString(); BigInteger value; if(wv.endsWith("d")) { long l = Double.doubleToRawLongBits(Double.parseDouble(wv)); value = new BigInteger(""+l); } else if(wv.endsWith("x")) { value = new BigInteger(wv.substring(wv.length()-1), 16); } else if(wv.endsWith("f") || wv.indexOf(".")>0) { int i = Float.floatToRawIntBits(Float.parseFloat(wv)); value = new BigInteger(""+i); } else{ value = new BigInteger(wv); } int width=((Integer)widths.get(port_name)).intValue(); SimpleName port=(SimpleName)inputs.get(port_name); if(port_name.equals(".reset") || port_name.equals(".start")) { p.addStatement(new SignalAssignment(port, new Waveform(VHDLConstant.genConstant(value, width)))); p.addStatement(new WaitStatement((Expression)null,new Expression(period))); p.addStatement(new SignalAssignment(port, new Waveform(VHDLConstant.genConstant(BigInteger.ZERO, width)))); } else{ int width_we=((Integer)widths.get(port_name+"_we")).intValue(); SimpleName port_we=(SimpleName)inputs.get(port_name+"_we"); p.addStatement(new SignalAssignment(port, new Waveform(VHDLConstant.genConstant(value, width)))); p.addStatement(new SignalAssignment(port_we, new Waveform(VHDLConstant.genConstant(BigInteger.ONE,width_we)))); p.addStatement(new WaitStatement((Expression)null,new Expression(period))); p.addStatement(new SignalAssignment(port, new Waveform(VHDLConstant.genConstant(BigInteger.ZERO,width)))); p.addStatement(new SignalAssignment(port_we, new Waveform(VHDLConstant.genConstant(BigInteger.ZERO,width_we)))); } } void addRead(ProcessStatement p, Read r, String name) { String port_name = r.sector; String wr = r.value[0].toString(); BigInteger value; if(wr.endsWith("d")) { long l = Double.doubleToRawLongBits(Double.parseDouble(wr)); value = new BigInteger(""+l); } else if(wr.endsWith("x")) { value = new BigInteger(wr.substring(wr.length()-1), 16); } else if(wr.endsWith("f") || wr.indexOf(".")>0) { int i = Float.floatToRawIntBits(Float.parseFloat(wr)); value = new BigInteger(""+i); } else{ value = new BigInteger(wr); } Literal first = new StringLiteral("N wasn't set correctly to "+r.value[0]+" (N="); FunctionCall to_string = new FunctionCall(new SimpleName("to_string")); to_string.add((SimpleName)outputs.get(port_name)); Literal second = new StringLiteral(") "+name); int width=((Integer)widths.get(port_name)).intValue(); SimpleName port=(SimpleName)outputs.get(port_name); //Have to disable anysize zeros since the compiler doesn't like them in asserts p.addStatement(new AssertionStatement(new Expression(new Eq(port, VHDLConstant.genConstant(value, width, false))), new Expression(new Concat(first,to_string,second)), AssertionStatement.ERROR)); } void addWait(ProcessStatement p, Wait w) { //This appears in so many places that it makes sense to make it a constant somewhere someday SimpleName period = new SimpleName("PERIOD"); if(w == null) { p.addStatement(new WaitStatement((Expression)null, new Expression(period))); return; } String port_name = w.sector; if(port_name == null) { p.addStatement(new WaitStatement((Expression)null, new Expression(period))); } else if(port_name.equals(".done")) { p.addStatement(new WaitStatement(new Expression(new Eq((SimpleName)outputs.get(port_name), Char.ONE)))); p.addStatement(new WaitStatement((Expression)null,new Expression(period))); } else if(port_name.equals(".reset")) { p.addStatement(new WaitStatement((Expression)null, new Expression(new Mult(period,new NumericLiteral(8))))); } } public static void main(String args[]) { Circuit dc = new VHDLCircuit(null, null, "Bob"); //dc.setClustering(true); dc.insertInPort("a","data_a",1); dc.insertInPort("b","data_b",1); dc.insertOperator(Operation.AND, "data_a", "data_b", "and_ab", 1); dc.insertRegister("my_reg", "and_ab", null, "result", 1, 0); dc.insertOutPort("result","c",1); Circuit child = dc.insertCircuit("my_child"); child.insertInPort("data_a","a","my_a",1); child.insertInPort("data_b","b","my_b",1); child.insertOutPort("my_c","c","result_2",1); child.insertOperator(Operation.OR, "my_a", "my_b", "my_c", 1); child.insertOperator(Operation.MUX, "my_a", "my_b", "my_c", "s", 1); dc.insertOutPort("result_2","d",1); dc.build("test.dot",null); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -