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", WIDTH_PACKET);
30 Module.SinkPort out0 = createOutputPort("out0", WIDTH_PACKET, "");
31 Module.SinkPort out1 = createOutputPort("out1", WIDTH_PACKET, "");
32 Module.Latch out = new Module.Latch("out", WIDTH_PACKET);
33 out0.forceNoLatch = true;
34 out1.forceNoLatch = true;
35 addCrap("assign out0 = out;");
36 addCrap("assign out1 = out;");
37 String shifted_packet = "{ ";
38 if (top_of_addr_field < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
39 shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
40 if (bot_of_addr_field > 0) shifted_packet += ", in["+(bot_of_addr_field-1)+":0] ";
41 shifted_packet += " }";
42 new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
43 new Action[] { in, out0, new AssignAction(out, shifted_packet) });
44 new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
45 new Action[] { in, out1, new AssignAction(out, shifted_packet) });
48 public static class HornInstance extends Module.InstantiatedModule implements FabricElement {
49 private FabricElement out0;
50 private FabricElement out1;
51 public void addInput(FabricElement in, Module.Port source) { source.connect(getInputPort("in")); }
52 public Module.Port getOutputPort() { throw new RuntimeException("horn has multiple outputs"); }
53 public Module.Port getInputPort() { return getInputPort("in"); }
54 public HornInstance(Module thisModule, FabricElement out0, FabricElement out1) {
55 super(thisModule, new HornModule());
58 out0.addInput(this, getOutputPort("out0"));
59 out1.addInput(this, getOutputPort("out1"));
61 public void addOutput(FabricElement out, Module.Port outPort) { throw new RuntimeException(); }
62 public FpgaPath getPath(FabricElement dest, BitVector signal) {
63 FpgaPath path0 = out0==null ? null : out0.getPath(dest, signal);
64 FpgaPath path1 = out1==null ? null : out1.getPath(dest, signal);
65 if (path0 != null) path0 = path0.prepend(false);
66 if (path1 != null) path1 = path1.prepend(true);
67 if (path0==null) return path1;
68 if (path1==null) return path0;
69 if (path0.getLatencyMetric() < path1.getLatencyMetric()) return path0;
70 // FIXME: choke if latency metrics equal?
71 // FIXME: determinism of path-search?