import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
public class FifoModule extends Module {
- public FifoModule(int len) {
- super("fifo"+len);
- Module.SourcePort in = createInputPort("in", WIDTH_PACKET);
- Module.SinkPort out = createOutputPort("out", WIDTH_PACKET, "");
+ private int len;
+ private int width;
+ public FifoModule(int len, int width) {
+ super("fifo"+len+"x"+width);
+ this.len = len;
+ this.width = width;
+ Module.SourcePort in = createInputPort("in", width);
+ Module.SinkPort out = createOutputPort("out", width, "");
Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
if (len==0) {
+ in.hasLatch = false;
+ out.hasLatch = false;
+ addPreCrap("assign out = in;");
+ addPreCrap("assign out_r = in_r;");
+ addPreCrap("assign in_a = out_a;");
+ } else if (len==1) {
new Event(new Object[] { in, out },
new Action[] { in, out, new AssignAction(out, in) });
} else {
- Module fifo0 = new FifoModule(0);
+ Module fifo1 = new FifoModule(1,width);
for(int i=0; i<=len; i++) {
- if (i<len) stages[i] = new Module.InstantiatedModule(this, fifo0);
+ if (i<len) stages[i] = new Module.InstantiatedModule(this, fifo1);
Module.SourcePort driver = i==0 ? in : stages[i-1].getOutputPort("out");
Module.SinkPort driven = i==len ? out : stages[i].getInputPort("in");
driver.connect(driven);
}
}
}
+
+ int dislog(int num) {
+ for(int i=0; i<32; i++)
+ if ((1<<i) >= num)
+ return i;
+ throw new RuntimeException();
+ }
+
+ public void dump(String prefix) throws IOException {
+ if (len>16) throw new RuntimeException("FifoModule(i>16) not supported due to SRL16 limitation");
+ if (len<2) {
+ super.dump(prefix);
+ return;
+ }
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
+ pw.println("`define ADDR_BITS "+dislog(len));
+ pw.println("`define WIDTH " + width);
+ pw.println("`define MODULE_NAME "+name);
+ pw.println("`include \"ramfifo.inc\"");
+ pw.flush();
+ }
}