ee7d4a640f4a5f6fe4ba0306a4246fa5bc1438e0
[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",    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) });
46     }
47
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());
56             this.out0 = out0;
57             this.out1 = out1;
58             out0.addInput(this, getOutputPort("out0"));
59             out1.addInput(this, getOutputPort("out1"));
60         }
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?
72             return path1;
73         }
74     }
75
76 }