support for both slow and fast fifos
authormegacz <adam@megacz.com>
Mon, 6 Apr 2009 18:33:58 +0000 (11:33 -0700)
committermegacz <adam@megacz.com>
Mon, 6 Apr 2009 18:33:58 +0000 (11:33 -0700)
src/edu/berkeley/fleet/fpga/FifoModule.java
src/edu/berkeley/fleet/fpga/ramfifo.inc

index 0741e0c..21ceab6 100644 (file)
@@ -15,16 +15,20 @@ import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
 public class FifoModule extends Module {
     private int len;
     private int width;
-    public FifoModule(int len, int width) {
-        super("fifo"+len+"x"+width);
+    private boolean doubleSpeed;
+    public FifoModule(int len, int width) { this(len, width, false); }
+    public FifoModule(int len, int width, boolean doubleSpeed) {
+        super("fifo"+len+"x"+width+(doubleSpeed?"_2x":""));
         this.len = len;
         this.width = width;
+        this.doubleSpeed = doubleSpeed;
         Module.SourcePort  in  = createInputPort("in", width);
         Module.SinkPort    out = createOutputPort("out", width);
         Module.InstantiatedModule[] stages = new Module.InstantiatedModule[len];
         if (len==0) {
             in.connect(out);
         } else if (len==1) {
+            if (doubleSpeed) throw new RuntimeException();
             new Event(new Object[] { in, out },
                       new Action[] { in, out, new AssignAction(out, in) });
         } else {
@@ -53,10 +57,16 @@ public class FifoModule extends Module {
             pw.println("`define ADDR_BITS "+dislog(len));
             pw.println("`define WIDTH " + width);
             pw.println("`define MODULE_NAME "+name);
+            if (doubleSpeed) {
+                pw.println("`define DELAY 2");
+            } else {
+                pw.println("`define DELAY 5");
+            }
             pw.println("`include \"ramfifo.inc\"");
             pw.flush();
             return;
         }
+        if (doubleSpeed) throw new RuntimeException();
 
         super.dump(prefix);
         return;
index 6e6e6af..ae7e394 100644 (file)
@@ -1,7 +1,7 @@
 module `MODULE_NAME(clk, rst, 
                in_r, in_a_, in_d,
                out_r_, out_a, out_d_); 
-    input  clk; 
+    input  clk;
     input  rst; 
     input  in_r;
     output in_a_;
@@ -34,6 +34,10 @@ module `MODULE_NAME(clk, rst,
     reg[3:0] addr;
     initial  addr = 4'b1111;
 
+    reg inchead;
+    reg inctail;
+    reg[3:0] count;
+
     genvar j;
     generate
       for(j=0; j<`WIDTH ; j=j+1) begin : OUTX
@@ -42,7 +46,7 @@ module `MODULE_NAME(clk, rst,
                         .A1 (addr[1]),
                         .A2 (addr[2]),
                         .A3 (addr[3]),
-                        .CE (in_r && !in_a && !control[0]),
+                        .CE (in_r && !in_a && !control[0] && count==0),
                         .CLK (clk),
                         .D (in_d[j]));
          defparam SRL16E.INIT = 0;
@@ -52,16 +56,20 @@ module `MODULE_NAME(clk, rst,
     assign controlx[(1<<`ADDR_BITS)-1] =
         !control[(1<<`ADDR_BITS)-1] ? control[(1<<`ADDR_BITS)-2] : (!out_r && !out_a) ? 0 : control[(1<<`ADDR_BITS)-1];
 
-    reg inchead;
-    reg inctail;
-
     always @(posedge clk) begin 
         if (rst) begin
           out_r <= 0;
           in_a <= 0;
           control <= 0;
           addr <= 4'b1111;
+
+        end else if (count!=0) begin
+          count <= count-1;
+
         end else begin
+
+          count <= `DELAY;
+
           inchead = 0;
           inctail = 0;
           if (!in_r && in_a) in_a <= 0;