massive overhaul of fpga code
[fleet.git] / src / edu / berkeley / fleet / fpga / HornModule.java
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.*;
10 import java.util.*;
11 import java.io.*;
12 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
13 import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
14
15
16 public class HornModule extends Module {
17
18     public HornModule() {
19         this(PACKET_DEST.width-1,
20              PACKET_DEST.valmaskmax,
21              PACKET_DEST.valmaskmin,
22              0);
23     }
24     private HornModule(int top,
25                        int top_of_addr_field,
26                        int bot_of_addr_field,
27                        int bot) {
28         super("horn");
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);
33         out.connect(out0);
34         out.connect(out1);
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,
43                 });
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) });
48     }
49
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());
58             this.out0 = out0;
59             this.out1 = out1;
60             out0.addInput(this, getOutputPort("out0"));
61             out1.addInput(this, getOutputPort("out1"));
62         }
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?
74             return path1;
75         }
76     }
77
78 }