1 package edu.berkeley.fleet.fpga;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.two.*;
4 import edu.berkeley.fleet.*;
5 import java.lang.reflect.*;
6 import edu.berkeley.sbp.chr.*;
7 import edu.berkeley.sbp.misc.*;
8 import edu.berkeley.sbp.meta.*;
9 import edu.berkeley.sbp.util.*;
12 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
13 import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
16 public class HornModule extends Module {
19 this(PACKET_DEST.width-1,
20 PACKET_DEST.valmaskmax,
21 PACKET_DEST.valmaskmin,
24 private HornModule(int top,
25 int top_of_addr_field,
26 int bot_of_addr_field,
29 Module.SourcePort in = createInputPort("in", top+1);
30 Module.SinkPort out0 = createOutputPort("out0", top+1, "");
31 Module.SinkPort out1 = createOutputPort("out1", top+1, "");
32 Module.Latch out = new Module.Latch("out", top+1);
35 Value shifted_packet =
36 new CatValue(new Value[] {
37 (top_of_addr_field < top) ? in.getBits(top, top_of_addr_field+1) : null,
38 //in.getBits(bot_of_addr_field, bot_of_addr_field),
39 // we drop address bits instead of rotating to help synthesis eliminate unused junk
40 new SimpleValue("1'b0"),
41 in.getBits(top_of_addr_field, bot_of_addr_field+1),
42 (bot_of_addr_field > 0) ? in.getBits(bot_of_addr_field-1, 0) : null,
44 new Event(new Object[] { in, out0, out1, in.testBit(bot_of_addr_field, false) },
45 new Action[] { in, out0, new AssignAction(out, shifted_packet) });
46 new Event(new Object[] { in, out0, out1, in.testBit(bot_of_addr_field, true) },
47 new Action[] { in, out1, new AssignAction(out, shifted_packet) });
50 public static class HornInstance extends Module.InstantiatedModule implements FabricElement {
51 private FabricElement out0;
52 private FabricElement out1;
53 public void addInput(FabricElement in, Module.Port source) { source.connect(getInputPort("in")); }
54 public Module.SourcePort getOutputPort() { throw new RuntimeException("horn has multiple outputs"); }
55 public Module.Port getInputPort() { return getInputPort("in"); }
56 public HornInstance(Module thisModule, FabricElement out0, FabricElement out1) {
57 super(thisModule, new HornModule());
60 out0.addInput(this, getOutputPort("out0"));
61 out1.addInput(this, getOutputPort("out1"));
63 public void addOutput(FabricElement out, Module.Port outPort) { throw new RuntimeException(); }
64 public FpgaPath getPath(FabricElement dest, BitVector signal) {
65 FpgaPath path0 = out0==null ? null : out0.getPath(dest, signal);
66 FpgaPath path1 = out1==null ? null : out1.getPath(dest, signal);
67 if (path0 != null) path0 = path0.prepend(false);
68 if (path1 != null) path1 = path1.prepend(true);
69 if (path0==null) return path1;
70 if (path1==null) return path0;
71 if (path0.getLatencyMetric() < path1.getLatencyMetric()) return path0;
72 // FIXME: choke if latency metrics equal?
73 // FIXME: determinism of path-search?