📄 circuit.java
字号:
/* * 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.circuit;import fp.util.Nameable;import fp.util.UniqueName;import java.util.*;import java.math.BigInteger;/** * This is a generic circuit object for generated other circuit * formats. It was originally developed for use with JHDL for the Sea * Cucumber synthesis tool. This is a simplified version that * hopefully removed some of the more tedious elements of the first * version. * * The Circuit object contains other _circuits, _nets, _nodes, and * _ports. there are some naming objects and a reference to its * parent. There are also several abstract methods that are to be * implemented by a circuit object of a specific technology. This * allows the circuits to be built using the generic abstract class * and then "build" the circuit in the underlying technology. This * allows several different backends to be targeted from the same * generic circuit object. * * @author Justin L. Tripp * @version $revision$ */public abstract class Circuit extends Nameable { int WIDTH = -1; int CONTROL = 1; /** * Subcircuits contained within this level of hierarchy. They may * also have subcircuits as well. */ private HashSet _circuits; /** * The wires contained within this circuit level. */ private HashSet _nets; /** * These are all of the leaf-nodes found at this level. These are * generally registers, operations, memories and the objects that * will have a definition outside of this circuit. */ private HashSet _nodes; /** * This hash is for easy differetiation between ports and other * nodes. All of the ports are contained within the node hash. */ private HashSet _ports; /** * This is a special hash for associating wires. */ private NetHash _nethash; /** * The parent of this level of heirarchy. If it is * <code>null</code>, then this is the highest level of heirarchy. */ private Circuit _parent; /** * This is the non-unique version of the name of level of the * circuit. */ private String _ref_name; // and if we are a leaf /** * This and parameters may be cruft from the idea that leaves in a * circuit, which are externally defined objects should be Circuits * and not Nodes. I am not so convinced now. */ private String _object; private Object[] _parameters; /** * For naming different elements in the circuit with unique names. */ private UniqueName _unique_names; /** * Wire name generation for this level of heirarchy. */ private UniqueName _wire_names; // hmmm ... /** * This is for naming nodes. Wires and nodes can have name * collisions, which is probably fine. */ private static UniqueName uname = new UniqueName("_"); /** * The main constructor for building Circuit heirachies. It creates * all of the datamembers that are necessary. * * @param parent CIrcuit's parent * @param name Name of this * level. */ public Circuit(Circuit parent, String name) { super(parent == null ? name : uname.getUniqueName(name)); _ref_name = name; _parent = parent; if (_parent != null) _parent.addCircuit(this); _circuits = new HashSet(); _nets = new HashSet(); _nodes = new HashSet(); _ports = new HashSet(); _nethash = new NetHash(this); _wire_names = new UniqueName(); _unique_names = new UniqueName(); } /** * This is the leaf version of the Circuit. The additional fields * in the constructor set the name of the object and parameters to * be passed to that object. They could also be extended to be used * however one feels necessary. * * @param parent Parent circuit * @param name Name * @param object Object that * defines behavior * @param parameters Parameters * to that behavior */ public Circuit(Circuit parent, String name, String object, Object[] parameters) { this(parent, name); _object = object; _parameters = parameters; // ??? -- we do not need them, but do we care ??? _nets = null; // ports -- still up in the air about ports. // may be the isLeaf() call should be _circuit == null ???? } /** * Simple accessor * * @return parent Circuit object */ public Circuit getParent() { return _parent; } /** * This tests to see if there are any subcircuits at this level of * heirachy. There still may be leaves of this circuit. * * @return true if there are no * subcircuits. */ public boolean isParent() { return _circuits.size() > 0; } /** * This is a test to see if there no subcircuits. It does not say * that there are no leaves (nodes). * * @return if size of the circuits is * zero */ public boolean isLeaf() { return _circuits.size() == 0; } // Nodes accessors and Methods /** * Add a node to the node hash. * * @param node A circuit Node. */ void addNode(Node node) { _nodes.add(node); } // this is not exclusive -- it may include subCircuits ... /** * Simple accessor. * * @return returns a reference to the * _nodes Hash. */ protected HashSet getNodes() { return _nodes; } /** * Simple accessor. * * @return Returns non-unique name. */ public String getRefName() { return _ref_name; } // Net accessors and methods /** * Adds a net to the net hash ... not to be confused with the * NetHash. :) * * @param net net to be added. */ void addNet(Net net) { _nets.add(net); } /** * Simple accessor. * * @return return simple hash of nets. */ protected HashSet getNets() { return _nets; } /** * Query the unique wire namer for a unique wire name. It is * important to choose a useful seed. * * @param seed Base name for wire. * @return unique ware name. */ public String getUniqueWireName(String seed) { return _wire_names.getUniqueName(seed); } /** * This is the lazy unique wire namer. It does not provide * insightful wire names. * * @return Unique wire name. */ public String getUniqueWireName() { return getUniqueWireName("net"); } /** * Gives access to unique names for elements in each circuit. */ public String getUniqueName() { return _unique_names.getUniqueName(""); } // ports /** * Simple accessor. * * @return port hash. */ public HashSet getPorts() { return _ports; } /** * Adds a port to the port hash. Since ports are also nodes, this * is only used for quick classification. * * @param p A port. */ void addPort(Port p) { _ports.add(p); } public Port getPortByName(String name) { for(Iterator iter = _ports.iterator(); iter.hasNext(); ) { Port p = (Port)iter.next(); // System.out.println(" Port :"+p+" matches ? "+name); if (p.getName().equals(name)) { return p; } } return (Port)null; } // sub graph accessors and methods /** * Adde a new sub circuit to this circuit. * * @param graph Circuit to be a child * of this circuit. */ public void addCircuit(Circuit graph) { _circuits.add( graph ); } /** * Simple accessor. * * @return This method returns a * reference to the circuit hash. */ protected HashSet getCircuits() { return _circuits; } /** * Simple accessor. * * @return the NetHash. */ protected NetHash getNetHash() { return _nethash; } /* Insert Object into circuit */ /** * This inserts a new circuit object with name. Since newCircuit is * abstract it will create the underlying circuit of the current * implementation technology. * * @param name New name. * @return the new Circuit. */ public Circuit insertCircuit(String name) { //new Exception("Building "+name).printStackTrace(); Circuit c = newCircuit(this, name); addCircuit(c); return c; } private String extendFpValue(String val, int width) { String extVal = new String(val); int hexLength = width/4; for(int i = 0; i < (hexLength - val.length()); i++) extVal = "0"+extVal; return extVal; } private Constant insertConstant(String name, String val, String out_name, int width, int type) { if (width <= 0) new CircuitException("insertConstant: Constant width too small <= 0"); Constant c = newConstant(this, name, val, width, type); PortTag out = c.addPort("out", PortTag.OUT, width); _nethash.addSource( out_name, out); // addConstant(c); return c; } public Constant insertConstant(String name, BigInteger val, String out_name, int width) { return insertConstant(name, val.toString(16), out_name, width, Constant.INT); } public Constant insertConstant(String name, int val, String out_name, int width) { BigInteger big = BigInteger.valueOf(val); return insertConstant(name, big, out_name, width); } public Constant insertConstant(String name, float val, String out_name, int width) { String constVal = Integer.toHexString(Float.floatToRawIntBits(val)); String extVal = (val < 0) ? constVal : extendFpValue(constVal, width); return insertConstant(name, extVal, out_name, width, Constant.FLOAT); } public Constant insertConstant(String name, double val, String out_name, int width) { String constVal = Long.toHexString(Double.doubleToRawLongBits(val)); String extVal = (val < 0) ? constVal : extendFpValue(constVal, width); return insertConstant(name, extVal, out_name, width, Constant.DOUBLE); } public FSM insertFSM(String name, LinkedList inputs, StateMachine transitions) { FSM f = newFSM(this, name, transitions); for(ListIterator list_iter = inputs.listIterator(); list_iter.hasNext(); ) { String input = (String)list_iter.next(); PortTag in = f.addInPort(input, CONTROL); _nethash.addSink(input, in); } for(int i=0; i< transitions.getStates(); i++) { String external = "s%"+i; String output = StateMachine.FSM_OUT + i; PortTag out = f.addOutPort(output, CONTROL); _nethash.addSource(external, out); } return f; } /** * This is a new Port insert method. It allows the wires and the * port to be declared all in one place. Wires in Circuit are soft, * so the wires are just names that one hopes actually meet up. * They will only meet up if the same name is used by both sources * and sinks. This is a double edged sword as it is easy, but it is * also easy to make a mistake. * * @param parent_net The net that * exists in the parent * @param name The name of the * portInfo in the Port. * @param child_net The net that * will exist in the child * @param width The size of the * portinfo in the Port * @return The new Port. */ public Port insertInPort(String parent_net, String name, String child_net, int width) { Port port = newPort(this, name, width, PortTag.IN); if (parent_net != null) { PortTag in = port.addPort("in", PortTag.IN, width); _parent.getNetHash().addSink(parent_net, in); } PortTag out = port.addPort("out", PortTag.OUT, width); _nethash.addSource(child_net, out); _ports.add(port); return port; } /** * This is the old way of inserting a port. It is tedious because * someone has to find the port and attach another wire to the other * side (in this case on the outside). The other method will allow * faster wiring of levels of heirachy. * * @param in_name The name of the new * Port * @param out_name The name of * the wire inside of the port * @param width size of the new * Port * @return The new port. */ public Port insertInPort(String in_name, String out_name, int width) { return insertInPort(null, in_name, out_name, width); } void insertParentPort(Node node, String name, int direction, int width) { PortTag port = node.addPort(name, direction, width); // hmm ? if (direction == PortTag.IN) { _nethash.addSink(name, port); insertInPort(name, name, name, width);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -