public SignExtend(UnaryOp cast) { Iterator<Port> ports = cast.getDataPorts().iterator(); Port d_port = ports.next(); assert (d_port.isUsed()) : "Operand port in unary operation is set to unused."; Bus d_bus = d_port.getBus(); assert (d_bus != null) : "Operand port in unary operation not attached to a bus."; PortWire pwire = new PortWire(d_port); if (pwire.getExpression() instanceof BaseNumber) { // input is a constant value, so the resize should be a no-op? } else { if (pwire.getExpression() instanceof Wire) { operand = (Wire) pwire.getExpression(); } else { operand = new Wire(ID.toVerilogIdentifier(ID.showLogical(cast)), d_port.getValue().getSize()); add(new Assign.Continuous(operand, new PortWire(d_port))); produced_nets.add(operand); } result_wire = NetFactory.makeNet(cast.getResultBus()); produced_nets.add(result_wire); int result_width = result_wire.getWidth(); /** unsigned value will be padded with zeros * */ add( new Assign.Continuous( result_wire, new org.xronos.openforge.verilog.pattern.SignExtend(operand, result_width))); } }
protected Bus duplicateBus(Component c, Bus bus) { Exit exit = getSidebandExit(c); Bus dup = exit.makeDataBus(Component.SIDEBAND); dup.setIDLogical(ID.showLogical(bus)); dup.copyAttributes(bus); return dup; }
Output(OutputPin opin, int nodeCount, int fontSize) { super(ID.showLogical(opin), nodeCount, fontSize); _graph.ln("Output Pin: " + opin); graph(opin, nodeCount++); Port p = opin.getPort(); Bus b = p.getBus(); graph(b.getOwner().getOwner(), nodeCount++); graphEdges(opin); }
Input(InputPin ipin, int nodeCount, int fontSize) { super(ID.showLogical(ipin), nodeCount, fontSize); graph(ipin, nodeCount++); _graph.ln("Input Pin: " + ipin); Bus b = ipin.getBus(); for (Port p : b.getPorts()) { Component c = p.getOwner(); graph(c, nodeCount++); graphEdges(c, b); } }
private static String getVerilogName(Object obj) { return ID.toVerilogIdentifier(ID.showLogical(obj)); }
private void generateKickers() { final GenericJob job = EngineThread.getGenericJob(); final boolean blockIO = !job.getUnscopedBooleanOptionValue(OptionRegistry.NO_BLOCK_IO); // If // Do // BlockIO final boolean doBlockSched = !job.getUnscopedBooleanOptionValue(OptionRegistry.SCHEDULE_NO_BLOCK_SCHEDULING); final boolean moduleBuilder = EngineThread.getGenericJob().getUnscopedBooleanOptionValue(OptionRegistry.MODULE_BUILDER); final Map<String, Kicker> kickers = new HashMap<String, Kicker>(); for (Task task : design.getTasks()) { final Call call = task.getCall(); final String domainSpec = (String) ((OptionString) EngineThread.getGenericJob().getOption(OptionRegistry.CLOCK_DOMAIN)) .getValue(call.getSearchLabel()); if (!task.isKickerRequired()) { // Ensure that the Go port is validly connected if (!call.getGoPort().isConnected()) { job.warn("Task " + call.showIDLogical() + " is not autostart and has no enabling signal"); Constant constant = new SimpleConstant(0, 1, false); constant.pushValuesForward(); call.getGoPort().setBus(constant.getValueBus()); call.getGoPort().pushValueForward(); } continue; } Kicker kicker; final String kickerKey; if (doBlockSched && !moduleBuilder) { // Connect up a KickerContinuous that will keep us running at // max rate indefinately. We expect only one task in block // io, but if we have more than one, we need individual // kickers so that we use the right clock/reset for each. kicker = new Kicker.KickerContinuous(); // Use the kickers string b/c there will be a (unique) // feedback from the task done kickerKey = kicker.toString(); } else if (blockIO) { boolean fbRequired = checkFeedback(call.getProcedure().getBody()); // System.out.println("Generated perpetual kicker withT/withoutF " // + fbRequired + " feedback flop required"); // Connect up a KickerPerpetual that will keep us running // indefinately. We expect only one task in block io, but // if we have more than one, each needs its own kicker // anyway (since we OR back in the done). We could use // just one kicker for all and put the OR external but // there is no Design level module to put this stuff in. // Argh! kicker = new Kicker.KickerPerpetual(fbRequired); // Use the kickers string b/c there will be a (unique) // feedback from the task done kickerKey = kicker.toString(); } else { if (moduleBuilder) { continue; } // find a kicker that matches this calls clk and reset // kickerKey = call.getClockName() + call.getResetName(); kickerKey = domainSpec; kicker = kickers.get(kickerKey); // if we didn't find it, construct a new one if (kicker == null) { kicker = new Kicker(); } } if (!kickers.containsKey(kickerKey)) { kickers.put(kickerKey, kicker); design.addComponentToDesign(kicker); design.getClockDomain(domainSpec).connectComponentToDomain(kicker); } if (call.getGoPort().isUsed()) { call.getGoPort().setBus(kicker.getDoneBus()); } if (kicker.getRepeatPort() != null) { Bus callDone = call.getExit(Exit.DONE).getDoneBus(); if (!callDone.isUsed()) { // there is the off-chance that it has fixed timing // and thus needs no done. Create a sequence of flops // to bypass. if (!call.getLatency().isFixed()) { EngineThread.getEngine() .fatalError( "Unexpected internal state. Design does not have a control structure and has variable timing"); } Bus done = kicker.getDoneBus(); for (int i = 0; i < call.getLatency().getMinClocks(); i++) { // Needs RESET b/c it is in the control path Reg flop = Reg.getConfigurableReg(Reg.REGR, ID.showLogical(call) + "_go_done_" + i); design.getClockDomain(domainSpec).connectComponentToDomain(flop); flop.getInternalResetPort().setBus(flop.getResetPort().getBus()); flop.getDataPort().setBus(done); // Ensure that we've constant propagated the flop flop.propagateValuesForward(); done = flop.getResultBus(); design.addComponentToDesign(flop); } callDone = done; } kicker.getRepeatPort().setBus(callDone); } } }