⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datapathcircuitgenerator.java

📁 一种将c高级语言转化给VHDL的编译器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
      // So, create as many pipeline registers as required.            // Get the width of the operand.      int width = 0;      if(isPredicate)      // Predicate logic is boolean, so of width 1.        width = 1;      else if(isAddress)   // Address width should be separate from others.        width = ADDR_WIDTH;      else if(Cast.conforms(def_inst))  	if (operand.equals(Cast.getResult(def_inst).toString())) 	  width = Cast.getType(def_inst).getType().getWidth();	else 	  width = def_inst.type().getWidth();      else // Otherwise, width is variable.        width = def_inst.type().getWidth();      if(isPipelined()) {	// Add pipeline registers...        // CHANGE: is this wire name correct???        //wire_name = def_inst.getOperand(0).getFullName()+"_"+        //(cur_cycle-def_end_cycle);        wire_name = result.getFullName()+"_"+cur_cycle;        String in_name = null;        if(Load.conforms(def_inst))          in_name = Load.getSource(def_inst).getFullName();        else if(ALoad.conforms(def_inst))          in_name = ALoad.getPrimalSource(def_inst).getFullName() + "_" +             result.getFullName();        else          in_name = result.getFullName();        insertPipelineRegisters(dp,"reg_"+result.getFullName(),           in_name, width,	cur_cycle - def_end_cycle);      } else {	// Add a single register because this design isn't pipelined...      	wire_name=result.getFullName()+"_s%"+(def_end_cycle+1);      	String in_name = null;      	if(Load.conforms(def_inst))           in_name = Load.getSource(def_inst).getFullName();        else if(ALoad.conforms(def_inst))          in_name = ALoad.getPrimalSource(def_inst).getFullName() + "_" +             result.getFullName();        else          in_name = result.getFullName();        if(!_dpRegisters.containsKey(result.getFullName())) {	  dp.insertRegister("reg_"+result.getFullName(), in_name,             insertStateInputFromSM(dp, def_inst), wire_name, width, 0);          _dpRegisters.put(result.getFullName(), null);        }      }    } else {        // Error case where no previous definitions of the operand were found.      throw new SynthesisException("ERROR in makeOpConnection() -- "+        "no previous DEFINITION found:\n"+operand+        ", cur:" + cur_cycle);    }    return wire_name;  }  public String makeOpConnection(Circuit dp, String operand, int cur_cycle, 				 BlockNode bn, boolean isPredicate) {    return makeOpConnection(dp, operand, cur_cycle, bn, isPredicate, false);  }  /**   * This method determines how to set up the data (whether the data is    * in the form of a constant or block or primal) and then follows    * through by generating it.  This method determines whether a register    * is needed between whatever the connection is--this is much more    * simplified in that registers are only created here, and then, only    * if they are needed. They are only needed if the LHS operand isn't    * immediately consumed.   */  protected String getOpName(Circuit dp, Instruction cur_inst,  			     Operand operand, boolean isStore, BlockNode bn, 			     boolean isAddress) {    String wire_name = null;    int width;    //System.out.println("getOpName inst "+cur_inst+" op "+operand);    //System.out.println(" isStore "+isStore);    if (isAddress)       width = ADDR_WIDTH;    else if (Cast.conforms(cur_inst)) {      // cast needs its own special case :(      if (operand == Cast.getResult(cur_inst)) {	width = Cast.getType(cur_inst).getType().getWidth();      } else {	width = cur_inst.type().getWidth();      }     } else {      // common case      width = cur_inst.type().getWidth();    }          // jlt old method    //int width = (isAddress) ? ADDR_WIDTH : cur_inst.type().getWidth();    /*      ?? Future method ?    int width = (isAddress) ? MemoryInterfaceGenerator.ADDR_WIDTH :                              cur_inst.type().getWidth();    */    if (operand.isBlock()) {      wire_name = makeOpConnection(dp, operand.toString(), 				   cur_inst.getExecClkCnt(), bn, false, 				   isAddress);    } else if(operand.isAddr()) {      wire_name = makeOpConnection(dp, operand.toString(), 				   cur_inst.getExecClkCnt(), bn, false, 				   isAddress);    } else if(operand.isBoolean()) {      wire_name = makeOpConnection(dp, operand.toString(),				   cur_inst.getExecClkCnt(), bn, true, 				   isAddress);    } else if( operand.isConstant() ) {      // If the operand is a constant, then create a constant...      /*      if(ALoad.conforms(cur_inst))	wire_name = dp.getParent().getUniqueWireName();      else      */      wire_name = dp.getUniqueWireName();      // Depending on the type of the operand, insert the specific constant      if(operand.isFloatConstant()) 	dp.insertConstant("c_"+((FloatConstantOperand)operand).getValue(), 			  ((FloatConstantOperand)operand).getValue(),			  wire_name, width);      else if(operand.isDoubleConstant()) 	dp.insertConstant("c_"+((DoubleConstantOperand)operand).getValue(), 			  ((DoubleConstantOperand)operand).getValue(),			  wire_name, width);      else if(operand.isIntConstant()) 	dp.insertConstant("c_"+((IntConstantOperand)operand).getValue(), 			  ((IntConstantOperand)operand).getValue(),			  wire_name, width);      else 	throw new SynthesisException("getOpName() -- type not yet supported");                } else if (operand.isPrimal()) {      throw new SynthesisException("getOpName(): primal found...");    } else {      System.out.println("getOpName -- type of operand not yet supported");      System.out.println("         "+cur_inst);      throw new SynthesisException();    }    //System.out.println(" wire_name "+wire_name);    // Create a port out, if this is a store instruction.    if(isStore && !_dpOutWires.contains(wire_name)) {      String portIn = wire_name;      /*	Here Jeff gets a unique wire name, but does not	use it for the next request of that same wire.	So, this is an incorrect implementation.  I have	modified it so that it will use the same name always	and we will leave the unique wire for another day.	jlt -- does this really belong here?  If an instruction is a store,	it can take care of this itself...  Why push the work to this	function?      wire_name = dp.getParent().getUniqueWireName();      dp.insertOutPort(portIn, "o_"+portIn, wire_name, width);      */      dp.insertOutPort(portIn, "o_"+portIn, portIn, width);      _dpOutWires.add(portIn);    }    return wire_name;  }    protected String getOpName(Circuit dp, Instruction cur_inst, 			     Operand operand, 			     boolean isStore, BlockNode bn) {    return getOpName(dp, cur_inst, operand, isStore, bn, false);  }  /**   * This method makes all of the current block's out ports.  It does this    * after creating the datapath to take care of the case where a STORE    * writes to the same variable during different cycles.   */  private HashSet makeBlockOutPorts(Circuit block) {    Set entries = _blockOutWires.entrySet();    String data_port_input = null;    String en_port_input = null;    HashSet processed = new HashSet();    HashSet wiresToRegfile = new HashSet();    for(Iterator i1 = entries.iterator(); i1.hasNext(); ) {      int n_added = 0;      Map.Entry e1 = (Map.Entry) i1.next();      // Skip this entry if already processed.      if(processed.contains(e1)) 	continue;      HashMap data_map = new HashMap();      HashMap en_map = new HashMap();            // Separate the state info from the key; save the operand info.      String wirename = (String)e1.getKey();      String operand1 = wirename.replaceFirst("_s%[0-9]+$", "");      String state1 = wirename.substring(wirename.lastIndexOf("_s%"));      // Get the info on the connecting wire.      ConnectionPair pair = (ConnectionPair) e1.getValue();      String pred = pair.wireName;      int width = pair.width;            // Find all matching map values (operands) and put them in another       // map to add to an OR operator.      for(Iterator i2 = entries.iterator(); i2.hasNext(); ) {	Map.Entry e2 = (Map.Entry) i2.next();	String wirename2 = (String)e2.getKey();	String operand2 = wirename2.replaceFirst("_s%[0-9]+$", "");	String state2 = wirename2.substring(wirename2.lastIndexOf("_s%"));	// If the operands are the same, but not necessarily the cycle...	// then add the mux outputs to the inputs of the OR gate.	if(operand1.equals(operand2)) {	  data_map.put(e2.getKey(), 		       new PortTag(null, (String)e2.getKey(), PortTag.IN, 				   width)); 	  en_map.put(operand1+"_"+state2+"_we",  		     new PortTag(null, operand1+"_"+state2+"_we", 				 PortTag.IN, 1));	  processed.add(e2);	  n_added++;	}      }      // If only one input was added, then don't create an OR gate, just       // an OUT port.      if(n_added == 1) {	// Name the input wires to the OUT port.	data_port_input = (String) e1.getKey();	en_port_input   = pred;	// Add the OUT ports.	String block_name = getCircuitName(block);	block.insertOutPort(data_port_input, "o_"+operand1, 			    block_name+"_"+operand1, 			    width);	block.insertOutPort(en_port_input, "o_"+operand1+"_we", 			    block_name+"_"+operand1+"_we", 1);	String addWireName = operand1+"/"+width;	wiresToRegfile.add(addWireName);	//ConnectionPair cp = new ConnectionPair(operand1, width);	//wiresToRegfile.add(cp);	_regfile.addRegister(operand1, "w_"+operand1, "we_"+operand1,                             "r_"+operand1, width, 0);      } else if(n_added > 1) {	// Shouldn't allow multiple stores to the same primal in the same 	// hyperblock...	throw new SynthesisException("2+ stores to primal in hyperblock!" + 				     "\n    Primal = " + operand1);      }            // Remove the current map entry now that it has been processed.      i1.remove();    }    return wiresToRegfile;  }  /**   * This method takes a boolean equation (representing the predicate) and    * generates the logic for the circuit.  This is usually used for store    * operations...   */  protected String makePredicateLogic(Circuit graph, BooleanEquation eq,				      int cycle, BlockNode bn) {    if(!predHasBeenDefined(eq, cycle, bn)) {      System.out.println("PREDICATE NOT DEFINED!  "+eq+" -- cycle: "+cycle);      return (String) null;    }    LinkedList or_inputs = new LinkedList();    for(ListIterator iter = eq.getTwoLevel().listIterator();iter.hasNext(); ) {      LinkedList and_inputs = new LinkedList();      LinkedList list = (LinkedList) iter.next();      for(ListIterator list_iter = list.listIterator();          list_iter.hasNext(); ) {	String invOut = null;	BooleanOp term = (BooleanOp)list_iter.next();	String operand = term.getOp().toString();	String toAdd = makeOpConnection(graph, operand, cycle, bn, true);	String name = null;	if(term.getSense() == false) {	  // CHANGE: the following is a hack! there doesn't yet appear 	  //         to be a way around this...How do i fix this????	  if(term.getOp().getBoolName().trim().startsWith("(BOOLEAN) %")) {	    int last = term.getOp().getBoolName().lastIndexOf('%');	    name = term.getOp().getBoolName().substring(last+1);	    invOut = "inv%"+name;	    //	  invOut = "dp_inv_"+term.getOp().getBoolName();	  } else {	    throw new SynthesisException("ERROR boolean mismatch: " + invOut);	  }	  if(!_dpInvWires.contains(invOut)) {	    graph.insertOperator(Operation.NOT, invOut, toAdd, invOut, 1);	    _dpInvWires.add(invOut);	  }	}	and_inputs.add((term.getSense()) ? toAdd : invOut);      }      String lower = makeLogicTree(graph, Operation.AND, and_inputs, 1);      or_inputs.add(lower);    }    // Return the output from the logic tree made from the OR list.    String out = makeLogicTree(graph, Operation.OR, or_inputs, 1);    _predicateWires.put(eq.toString(), out);     return out;  }  /**   * This method checks whether an operand has been defined previous to the    * given cycle.  It returns true if it has been defined and false otherwise.   */  static protected boolean hasBeenDefined(String operand, int cycle, 					  BlockNode bn) {    // Find the last definition of the operand before it's use in the     // current cycle.    Iterator it = bn.getInstructions().iterator();    while(it.hasNext()) {      Instruction i = (Instruction) it.next();      // If this inst finishes before the cycle when the use occurs...      int end_cycle = i.getExecClkCnt() + (int) i.getRunLength();      if(end_cycle < cycle)	// If this inst defines the operand...	if(i.getOperand(0).toString().trim().equals(operand)) 	  return true;	    }    return false;  }  /**   * This method checks whether a boolean equation has been defined previous    * to the given cycle. It returns true if all parts of the boolean equation    * have been defined and false otherwise.   */  static protected boolean predHasBeenDefined(BooleanEquation be, int cycle, 					      BlockNode bn) {    // For each BooleanOp in the BooleanEquation, check if it has been     // defined.  If any BooleanOp has not been defined, then return false.    for(ListIterator iter = be.getTwoLevel().listIterator();iter.hasNext(); ) {      Iterator list_iter = ((LinkedList)iter.next()).listIterator();      while(list_iter.hasNext()) {	String operand = ((BooleanOp)list_iter.next()).getOp().getBoolName();	if(!hasBeenDefined(operand, cycle, bn))	  return false;      }    }    return true;  }  /**   * This method creates 'num' pipeline registers after the input wire.     * The names of the wires out of each pipeline register begin with    * the specified 'name' and end with a number specifying the pipeline    * register stage.   */  public void insertPipelineRegisters(Circuit circuit, String name, 				      String input, int width, int num) {    // Create the connected pipeline registers.    for(int i = 1; i <= num; i++) {      if(!_dpRegisters.containsKey(name+"_"+i)) {	String in = (i == 1) ? input : name+"_"+(i-1);	String out = name+"_"+i;	circuit.insertRegister(name+"_"+i, in, null, out, width, 0);	_dpRegisters.put(name+"_"+i, null);      }    }  }  HashMap getPredicateWires() {    return _predicateWires;  }  HashSet getDpOutWires() {    return _dpOutWires;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -