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

📄 datapathcircuitgenerator.java

📁 一种将c高级语言转化给VHDL的编译器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    TypeOperand type_op = Cast.getType(inst);    int target_width = type_op.getType().getWidth();    int source_width = inst.type().getWidth();    String op_name = "op_"+inst.operator+dpCircuit.getParent().getUniqueName();    Operation op = library.select(inst);    String wire_name;    if (op != null) {      /*      // I don't think I can use this one...      dpCircuit.insertOperator(op, op_name,			       getOpName(dpCircuit, inst, source, false, bn), 			       target.getFullName(),			       inst.type().getWidth());      */            // this feels like a kludge...      if (op.getName().equals("tr_dcast")) {	Operation my_op = Operation.SLICE;		HashMap map = new HashMap();	String source_name = getOpName(dpCircuit, inst, source, false, bn);	map.put(source_name, new PortTag(null, "in0", PortTag.IN, source_width));	String const1_name = dpCircuit.getUniqueWireName();	dpCircuit.insertConstant("c_"+(target_width-1), (target_width-1), const1_name, source_width);	map.put(const1_name, new PortTag(null, "in1", PortTag.IN, source_width));	String const2_name = dpCircuit.getUniqueWireName();	dpCircuit.insertConstant("c_"+(0), (0), const2_name, source_width);	map.put(const2_name, new PortTag(null, "in2", PortTag.IN, source_width));	String target_name = target.getFullName();	map.put(target_name, new PortTag(null, "out", PortTag.OUT, target_width));		dpCircuit.insertOperator(op_name, my_op, map);      } else if (op.getName().equals("tr_ucast")) {	// source only matters	if (type_op.getType().isSigned()) {	  // first we slice	  Operation slice = Operation.SLICE;	  	  HashMap slice_map = new HashMap();	  String source_name = getOpName(dpCircuit, inst, source, false, bn);	  slice_map.put(source_name, new PortTag(null, "in0", PortTag.IN, source_width));	  	  String slice_const1 = dpCircuit.getUniqueWireName();	  dpCircuit.insertConstant("c_"+(source_width-1), (source_width-1), slice_const1, source_width);	  slice_map.put(slice_const1, new PortTag(null, "in1", PortTag.IN, source_width));	  String slice_const2 = dpCircuit.getUniqueWireName();	  dpCircuit.insertConstant("c_"+(source_width-2), (source_width-2), slice_const2, source_width);	  slice_map.put(slice_const2, new PortTag(null, "in2", PortTag.IN, source_width));	  String top_bit = dpCircuit.getUniqueWireName("topbit");	  slice_map.put(top_bit, new PortTag(null, "out", PortTag.OUT, 1)); // 1 bit	  	  dpCircuit.insertOperator(op_name+"_slice", slice, slice_map);	  // Then mux	  Operation mux = Operation.MUX;	  	  HashMap mux_map = new HashMap();	  mux_map.put(top_bit, new PortTag(null, "s", PortTag.IN, 1)); // top_bit is the selector	  String mux_const1 = dpCircuit.getUniqueWireName();	  int mux_const_width = target_width - source_width;	  dpCircuit.insertConstant("c_0", BigInteger.ZERO, mux_const1, mux_const_width);	  mux_map.put(mux_const1, new PortTag(null, "in0", PortTag.IN, mux_const_width));	  String mux_const2 = dpCircuit.getUniqueWireName();	  BigInteger neg_value = new BigInteger("2").pow(mux_const_width).subtract(BigInteger.ONE);	  dpCircuit.insertConstant("c_neg", neg_value, mux_const2, mux_const_width);	  mux_map.put(mux_const2, new PortTag(null, "in1", PortTag.IN, mux_const_width));		  	  String mux_out = dpCircuit.getUniqueWireName("consts");	  mux_map.put(mux_out, new PortTag(null, "out", PortTag.OUT, mux_const_width));	  dpCircuit.insertOperator(op_name+"_mux", mux, mux_map);	  // now concat	  Operation concat = Operation.CONCAT;	  HashMap concat_map = new HashMap();	  concat_map.put(mux_out, new PortTag(null, "in0", PortTag.IN, mux_const_width)); 	  concat_map.put(source_name, new PortTag(null, "in1", PortTag.IN, source_width)); 	  String target_name = target.getFullName();	  concat_map.put(target_name, new PortTag(null, "out", PortTag.OUT, target_width));	 dpCircuit.insertOperator(op_name, concat, concat_map); 	} else {	  Operation my_op = Operation.CONCAT;	  	  HashMap map = new HashMap();	  String source_name = getOpName(dpCircuit, inst, source, false, bn);	  map.put(source_name, new PortTag(null, "in0", PortTag.IN, source_width));	  	  String const1_name = dpCircuit.getUniqueWireName();	  dpCircuit.insertConstant("c_"+0, 0, const1_name, target_width - source_width);	  map.put(const1_name, new PortTag(null, "in1", PortTag.IN, source_width));	  String target_name = target.getFullName();	  map.put(target_name, new PortTag(null, "out", PortTag.OUT, target_width));	  dpCircuit.insertOperator(op_name, my_op, map);	}      } else {	HashMap map = new HashMap();	String source_name = getOpName(dpCircuit, inst, source, false, bn);	map.put(source_name, new PortTag(null, "in0", PortTag.IN, source_width));	String target_name = target.getFullName();	map.put(target_name, new PortTag(null, "out", PortTag.OUT, target_width));	dpCircuit.insertOperator(op_name, op, map);      }    } else {      // throw exception ...      throw new SynthesisException("Unknown cast operator "+inst);    }  }  /**   * This method implements the load operator in the datapath logic. Its    * simple in that it only makes IN ports from the regfile to the datapath.   * It then relies on other operators to build a register if the value is    * not immediately consumed by any instruction. If the value is only    * immediately consumed then no registers will be connected by the    * consuming instructions.   */  private void caseLoad(Circuit dpCircuit, Instruction inst, BlockNode bn) {    Circuit block = dpCircuit.getParent();    Operand source = Load.getSource(inst);    Operand target = Load.getResult(inst);    String primal = source.getFullName();    String local = target.getFullName();    int width = inst.type().getWidth();    // Deal with all the types of operands!    if(target.isPrimal())      throw new SynthesisException("register copy not allowed...");    if(source.isConstant() || source.isBlock()) {      // Create a buffer...      String in = getOpName(dpCircuit, inst, source, false, bn);      String out = target.getFullName();      insertBuf(dpCircuit, "buf_"+dpCircuit.getUniqueName(), 		in, out, width);      return;    } else if(!source.isPrimal()) {      // Error!      throw new SynthesisException("Unhandled operand for load");    }    String blk_primal = primal+block.getUniqueName();    if(!_dpInWires.contains(primal)) {      dpCircuit.insertInPort(blk_primal, "i_"+primal, primal, width);      _dpInWires.add(primal);      // Has a primal already been loaded? If not, make a path of       // wires and ports to the regfile.      _regfile.addRegister(primal, "w_"+primal, "we_"+primal, 			   "r_"+primal, width, 0);    }    if(!_blkWires.contains(primal)) {      block.insertInPort("r_"+primal, "i_"+primal, blk_primal, width);      _blkWires.add(primal);    }  }  /**   * This method implements the select operator in the datapath logic.   */  private void caseSelect(Circuit dpCircuit, Instruction inst, BlockNode bn) {    Operand source1 = Select.getVal1(inst);    Operand source2 = Select.getVal2(inst);    Operand condition = Select.getCondition(inst);    Operand target = Select.getResult(inst);    String out = target.getFullName();    boolean isPrimalResult = target.isPrimal();    if(isPrimalResult)      throw new SynthesisException("caseSelect: primal result found.");        // Build a mux or buffer depending on how the conditional evaluates.    if(condition == BooleanOperand.TRUE) {      // Create a buffer with the 1st input.      String in0 = getOpName(dpCircuit, inst, source1, false, bn);      insertBuf(dpCircuit, 		"buf_"+inst.operator+dpCircuit.getUniqueName(), 		in0, out, inst.type().getWidth());    } else if(condition == BooleanOperand.FALSE) {      // Create a buffer with the 2nd input.      String in1 = getOpName(dpCircuit, inst, source2, false, bn);      insertBuf(dpCircuit, 		"buf_"+inst.operator+dpCircuit.getUniqueName(), 		in1, out, inst.type().getWidth());    } else if (source1 == source2) {      System.out.println("WARNING: mux with identical inputs");       // Create a buffer with the 1st input.      String in0 = getOpName(dpCircuit, inst, source1, false, bn);      insertBuf(dpCircuit, 		"buf_"+inst.operator+dpCircuit.getUniqueName(), 		in0, out, inst.type().getWidth());    } else {      // Create a mux because the conditional isn't known yet...      String in0 = getOpName(dpCircuit, inst, source2, false, bn);      String in1 = getOpName(dpCircuit, inst, source1, false, bn);      String sel = getOpName(dpCircuit, inst, condition, false, bn);      String name = "mux_"+inst.operator+dpCircuit.getUniqueName();      insertMux(dpCircuit, name, in0, in1, sel, out, inst.type().getWidth());   }  }  /**   * This method implements a store operator in the datapath logic.   */  private void caseStore(Circuit dpCircuit, Instruction inst, BlockNode bn) {    Circuit blockCircuit = dpCircuit.getParent();    Operand source = Store.getValue(inst);    Operand target = Store.getDestination(inst);    boolean isPrimalCopy = source.isPrimal();    if(isPrimalCopy)  // Primal copies are not allowed!      throw new SynthesisException("register copy not allowed...");    // If this is a store to a block, then just use a buffer...    if(target.isBlock() || target.isAddr()) {        String in = getOpName(dpCircuit, inst, source, false, bn);      String out = target.getFullName();      insertBuf(dpCircuit, "buf"+dpCircuit.getUniqueName(), 		in, out, inst.type().getWidth());      return;    }    // jt -- ugh    // In this case there should only be one.    String blkEn = inst.getOperand(0).getFullName()+"_we";         String dataOut = makeDataMuxLogic(dpCircuit, inst, blkEn, bn);    // Save the mux output and write enable to connect to outports later.      // The write enable wire is just the mux_out string plus "_en" added     // to the end.  The mux output and write enable will be added at the     // same time, so only one element needs to be added to the hashmap.      ConnectionPair predAndWidth = new ConnectionPair(blkEn, 						     inst.type().getWidth());    _blockOutWires.put(dataOut, predAndWidth);  }  /**    * This method implements test operations (i.e. setgt, setlt, ...) in    * the datapath logic.   */  private void caseTest(Circuit dpCircuit, Instruction inst, BlockNode bn) {    Operand source1 = Test.getVal1(inst);    Operand source2 = Test.getVal2(inst);    Operation op = library.select(inst);    if (op != null) {      String op_name = "op_" +	inst.operator+dpCircuit.getUniqueName();      HashMap map = new HashMap();      map.put(getOpName(dpCircuit, inst, source1, false, bn),	      new PortTag(null, "in0", PortTag.IN, inst.type().getWidth()));      map.put(getOpName(dpCircuit, inst, source2, false, bn), 	      new PortTag(null, "in1", PortTag.IN, inst.type().getWidth()));      map.put(inst.getOperand(0).getFullName(), 	      new PortTag(null, "out", PortTag.OUT, 1));      dpCircuit.insertOperator(op_name, op, map);    } else {      // throw exception ...      throw new SynthesisException("Unknown test operator "+inst);    }  }  /**    * This method implements unary operations (not, ...) in the datapath.    */  private void caseUnary(Circuit dpCircuit, Instruction inst, BlockNode bn) {     Operand source = Unary.getVal(inst);    Operand target = Unary.getResult(inst);    String op_name = "op_"+inst.operator+dpCircuit.getParent().getUniqueName();    Operation op = library.select(inst);    if (op != null) {      dpCircuit.insertOperator(op, op_name,			       getOpName(dpCircuit, inst, source, false, bn), 			       target.getFullName(),			       inst.type().getWidth());    } else {      // throw exception ...      throw new SynthesisException("Unknown unary operator "+inst);    }  }  /**   * This method creates an in port from the block level to the dataflow    * level.  It gives the state associated with this instruction.   */  private String insertStateInputFromSM(Circuit dp, int startCycle, 					float runLength) {        String cycle = "s%"+(int)(startCycle+runLength);    // CHANGE: the following won't work with multiple blocks??    //         this had to be done because getPortByName() returns some     //         odd results...    if ( dp.getPortByName(getCircuitName(dp)+"_0."+"i_"+cycle+".0") != null ) {      return cycle;    }    insertInPort(dp, cycle, "i_"+cycle, cycle, 1);    return cycle;  }  private String insertStateInputFromSM(Circuit dp, Instruction inst) {    return insertStateInputFromSM(dp, inst.getExecClkCnt(), 				  inst.getRunLength());  }  /**   * This method connects the definition of an operand to its use in the    * current cycle. Pipeline registers (or a single register) are added    * if necessary.  A string is returned with the name of the wire.   */  public String makeOpConnection(Circuit dp, String operand, int cur_cycle, 				 BlockNode bn, boolean isPredicate, 				 boolean isAddress) {    String wire_name = null;    Instruction def_inst = null;    int def_end_cycle = -1;    Operand result = null;    // this looks really bad -- it needs to be fixed.    /*      Why do we need to search through all the instructions?  What about      the def-use hashes?  Why can't we have the instruction?    */    // Find the most recent def of the current operand.    for(Iterator it = bn.getInstructions().iterator(); it.hasNext(); ) {      Instruction i_inst = (Instruction) it.next();      int i_start_cycle = i_inst.getExecClkCnt();      int i_end_cycle = i_start_cycle + (int)i_inst.getRunLength();      // Don't check any instructions that are scheduled later than       // the current instruction.      if(i_start_cycle > cur_cycle) break;      // but don't look at operands that aren't available yet      if(i_end_cycle > cur_cycle) continue;      // identify the instruction def      Operand i_result = AStore.conforms(i_inst)         ? AStore.getAddrDestination(i_inst) : i_inst.getOperand(0);      if(i_result.toString().equals(operand)) {	def_inst = i_inst;	def_end_cycle = i_end_cycle;        result = i_result;      }    }        //System.out.println(" Op "+operand);    //System.out.println("def_end_cycle "+def_end_cycle+" cur_cycle "+cur_cycle);    if(def_end_cycle == cur_cycle) {      // This is where immediate consumption of the LHS operand occurs.       // So, no registers are needed.      if(Load.conforms(def_inst))       	wire_name = Load.getSource(def_inst).getFullName();      else if(ALoad.conforms(def_inst))	wire_name = ALoad.getPrimalSource(def_inst).getFullName()+"_"+	  ALoad.getResult(def_inst).getFullName();      /*	wire_name = def_inst.getOperand(2).getFullName()+"_"+	  def_inst.getOperand(0).getFullName();      */      else       	wire_name = result.getFullName();    } else if((def_end_cycle < cur_cycle) && (def_end_cycle >= 0)) {      // This is where delayed consumption of the LHS operand occurs.  

⌨️ 快捷键说明

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