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

📄 datapathcircuitgenerator.java

📁 一种将c高级语言转化给VHDL的编译器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * LA-CC 05-135 Trident 0.7.1Copyright NoticeCopyright 2006 (c) the Regents of the University of California.This Software was produced under a U.S. Government contract(W-7405-ENG-36) by Los Alamos National Laboratory, which is operatedby the University of California for the U.S. Department of Energy. TheU.S. Government is licensed to use, reproduce, and distribute thisSoftware. Permission is granted to the public to copy and use thisSoftware without charge, provided that this Notice and any statementof authorship are reproduced on all copies. Neither the Government northe University makes any warranty, express or implied, or assumes anyliability or responsibility for the user of this Software. */package fp.synthesis;import fp.circuit.*;import fp.flowgraph.*;import fp.flowgraph.Operator;import fp.util.BooleanEquation;import fp.util.BooleanOp;import fp.hardware.*;import fp.hwdesc.Memory;import java.util.*;//import java.lang.Integer;import java.math.BigInteger;public final class DataPathCircuitGenerator extends DesignCircuitGenerator {  /**   * This class generates the datapath part of the abstract circuit.  The    * datapath exists inside of a block circuit along with the state machine.    */  private static final int ADDR_WIDTH = 32;  private HashMap _blockOutWires;  private HashSet _dpOutWires;  private HashSet _dpInWires;  private HashSet _dpInvWires;  private HashSet _blkWires;  private HashMap _dpRegisters;  private HashMap _predicateWires;  DataPathCircuitGenerator() {    super();    _blockOutWires = new HashMap();    _dpOutWires = new HashSet();    _dpInWires = new HashSet();    _dpInvWires = new HashSet();    _blkWires = new HashSet();    _dpRegisters = new HashMap();    _predicateWires = new HashMap();  }  /**   * This method has two purposes:   * 1) create a data path sub-circuit in this block's circuit   * 2) create the logic for each instruction in this block node    * It returns a HashSet containing the names of the wires that should    * be connected to the register file.   */  public HashSet generate(Circuit blockLevel, BlockNode cfgBlockNode, 			  ChipDef chipInfo) {    _circuit = blockLevel.insertCircuit("dp_"+blockLevel.getName());      for(Iterator it=cfgBlockNode.getInstructions().iterator();it.hasNext(); ) {      Instruction current = (Instruction) it.next();      Operator operator = current.operator;      //System.out.println("-- inst type: " + current.type()+"  "+operator.format+" "+current);      // Create the logic based on what the current operator is...      switch(operator.format) {      case InstructionFormat.Store_format:	caseStore(_circuit, current, cfgBlockNode);	break;      case InstructionFormat.Load_format:	caseLoad(_circuit, current, cfgBlockNode);	break;      case InstructionFormat.Select_format:	caseSelect(_circuit, current, cfgBlockNode);	break;      case InstructionFormat.Test_format:	caseTest(_circuit, current, cfgBlockNode);	break;      case InstructionFormat.Unary_format:	caseUnary(_circuit, current, cfgBlockNode);	break;      case InstructionFormat.Binary_format:	caseBinary(_circuit, current, cfgBlockNode);	break;      case InstructionFormat.Cast_format:	caseCast(_circuit, current, cfgBlockNode);	break;      case InstructionFormat.ALoad_format:	caseALoad(_circuit, current, cfgBlockNode, chipInfo);	break;      case InstructionFormat.AStore_format:	caseAStore(_circuit, current, cfgBlockNode, chipInfo);	break;      default:	System.out.println("Operator("+current.operator+") not yet supported");	continue;      }    }       _circuit.insertInPort("reset", "i_reset", "reset", 1);    _circuit.insertInPort("clk", "i_clk", "clk", 1);    return makeBlockOutPorts(blockLevel);  }  /**   * This method creates a mux, which is used to control the data flowing    * out of the datapath/block. It also creates an outport from the datapath   * to the block level for the write enable logic.   *    * This is only used in array loads and stores...   */  private String makeMuxLogic(Circuit dp, Instruction inst, 			      String blkEn, BlockNode bn, 			      boolean isAddress) {    int startCycle = inst.getExecClkCnt();    //int width = inst.type().getWidth();    int width = (isAddress) ? ADDR_WIDTH :                               inst.type().getWidth();    float runLength = inst.getRunLength();    BooleanEquation pred = inst.getPredicate();    Circuit block = dp.getParent();    // Add an inport to get info from the state machine.    String cycle = null;     if(isAddress)  // Use the starting cycle if aload/astore address write..      cycle = insertStateInputFromSM(dp, startCycle, 0);    else           // Otherwise use the ending cycle.      cycle = insertStateInputFromSM(dp, startCycle, runLength);        // Make the conditions for asserting the enable line.    String en = null;    if(pred.isTrue()) {      // Add a buffer for the state machine cycle input.      // makeLogicTree should deal with this.      en = cycle;    } else if(pred.isFalse()) {      // Make a zero (invalid) output.      String zeroOut = block.getUniqueWireName();      Constant zeroConst = block.insertConstant("c_0", 0, zeroOut, width);      en = zeroOut;    } else {      // Otherwise, predicate is not yet known; so make some logic...      String predName = makePredicateLogic(dp, pred, startCycle, bn);      LinkedList inputs = new LinkedList();      if(predName != null) {	// Only add the predicate input if the predicate has been	// already defined in a previous cycle...        inputs.add(predName);	inputs.add(cycle);	// Make a logic tree of the above predicate logic.	en = makeLogicTree(dp, Operation.AND, inputs, 1);      } else {	en = cycle;      }    }    // Make an "en" port from the DP to the block level.    Operand operand = null;    Operand address = null;    if(AStore.conforms(inst)) {      operand = AStore.getPrimalDestination(inst);      address = AStore.getAddrDestination(inst);      //S      //operand = (isAddress) ? AStore.getValue(inst) : AStore.getPrimalDestination(inst);      //address = AStore.getAddrDestination(inst);    } else if(ALoad.conforms(inst)) {      //S      //operand = ALoad.getPrimalSource(inst);      //address = ALoad.getAddrSource(inst);      operand = (isAddress) ? inst.getOperand(1) : inst.getOperand(0);      address = ALoad.getAddrSource(inst);    } else {  // CHANGE:  is this correct?  should it always be operand(0)?            // if it is not an ALOAD and not an ASTORE, where does the address       // come from and who cares ?      operand = (isAddress) ? inst.getOperand(1) : inst.getOperand(0);    }    //System.out.println("mux operand:  "+operand);    String name = operand.getFullName();    //String blkEn = block.getUniqueWireName(name)+"_we";    insertOutPort(dp, en, "o_"+blkEn, blkEn, 1);    // Make a zero (invalid) output.    String zeroOut2 = "z_"+block.getUniqueWireName();    block.insertConstant("c_0", 0, zeroOut2, width);    // mux the invalid and valid data_out signals    String muxName = "mux_"+cycle+block.getUniqueName();    String muxIn = null;    String muxOut = null;    if(isAddress) {      muxOut = address.getFullName()+block.getUniqueName();    } else {      muxOut = name+"_"+cycle;    }    if(AStore.conforms(inst))      muxIn = (isAddress)         ? getOpName(dp, inst, AStore.getAddrDestination(inst), true, bn, true)         : getOpName(dp, inst, AStore.getValue(inst), true, bn, false);    else      muxIn = getOpName(dp, inst, inst.getOperand(1), true, bn, isAddress);    //System.out.println(inst+" result MuxIn "+muxIn);    insertMux(block, muxName, zeroOut2, muxIn, blkEn, muxOut, width);    return muxOut;  }    /*    This is currently only used by caseStore ...  */  private String makeDataMuxLogic(Circuit dp, Instruction inst, 				  String blkEn, BlockNode bn) {    return makeMuxLogic(dp, inst, blkEn, bn, false);  }  /**   * This method builds connection logic between the datapath and the memory    * interface.  This includes an address write and data read path of wires.   */  private void caseALoad(Circuit dpCircuit, Instruction inst, 			 BlockNode bn, ChipDef chipInfo) {    System.out.println("caseAload: "+inst);    Circuit block = dpCircuit.getParent();    Circuit top = block.getParent();    Operand arrayOp = ALoad.getPrimalSource(inst);    Operand addrOp = ALoad.getAddrSource(inst);    // Create the guard logic for writing the address to the membus.    String addrEn = block.getUniqueWireName(addrOp.getFullName()) + "_we";    String addrOut = makeMuxLogic(dpCircuit, inst, addrEn, bn, true);    // Connect the address block in the datapath to the memory bus'     // address read port (actually just make ports/wires up to the     // top level).    // this mixing of wires and names is not good ...    String topUnique = top.getUniqueName();    String topAddrWire = arrayOp.getFullName()+topUnique;    // Fix up the address width.    String portIn = null;    int addrWidth = MemoryInterfaceGenerator.ADDR_WIDTH;    if(addrWidth < ADDR_WIDTH) {      portIn = "slice"+block.getUniqueName();      insertSlice(block, portIn, addrOut, 0, 		  addrWidth-1, portIn, ADDR_WIDTH, 		  addrWidth);    } else {      portIn = addrOut;    }    // Make outports for the address and write enable.    block.insertOutPort(portIn, 			"o_"+addrOp.getFullName()+block.getUniqueName(), 			topAddrWire, addrWidth);    //String addrWe = addrOp.getFullName()+"_we";    String addrWe = addrEn;     Port p = block.getPortByName("o_"+addrWe);    block.insertOutPort(addrWe,"o_"+addrWe+block.getUniqueName(), topAddrWire+"_we", 1);    // Connect the data between the memory bus and datapath.    Operand resultOp = ALoad.getResult(inst);    String dpDataWire = arrayOp.getFullName()+"_"+resultOp.getFullName();    String blockDataWire = arrayOp.getFullName()+block.getUniqueName();    Memory mb = chipInfo.findMemoryBlock(arrayOp);    String memName = mb.getName();    String topDataWire = arrayOp.getFullName()+top.getUniqueName();    block.insertInPort(topDataWire, "i_"+blockDataWire, 		       blockDataWire, inst.type().getWidth());    dpCircuit.insertInPort(blockDataWire,"i_"+dpDataWire, dpDataWire, 			   inst.type().getWidth());    // Add this memory access to the memory interface data structure.    String blkName = bn.getLabel().getFullName();    _memory.addMemoryAccess(memName, blkName, topAddrWire, topDataWire,			    MemoryInterfaceGenerator.ADDR_WIDTH, 			    inst.type().getWidth(),			    inst.getExecClkCnt(), 			    MemoryInterfaceGenerator.LOAD);  }  private void caseAStore(Circuit dpCircuit, Instruction inst, 			  BlockNode bn, ChipDef chipInfo) {    Circuit block = dpCircuit.getParent();    Circuit top = block.getParent();    Operand addrOp = AStore.getAddrDestination(inst);    Operand arrayOp = AStore.getPrimalDestination(inst);    String addrEn = block.getUniqueWireName(arrayOp.getFullName())+"_we";    // Create the guard logic for writing the address to the memory interface.    String addrOut = makeMuxLogic(dpCircuit, inst, addrEn, bn, true);    // Create the guard logic for writing the data to the memory interface.    String dataOut = makeMuxLogic(dpCircuit, inst, addrEn, bn, false);    int dataWidth = inst.type().getWidth();    String extendOut = dataOut+"_ext";    insertZeroExtend(block, "zextend_"+dataOut, dataOut, extendOut, 		     dataWidth, MemoryInterfaceGenerator.DATA_WIDTH);    // Connect the address in the datapath to the memory interface.    String topAddrWire = addrOp.getFullName()+top.getUniqueName();    int memWidth = MemoryInterfaceGenerator.ADDR_WIDTH;    String portIn = null;    if(memWidth < ADDR_WIDTH) {      portIn = addrOut + "_s";      insertSlice(block, "slice_"+portIn, addrOut, 0, memWidth-1, portIn, 		  ADDR_WIDTH, memWidth);    } else {      portIn = addrOut;    }    block.insertOutPort(portIn, 			"o_"+addrOp.getFullName()+block.getUniqueName(), 			topAddrWire, MemoryInterfaceGenerator.ADDR_WIDTH);    // Connect the data in the datapath to the memory interface.    String topDataWire = arrayOp.getFullName()+top.getUniqueName();    block.insertOutPort(extendOut, 			"o_"+arrayOp.getFullName()+block.getUniqueName(),			topDataWire, MemoryInterfaceGenerator.DATA_WIDTH);    String we = topDataWire+"_we";    block.insertOutPort(addrEn, "o_"+we, we, 1);    // Add this memory access to the memory interface data structures.    String blkName = bn.getLabel().getFullName();    String memName = chipInfo.findMemoryBlock(arrayOp).getName();    _memory.addMemoryAccess(memName, blkName, topAddrWire, topDataWire, 			    MemoryInterfaceGenerator.ADDR_WIDTH, 			    MemoryInterfaceGenerator.DATA_WIDTH, 			    inst.getExecClkCnt(), 			    MemoryInterfaceGenerator.STORE);  }  /**   * This method implements all of the binary operators that occur in the    * control flow graph.   */  private void caseBinary(Circuit dpCircuit, Instruction inst, 			  BlockNode bn) {    Operand source1 = Binary.getVal1(inst);    Operand source2 = Binary.getVal2(inst);    Operand result = Binary.getResult(inst);    Operation op = library.select(inst);    // If the operation is handled, then insert it.    if(op != null) {      String out_name = result.getFullName();      String op_name = "op_"+inst.operator()	               + dpCircuit.getUniqueName();      // Case where a binary inst's result is a primal.      if(result.isPrimal())	throw new SynthesisException("caseBinary(): primal result found");      dpCircuit.insertOperator(op, op_name, 			       getOpName(dpCircuit, inst, source1, false, bn),			       getOpName(dpCircuit, inst, source2, false, bn),			       out_name, inst.type().getWidth());    } else {      throw new SynthesisException("Binary operator not yet supported: "+				   inst.operator());    }  }  private void caseCast(Circuit dpCircuit, Instruction inst, BlockNode bn) {    //System.out.println("caseCast():  "+inst);    Operand source = Cast.getValue(inst);    Operand target = Cast.getResult(inst);

⌨️ 快捷键说明

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