massive overhaul of fpga code
authoradam <adam@megacz.com>
Thu, 21 Aug 2008 10:32:31 +0000 (11:32 +0100)
committeradam <adam@megacz.com>
Thu, 21 Aug 2008 10:32:31 +0000 (11:32 +0100)
33 files changed:
src/edu/berkeley/fleet/fpga/Client.java
src/edu/berkeley/fleet/fpga/FabricElement.java
src/edu/berkeley/fleet/fpga/FifoModule.java
src/edu/berkeley/fleet/fpga/Fpga.java
src/edu/berkeley/fleet/fpga/FpgaDestination.java
src/edu/berkeley/fleet/fpga/FpgaDock.java
src/edu/berkeley/fleet/fpga/FpgaPath.java
src/edu/berkeley/fleet/fpga/FpgaShip.java
src/edu/berkeley/fleet/fpga/FunnelModule.java
src/edu/berkeley/fleet/fpga/HornModule.java
src/edu/berkeley/fleet/fpga/bram.inc [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/bram14.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/empty.vhd [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/fifo.inc [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/macros.v [deleted file]
src/edu/berkeley/fleet/fpga/main.ucf
src/edu/berkeley/fleet/fpga/main.v
src/edu/berkeley/fleet/fpga/main.xst
src/edu/berkeley/fleet/fpga/mem/async_fifo.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/ddr_clkgen.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/ddr_ctrl.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/ddr_include.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/ddr_init.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/ddr_pulse78.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/ddr_rpath.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/ddr_wpath.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/gray_counter.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/rotary.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/mem/wb_vga.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/ramfifo.inc [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/ramfifo8.v [new file with mode: 0644]
src/edu/berkeley/fleet/fpga/verilog/Verilog.java
src/edu/berkeley/fleet/fpga/vram.v [new file with mode: 0644]

index 709ce15..c563917 100644 (file)
@@ -49,6 +49,7 @@ public class Client extends FleetProcess {
         this.fpga = fpga;
 
         s = new Socket(InetAddress.getByName("goliath.megacz.com"), 3133);
+        //s = new Socket(InetAddress.getByName("localhost"), 3133);
         OutputStream os = new BufferedOutputStream(s.getOutputStream());
         PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
         pw.print(Server.pass_string+" "+bitfile+"\n");
index 59de514..d5a4c9b 100644 (file)
@@ -20,6 +20,6 @@ public interface FabricElement {
     public void addInput(FabricElement in, Module.Port inPort);
     public void addOutput(FabricElement out, Module.Port outPort);
 
-    public Module.Port getOutputPort();
+    public Module.SourcePort getOutputPort();
     public Module.Port getInputPort();
 }
index 3cb6bc5..26e75c7 100644 (file)
@@ -13,22 +13,53 @@ import static edu.berkeley.fleet.two.FleetTwoFleet.*;
 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();
+    }
 }
index 7b113ac..86d13e8 100644 (file)
@@ -15,8 +15,24 @@ import static edu.berkeley.fleet.two.FleetTwoFleet.*;
 import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
 
 
+/*
+=> get rid of getInputPort(String) and instead use members
+=> clean up fabricelement methods
+=> get rid of addcrap
+=> automatic width-setting on ports
+=> nuke DATAWIDTH?
+  => serdes and fastclock/slowclock?
+*/
+
 public class Fpga extends FleetTwoFleet {
 
+    public  Module top;
+    public  FabricElement top_horn;
+    Ship debugShip;
+
+    public LinkedHashMap<String,FpgaShip> ships = new LinkedHashMap<String,FpgaShip>();
+    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
+
     public Ship getShip(String type, int ordinal) {
         for(Ship s : this)
             if (s.getType().equals(type))
@@ -25,28 +41,8 @@ public class Fpga extends FleetTwoFleet {
         return null;
     }
 
-    public int getWordWidth() { return 37; }
-
-    public Module top;
-    public FabricElement top_horn;
-
-    public LinkedHashMap<String,FpgaShip> ships = new LinkedHashMap<String,FpgaShip>();
-    public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)ships.values().iterator(); }
-
     public static void main(String[] s) throws Exception { 
-        String prefix = s[0];
-
-        new FunnelModule().dump(prefix);
-        new HornModule().dump(prefix);
-
-        new FifoModule(0).dump(prefix);
-        new FifoModule(4).dump(prefix);
-        new FifoModule(8).dump(prefix);
-        new FpgaDock.DockModule(false).dump(prefix);
-        new FpgaDock.DockModule(true).dump(prefix);
-
-        Module top = new Module("root");
-        new Fpga(top).top.dump(prefix);
+        new Fpga(new Module("root")).top.dump(s[0]);
     }
 
     public FleetProcess run(Instruction[] instructions) {
@@ -68,35 +64,85 @@ public class Fpga extends FleetTwoFleet {
     public Fpga(Module top) throws Exception {
         this.top = top;
         debugShip = createShip("Debug",     "debug");
-        createShip("Memory",    "memory");
-        createShip("Fifo",      "fifo1");
-        createShip("Fifo",      "fifo2");
-        createShip("Alu2",      "alu2a");
+
+        int LANES = 6;
+
+        createShip("Memory",    "memory1");
+
+        if (LANES>1)
+            createShip("Memory",    "memory2");
+
+        for(int i=0; i<LANES; i++) {
+            createShip("Fifo",      "fifo"+i);
+            createShip("Fifo",      "fifo"+i+"x");
+            createShip("Alu2",      "alu"+i);
+            createShip("Alu2",      "alu"+i+"x");
+        }
         createShip("Rotator",   "rotator");
-        //createShip("Alu1",      "alu1");
-        createShip("Lut3",      "lut3");
-        createShip("Alu3",      "alu3");
-
-        Module fifostage = new FifoModule(0);
-        Module fifo4     = new FifoModule(4);
-        Module fifo8     = new FifoModule(8);
-        Module horn      = new HornModule();
-        Module funnel    = new FunnelModule();
-        Module outbox    = new FpgaDock.DockModule(false);
-        Module inbox     = new FpgaDock.DockModule(true);
-
-        Module.SinkPort    debug_in    = top.createWirePort("debug_in", WIDTH_PACKET);
+        createShip("Lut3",      "lut");
+
+        if (LANES<=1)
+            createShip("Fifo",      "fifo_extra");
+
+        createShip("DRAM",    "dram");
+        createShip("Video",   "video");
+
+        //Module.SourcePort  debug_in    = top.createWireSourcePort("debug_in", WIDTH_PACKET);
         Module.SourcePort  debug_out   = null;
         for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
             if (ship.getType().toLowerCase().equals("debug"))
                 debug_out = ship.getVerilogModule().getOutputPort("debug_out");
         }
 
+        // for FifoShip
+        new Module.InstantiatedModule(top, new FifoModule(8, WIDTH_WORD));
+
         Module.SourcePort  in          = top.createInputPort("in", 8);
         Module.SinkPort    out         = top.createOutputPort("out", 8, "");
         Module.Latch       temp_in     = top.new Latch("temp", WIDTH_PACKET) { public String doReset() { return name+"=0;"; } };
         Module.Latch       count       = top.new Latch("count", 8);
         Module.Latch       count_out   = top.new Latch("count_out", 8);
+
+        ArrayList inbox_sources = new ArrayList<FabricElement>();
+        ArrayList inbox_dests   = new ArrayList<FabricElement>();
+        ArrayList outbox_sources = new ArrayList<FabricElement>();
+        ArrayList outbox_dests   = new ArrayList<FabricElement>();
+        ArrayList instruction_dests   = new ArrayList<FabricElement>();
+        int numdocks = 0;
+        for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
+            if (ship.getType().toLowerCase().equals("debug"))
+                debug_out = ship.getVerilogModule().getOutputPort("debug_out");
+            for(Dock port : ship) {
+                if (port.isInputDock()) {
+                    inbox_sources.add(((FpgaDock)port));
+                    instruction_dests.add(port.getInstructionDestination());
+                    inbox_dests.add(port.getDataDestination());
+                } else {
+                    outbox_sources.add(((FpgaDock)port));
+                    instruction_dests.add(port.getInstructionDestination());
+                    outbox_dests.add(port.getDataDestination());
+                }
+                numdocks++;
+            }
+        }
+        //System.err.println("dock count = " + numdocks);
+        ArrayList dests   = new ArrayList<FabricElement>();
+        ArrayList sources = new ArrayList<FabricElement>();
+        sources.addAll(inbox_sources);
+        sources.addAll(outbox_sources);
+        dests.addAll(inbox_dests);
+        dests.addAll(instruction_dests);
+        dests.addAll(outbox_dests);
+        top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true);
+        FabricElement   source  = mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false);
+        FunnelModule.FunnelInstance top_funnel = new FunnelModule.FunnelInstance(top, null, source.getOutputPort());
+        ((FunnelModule.FunnelInstance)source).out = top_funnel;
+        //top_horn.addInput(top_funnel, top_funnel.getOutputPort());
+        top_funnel.addOutput(top_horn, top_horn.getInputPort());
+
+        //Module.SourcePort  debug_in    = top.createWireSourcePort("debug_in", WIDTH_PACKET);
+        Module.SinkPort debug_in = top_funnel.getInputPort("in1");
+
         top.new Event(new Object[] { in, debug_in },
                       new Object[] { new SimpleAction(temp_in.getVerilogName()+" = ("+temp_in.getVerilogName()+" << 8) | in;"),
                                      new SimpleAction("if (count >= 5) begin"+
@@ -115,23 +161,6 @@ public class Fpga extends FleetTwoFleet {
                                                           " else count_out <= count_out+1; "),
                                      out });
 
-        ArrayList sources = new ArrayList<FabricElement>();
-        ArrayList dests   = new ArrayList<FabricElement>();
-        for(FpgaShip ship : (Iterable<FpgaShip>)(Object)this) {
-            if (ship.getType().toLowerCase().equals("debug"))
-                debug_out = ship.getVerilogModule().getOutputPort("debug_out");
-            for(Dock port : ship) {
-                sources.add(((FpgaDock)port));
-                dests.add(port.getInstructionDestination());
-                dests.add(port.getDataDestination());
-            }
-        }
-        top_horn = mkNode((FabricElement[])dests.toArray(new FabricElement[0]), true);
-        FabricElement   source  = mkNode((FabricElement[])sources.toArray(new FabricElement[0]), false);
-        FunnelModule.FunnelInstance top_funnel = new FunnelModule.FunnelInstance(top, debug_in, source.getOutputPort());
-        ((FunnelModule.FunnelInstance)source).out = top_funnel;
-        //top_horn.addInput(top_funnel, top_funnel.getOutputPort());
-        top_funnel.addOutput(top_horn, top_horn.getInputPort());
     }
 
     public FabricElement mkNode(FabricElement[] ports, boolean is_horn) { return mkNode(ports, is_horn, 0, ports.length); }
@@ -166,10 +195,15 @@ public class Fpga extends FleetTwoFleet {
 
             boolean auto = !"debug".equals(filename);
 
-            if (auto) {
-                pw.println("`include \"macros.v\"");
-                pw.println();
+            pw.println("`include \"bitfields.v\"");
+            pw.println("`define defreg(signame,width,regname) reg width regname; wire width signame;  assign signame = regname; initial regname = 0;");
+            pw.println("`define input(r, a, a_, w, d)  input r;  output a_; reg a; assign a_=a; input  w d; initial a=0;");
+            pw.println("`define output(r, r_, a, w, d) output r_; input a;  reg r; assign r_=r; output w d; initial r=0;");
+            pw.println("`define onread(req, ack)        if (!req && ack) ack <= 0;    else if (req && !ack)  begin ack <=1;");
+            pw.println("`define onwrite(req, ack)       if (!req && !ack) req <= 1; else if (req && ack)   begin req <= 0;");
+            pw.println();
 
+            if (auto) {
                 pw.print("`define reset ");
                 for(DockDescription bb : sd) {
                     String bb_name = bb.getName();
@@ -193,13 +227,64 @@ public class Fpga extends FleetTwoFleet {
                     }
                     pw.println();
                 }
+                if (filename.equals("dram")) {
+                    pw.println("    , dram_addr_");
+                    pw.println("    , dram_addr_r_");
+                    pw.println("    , dram_addr_a");
+                    pw.println("    , dram_isread_");
+                    pw.println("    , dram_write_data_");
+                    pw.println("    , dram_write_data_push_");
+                    pw.println("    , dram_write_data_full");
+                    pw.println("    , dram_read_data");
+                    pw.println("    , dram_read_data_pop_");
+                    pw.println("    , dram_read_data_empty");
+                    pw.println("    , dram_read_data_latency");
+                }
+                if (filename.equals("video")) {
+                    pw.println("    , vga_clk");
+                    pw.println("    , vga_psave");
+                    pw.println("    , vga_hsync");
+                    pw.println("    , vga_vsync");
+                    pw.println("    , vga_sync");
+                    pw.println("    , vga_blank");
+                    pw.println("    , vga_r");
+                    pw.println("    , vga_g");
+                    pw.println("    , vga_b");
+                    pw.println("    , vga_clkout");
+                }
                 pw.println("        );");
                 pw.println();
                 pw.println("    input clk;");
                 pw.println("    input rst;");
+                if (filename.equals("dram")) {
+                    pw.println("output  [31:0] dram_addr_;");
+                    pw.println("output         dram_addr_r_;");
+                    pw.println("input          dram_addr_a;");
+                    pw.println("output         dram_isread_;");
+                    pw.println("output  [63:0] dram_write_data_;");
+                    pw.println("output         dram_write_data_push_;");
+                    pw.println("input          dram_write_data_full;");
+                    pw.println("input   [63:0] dram_read_data;");
+                    pw.println("output         dram_read_data_pop_;");
+                    pw.println("input          dram_read_data_empty;");
+                    pw.println("input   [1:0]  dram_read_data_latency;");
+                }
+                if (filename.equals("video")) {
+                    pw.println("input          vga_clk;");
+                    pw.println("output         vga_psave;");
+                    pw.println("output         vga_hsync;");
+                    pw.println("output         vga_vsync;");
+                    pw.println("output         vga_sync;");
+                    pw.println("output         vga_blank;");
+                    pw.println("output   [7:0] vga_r;");
+                    pw.println("output   [7:0] vga_g;");
+                    pw.println("output   [7:0] vga_b;");
+                    pw.println("output         vga_clkout;");
+                }
                 for(DockDescription bb : sd) {
                     String bb_name = bb.getName();
                     pw.print("        ");
+                    if ("fifo".equals(filename)) continue;
                     if (bb.isInputDock()) {
                         pw.println("`input(" +
                                    bb_name+"_r,  "+
@@ -213,15 +298,17 @@ public class Fpga extends FleetTwoFleet {
                                    bb_name+"_r,  "+
                                    bb_name+"_r_, "+
                                    bb_name+"_a,  "+
-                                   "[("+WIDTH_WORD+"-1):0],"+
+                                   "[("+WIDTH_WORD+"):0],"+
                                    bb_name+"_d_)"
                                    );
+                        /*
                         if (!bb_name.equals("out") || !"memory".equals(filename))
                             pw.println("`defreg(" +
                                        bb_name+"_d_,  "+
                                        "[("+WIDTH_WORD+"-1):0],"+
                                        bb_name+"_d)"
                                        );
+                        */
                     }
                     pw.println();
                 }
@@ -237,19 +324,15 @@ public class Fpga extends FleetTwoFleet {
         } catch (Exception e) { throw new RuntimeException(e); }
     }
 
-
-    Ship debugShip;
-
-
-        public long getDestAddr(Path path) {
-            return ((FpgaPath)path).toLong();
-        }
-        public Dock getBoxByInstAddr(long dest) {
-            for(Ship ship : Fpga.this)
-                for(Dock bb : ship)
-                    if (((FpgaDestination)((FpgaDock)bb).getInstructionDestination()).getAddr() == dest)
-                        return bb;
-            return null;
-        }
+    public long getDestAddr(Path path) {
+        return ((FpgaPath)path).toLong();
+    }
+    public Dock getBoxByInstAddr(long dest) {
+        for(Ship ship : Fpga.this)
+            for(Dock bb : ship)
+                if (((FpgaDestination)((FpgaDock)bb).getInstructionDestination()).getAddr() == dest)
+                    return bb;
+        return null;
+    }
 
 }
index 9a61077..436e11f 100644 (file)
@@ -26,7 +26,7 @@ public class FpgaDestination extends Destination implements FabricElement {
         this.dock = dock;
     }
 
-    public Module.Port getOutputPort() { throw new RuntimeException(); }
+    public Module.SourcePort getOutputPort() { throw new RuntimeException(); }
     public Module.Port getInputPort()  { throw new RuntimeException(); }
     public void addOutput(FabricElement out, Module.Port outPort) { throw new RuntimeException(); }
 
index 820d2b7..8a53829 100644 (file)
@@ -16,11 +16,12 @@ import edu.berkeley.fleet.api.Dock;
 import edu.berkeley.fleet.two.*;
 import java.util.*;
 
-
 /** the pump itself is a */
 public class FpgaDock extends FleetTwoDock implements FabricElement {
 
-    private static final int INSTRUCTION_FIFO_SIZE = 8;
+    private static final int INSTRUCTION_FIFO_SIZE = 12;
+    private static final int EPILOGUE_FIFO_SIZE    = 0;
+    private static final int DATA_FIFO_SIZE        = 12;
         
     private FpgaDestination dataDestination;
     private FpgaDestination instructionDestination;
@@ -50,7 +51,7 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
     // FabricElement methods //////////////////////////////////////////////////////////////////////////////
 
     private FabricElement upstream;
-    public Module.Port getOutputPort() { throw new RuntimeException(); }
+    public Module.SourcePort getOutputPort() { throw new RuntimeException(); }
     public Module.Port getInputPort()  { throw new RuntimeException(); }
     public FpgaPath getPath(FabricElement dest, BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
     public FpgaPath getPath(Destination dest,BitVector signal) { return upstream.getPath((FabricElement)dest, signal); }
@@ -64,44 +65,74 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
 
         public DockModule(boolean inbox) {
             super(inbox ? "inbox" : "outbox");
-            Module fifo4     = new FifoModule(4);
-            Module fifo8     = new FifoModule(8);
-            Module fifo      = fifo8;
-            Module ififo_m   = new FifoModule(INSTRUCTION_FIFO_SIZE);
-            Module efifo_m   = fifo4;
+
+            /*
+            Module horn      = new HornModule();
+            Module funnel    = new FunnelModule();
             Module.SourcePort instruction   = createInputPort("instruction",       WIDTH_PACKET);
+            Module.SourcePort fabric_in     = createInputPort("fabric_in",   WIDTH_PACKET);
+            Module.SinkPort   fabric_out    = createOutputPort("fabric_out", WIDTH_PACKET, "");
+            if (!inbox) {
+                FunnelModule.FunnelInstance f0 = new FunnelModule.FunnelInstance(this, instruction, fabric_in);
+                Module.SourcePort ship_out = createInputPort("ship",        WIDTH_WORD);
+                FunnelModule.FunnelInstance f1 = new FunnelModule.FunnelInstance(this, f0.getOutputPort(), ship_out);
+                f1.addOutput(f0, fabric_out);
+            } else {
+                Module.SinkPort ship_in = createOutputPort("ship",        WIDTH_PACKET, "");
+                instruction.connect(fabric_out);
+                fabric_in.connect(ship_in);
+            }
+            */
+
+            int dfifo_width = inbox ? WIDTH_WORD+1 : 1;
+
+            // FIXME: assumes DISPATCH_PATH is at top of word!!!
+            Module ififo_m   = new FifoModule(INSTRUCTION_FIFO_SIZE, WIDTH_WORD-DISPATCH_PATH.valmaskwidth);
+            Module efifo_m   = new FifoModule(EPILOGUE_FIFO_SIZE,    WIDTH_WORD-DISPATCH_PATH.valmaskwidth);
+            Module dfifo_m   = new FifoModule(DATA_FIFO_SIZE,        dfifo_width);
+            Module.SourcePort instruction   = createInputPort("instruction", WIDTH_PACKET);
             instruction.hasLatch = true;
 
             Module.SourcePort fabric_in     = createInputPort("fabric_in",   WIDTH_PACKET);
+
+            // FIXME: at inboxes, no need for a full set of latches
             Module.SinkPort   fabric_out    = createOutputPort("fabric_out", WIDTH_PACKET, "");
-            Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, fifo);
-            fabric_in.connect(dfifo.getInputPort("in"));
+            
+            Module.InstantiatedModule dfifo = new Module.InstantiatedModule(this, dfifo_m);
+
+            fabric_in.hasLatch = false;
+            addPreCrap("assign "+dfifo.getInputPort("in").getName()+"_r = fabric_in_r;\n");
+            addPreCrap("assign fabric_in_a = "+dfifo.getInputPort("in").getName()+"_a;\n");
+            if (inbox)
+                addPreCrap("assign "+dfifo.getInputPort("in").getName()+
+                           " = { "+PACKET_SIGNAL.verilogVal("fabric_in")+
+                           ",    "+PACKET_DATA.verilogVal("fabric_in")+" };\n");
+            else
+                addPreCrap("assign "+dfifo.getInputPort("in").getName()+
+                           " = "+PACKET_SIGNAL.verilogVal("fabric_in")+";\n");
+
         
             Module.SourcePort dfifo_out = dfifo.getOutputPort("out");
             Module.SourcePort   ship_out    = null;
             if (!inbox) {
-                ship_out = createInputPort("ship",        WIDTH_WORD);
+                ship_out = createInputPort("ship",        WIDTH_WORD+1);
                 ship_out.hasLatch = true;
             }
 
             Module.SinkPort   ship_in     = null;
             if (inbox) {
-                ship_in = createOutputPort("ship",        WIDTH_PACKET, "");
+                ship_in = createOutputPort("ship",        WIDTH_WORD, "");
                 ship_in.hasLatch = true;
             }
 
-            Module.Latch     ondeck         = new Latch("ondeck", WIDTH_WORD);
             Module.Latch     repeat_counter = new Latch("repeat_counter", SET_ILC_FROM_IMMEDIATE.valmaskwidth+1, 1);
             Module.Latch     loop_counter   = new Latch("loop_counter", SET_OLC_FROM_IMMEDIATE.valmaskwidth, 1);
-            Module.Latch     tapl           = new Latch("tapl", SET_TAPL_FROM_IMMEDIATE.valmaskwidth);
             Module.Latch     flag_a         = new Latch("flag_a", 1);
             Module.Latch     flag_b         = new Latch("flag_b", 1);
             Module.Latch     flag_c         = new Latch("flag_c", 1);
-            Module.StateWire ondeckFull     = new StateWire("ondeck_full");
-            Module.StateWire newMayProceed  = new StateWire("newmayproceed", true);
-            Module.StateWire doRepeat       = new StateWire("dorepeat", false);
 
             Module.StateWire  isHatchOpen   = new StateWire("hatch", true);
+            Module.StateWire  proceed       = new StateWire("proceed", false);
         
             Module.SinkPort   token_out     = fabric_out;
             Module.SourcePort token_in      = dfifo_out;
@@ -110,21 +141,31 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
 
             Module.InstantiatedModule ififo = new Module.InstantiatedModule(this, ififo_m);
             Module.SinkPort   ififo_in      = ififo.getInputPort("in");
+            ififo_in.hasLatch = false;
+            ififo_in.forceNoLatch = true;
+
             Module.SourcePort ififo_out     = ififo.getOutputPort("out");
 
             Module.InstantiatedModule efifo = new Module.InstantiatedModule(this, efifo_m);
             Module.SinkPort   efifo_in      = efifo.getInputPort("in");
             Module.SourcePort efifo_out     = efifo.getOutputPort("out");
-            efifo_in.hasLatch = true;
-
-            addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_output;");
-            addPreCrap("wire [(`DATAWIDTH-1):0] data_latch_input;");
-            addPreCrap("assign data_latch_output = " +
-                       (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
-            addPreCrap("assign data_latch_input = " +
-                       (inbox ? "`packet_data("+data_in.getName()+")" : data_in.getName())+";");
-            Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() :
-                                                            "`packet_data("+data_out.getName()+")");
+            efifo_in.hasLatch = false;
+            efifo_in.forceNoLatch = true;
+
+            Module.SinkPort data_latch_output_p = createWirePort("data_latch_output", WIDTH_WORD);
+            Module.SinkPort data_latch_input_p  = createWirePort("data_latch_input", inbox ? WIDTH_WORD : WIDTH_WORD+1);
+
+            // FIXME
+            addPreCrap("wire ["+(ififo_out.width-1)+":0] ondeck;");
+            addPreCrap("wire ["+(Math.max(repeat_counter.width,loop_counter.width)-1)+":0] decremented;");
+            addPreCrap("assign data_latch_output = " + (inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")")+";");
+            addPreCrap("assign data_latch_input = " + (inbox ? data_in.getName() : data_in.getName())+";");
+            addPreCrap("assign "+efifo_in.getName()+" = `packet_data("+instruction.getName()+");");
+            addPreCrap("assign "+ififo_in.getName()+" = hatch ? "+efifo_out.getName()+" : ondeck;");
+            addPreCrap("assign ondeck = "+ififo_out.getName()+";");
+            addPreCrap("assign decremented = (`instruction_is_decr_loop(ondeck) ? {1'b0, loop_counter} : repeat_counter)-1;");
+
+            Assignable data_latch    = new SimpleAssignable(inbox ? data_out.getName() : "`packet_data("+data_out.getName()+")");
             String data_latch_input  = "data_latch_input";
 
             // Open the Hatch
@@ -134,18 +175,14 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
             // Torpedo Arrival
             new Event(new Object[] { instruction,
                                      PACKET_TOKEN.verilogVal("instruction"),
-                                     ondeckFull.isFull(),
+                                     ififo_out,
                                      token_out,
                                      I.verilog("ondeck"),
                 },
                 new Action[] { instruction,
-                               ondeckFull.doDrain(),
-                               newMayProceed.doFill(),
+                               ififo_out,
                                new AssignAction(loop_counter, "0"),
                                new AssignAction(repeat_counter, "1"),
-                               new AssignAction(new SimpleAssignable("`packet_token("+token_out.getName()+")"), "1"),
-                               new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), "tapl"),
-                               token_out,
                                isHatchOpen.doFill(),
                 });
             // Non-Torpedo Arrival
@@ -155,64 +192,51 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                 },
                 new Action[] {
                     efifo_in,
-                    instruction,
-                    new AssignAction(efifo_in, instruction)
                 });
+            new Event(new Object[] { efifo_in.getName()+"_a" },
+                      new Action[] { new SimpleAction(instruction.getName()+"_a <= 1;") });
 
             // Tail
-            new Event(new Object[] { efifo_out, TAIL.verilog("`packet_data("+efifo_out.getName()+")") },
+            new Event(new Object[] { efifo_out, TAIL.verilog(efifo_out.getName()) },
                       new Action[] { efifo_out, isHatchOpen.doDrain() } );
             // Enqueue
             new Event(new Object[] { efifo_out,
                                      ififo_in,
-                                     "!("+TAIL.verilog("`packet_data("+efifo_out.getName()+")")+")",
+                                     "!("+TAIL.verilog(efifo_out.getName())+")",
                                      isHatchOpen.isFull() },
-                new Action[] { efifo_out, ififo_in, new AssignAction(ififo_in, "`packet_data("+efifo_out.getName()+")")  } );
-
-            // New
-            new Event(new Object[] { ififo_out,
-                                     ondeckFull.isEmpty(),
-                                     newMayProceed.isFull(),
-                                     },
-                      new Action[] { ififo_out,
-                                     ondeckFull.doFill(),
-                                     newMayProceed.doDrain(),
-                                     new AssignAction(ondeck, ififo_out)
-                      }
-                      );
-
-            // RepeatExecute
-            new Event(new Object[] { doRepeat.isFull() },
-                      new Action[] { doRepeat.doDrain(), ondeckFull.doFill(),
-                                     new AssignAction(repeat_counter,
-                                                      "repeat_counter==`magic_standing_value?`magic_standing_value:(repeat_counter-1)")
-                      });
+                new Action[] { efifo_out,
+                               ififo_in,
+                }
+                );
 
             // Execute                                     
+            new Event(new Object[] { ififo_out, ififo_in, proceed.isFull() },
+                      new Action[] { ififo_out,           proceed.doDrain() });
             new Event(
-                      new Object[] { ondeckFull.isFull(),
+                      new Object[] { ififo_out,
                                      data_out,
                                      token_out,
                                      ififo_in,
+                                     proceed.isEmpty(),
                                      "(!`predicate_met(ondeck) || "+OS.verilog("ondeck")+" || !hatch)",
                                      new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_datain(ondeck))", data_in),
                                      new ConditionalTrigger("(`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck))", token_in)
                       },
-                      new Action[] { ondeckFull.doDrain(),
-                                     new ConditionalAction("`done_executing(ondeck)",                            newMayProceed.doFill()),
+                      new Action[] { 
                                      new ConditionalAction("`done_executing(ondeck) && `instruction_is_normal(ondeck)",
                                                            new AssignAction(repeat_counter, "1")),
-                                     new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in),
-                                     new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)),
-                                     new ConditionalAction("!`done_executing(ondeck)", doRepeat.doFill()),
-
+                                     new ConditionalAction("!`should_requeue(ondeck) && `done_executing(ondeck)", ififo_out),
+                                     new ConditionalAction("`should_requeue(ondeck)  && `done_executing(ondeck)", ififo_in),
+                                     new ConditionalAction("`should_requeue(ondeck)  && `done_executing(ondeck)", proceed.doFill()),
+                                     new ConditionalAction("!`done_executing(ondeck)",
+                                                           new AssignAction(repeat_counter,
+                                                                            "repeat_counter==`magic_standing_value?`magic_standing_value:decremented")),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_loop(ondeck)",
                                                            new AssignAction(loop_counter, "data_latch_output")),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_loop(ondeck)",
                                                            new AssignAction(loop_counter, "`instruction_loop_count_immediate(ondeck)")),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_is_decr_loop(ondeck)",
-                                                           new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)")),
-
+                                                           new AssignAction(loop_counter, "loop_counter==0 ? 0 : decremented")),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_data_to_repeat(ondeck)",
                                                            new AssignAction(repeat_counter, "data_latch_output")),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_is_load_immediate_to_repeat(ondeck)",
@@ -221,8 +245,8 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                                                            new AssignAction(repeat_counter, "`magic_standing_value")),
                                      new ConditionalAction("`predicate_met(ondeck) &&"+SHIFT.verilog("ondeck"),
                                                            new AssignAction(data_latch,
-                                                                            "({ data_latch_output["+(WIDTH_WORD-1-19)+":0], 19'b0 } | "+
-                                                                            SHIFT.verilogVal("ondeck")+")")),
+                                                                            "{ data_latch_output["+(WIDTH_WORD-1-SHIFT.valmaskwidth)+":0], "+
+                                                                            SHIFT.verilogVal("ondeck")+"}")),
                                      new ConditionalAction("`predicate_met(ondeck) && "+SET_IMMEDIATE.verilog("ondeck"),
                                                            new AssignAction(data_latch,
                                                                             "{ {"+(WIDTH_WORD-FleetTwoFleet.DataLatch_WIDTH)+
@@ -235,12 +259,15 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                                      (inbox
                                       ? new ConditionalAction("`predicate_met(ondeck) && "+
                                                               "(`instruction_bit_datain(ondeck) || `instruction_bit_tokenin(ondeck))",
-                                                              new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
+                                                              new AssignAction(flag_c, dfifo_out.getBits(dfifo_width-1, dfifo_width-1)))
                                       : new ConditionalAction("`predicate_met(ondeck) && "+
                                                               "(!`instruction_bit_datain(ondeck) && `instruction_bit_tokenin(ondeck))",
-                                                              new AssignAction(flag_c, PACKET_SIGNAL.verilogVal(dfifo_out.getName())))
-                                      /* FIXME: C-flag-from-ship */
+                                                              new AssignAction(flag_c, dfifo_out.getBits(dfifo_width-1, dfifo_width-1)))
                                       ),
+                                     inbox ? null :
+                                     new ConditionalAction("`predicate_met(ondeck) && "+
+                                                           "(`instruction_bit_datain(ondeck))",
+                                                           new AssignAction(flag_c, "data_latch_input["+WIDTH_WORD+"]")),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)",   data_in),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)",  data_out),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)",  token_in),
@@ -256,13 +283,12 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)",
                                                            new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
                                                                             DISPATCH_PATH.verilogVal(data_latch_input))),
-                                     new ConditionalAction("`predicate_met(ondeck) && "+SET_TAPL_FROM_IMMEDIATE.verilog("ondeck"),
-                                                           new AssignAction(tapl, SET_TAPL_FROM_IMMEDIATE.verilogVal("ondeck"))),
                                      new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_immediate(ondeck)",
                                                            new AssignAction(new SimpleAssignable("`packet_signal_and_dest("+token_out.getName()+")"),
                                                                             "`instruction_path_immediate(ondeck)")),
                       }
                       );
+
         }
 
         public void dump(PrintWriter pw, boolean fix) {
@@ -283,7 +309,6 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
             pw.println("`define instruction_is_tail(i)                   "+TAIL.verilog("i"));
             pw.println("`define instruction_is_normal(i)                 "+MOVE.verilog("i"));
             pw.println("`define instruction_is_setflags(i)               "+SET_FLAGS.verilog("i"));
-            pw.println("`define instruction_is_set(i)                    "+SET.verilog("i"));
 
             pw.println("`define instruction_is_decr_loop(i)              "+SET_OLC_FROM_OLC_MINUS_ONE.verilog("i"));
 
@@ -292,21 +317,20 @@ public class FpgaDock extends FleetTwoDock implements FabricElement {
             pw.println("`define instruction_bit_latch(i)        (`instruction_is_normal(i) && "+DC.verilog("i")+")");
             pw.println("`define instruction_bit_datain(i)       (`instruction_is_normal(i) && "+DI.verilog("i")+")");
             pw.println("`define instruction_bit_tokenin(i)      (`instruction_is_normal(i) && "+TI.verilog("i")+")");
-            pw.println("`define should_requeue(i)               (loop_counter > 0 && !("+OS.verilog("i")+"))");
+            pw.println("`define should_requeue(i)               (loop_counter!=0 && !("+OS.verilog("i")+"))");
             pw.println("`define predicate_met(i)  ("+
                        "("+
-                       "!`instruction_is_normal(i) || repeat_counter>0"+
+                       "!`instruction_is_normal(i) || repeat_counter!=0"+
                        ") && ("+
-              " " + P_A.verilog("i")+" ? flag_a "+
-              ":" + P_B.verilog("i")+" ? flag_b "+
-              ":" + P_C.verilog("i")+" ? flag_c "+
-              ":" + P_NOT_A.verilog("i")+" ? !flag_a "+
-              ":" + P_NOT_B.verilog("i")+" ? !flag_b "+
-              ":" + P_NOT_C.verilog("i")+" ? !flag_c "+
-              ":" + P_OLC.verilog("i")+" ? (loop_counter>0) "+
-              ": 1"+
+                       P_OLC_ZERO.verilog("i")+"==(loop_counter==0)"+
+                       ") && ("+
+                       " " + P_A.verilog("i")+" ? flag_a"+
+                       ":" + P_B.verilog("i")+" ? flag_b"+
+                       ":" + P_NOT_A.verilog("i")+" ? !flag_a"+
+                       ":" + P_NOT_B.verilog("i")+" ? !flag_b "+
+                       ": 1"+
                        ")"+
-              ")");
+                       ")");
             pw.println("`define new_flag(x)         ("+
                        "( ((x >> 0) & 1) & !flag_c) |" +
                        "( ((x >> 1) & 1) &  flag_c) |" +
index ff00574..e022be3 100644 (file)
@@ -3,10 +3,6 @@ import edu.berkeley.fleet.api.*;
 import edu.berkeley.fleet.two.*;
 import edu.berkeley.fleet.*;
 import java.lang.reflect.*;
-import edu.berkeley.sbp.chr.*;
-import edu.berkeley.sbp.misc.*;
-import edu.berkeley.sbp.meta.*;
-import edu.berkeley.sbp.util.*;
 import java.util.*;
 import java.io.*;
 import static edu.berkeley.fleet.two.FleetTwoFleet.*;
index ac193cd..45acd36 100644 (file)
@@ -20,7 +20,7 @@ public class FpgaShip extends FleetTwoShip {
         this.instance = new Module.InstantiatedModule(fleet.getVerilogModule(), module);
         for(DockDescription sdbb : sd) {
             if (sdbb.isInputDock()) module.createInputPort(sdbb.getName(), WIDTH_WORD);
-            else                module.createOutputPort(sdbb.getName(), WIDTH_WORD, "");
+            else                module.createOutputPort(sdbb.getName(), WIDTH_WORD+1, "");
             ports.put(sdbb.getName(), new FpgaDock(this, sdbb));
         }
         if (getType().toLowerCase().equals("debug"))
index bda75e8..49679a5 100644 (file)
@@ -15,12 +15,16 @@ import static edu.berkeley.fleet.fpga.verilog.Verilog.*;
 
 public class FunnelModule extends Module {
 
+    private static final int WIDTH = WIDTH_PACKET;
+
     public FunnelModule() {
         super("funnel");
-        Module.SinkPort    outp = createOutputPort("out", WIDTH_PACKET, "");
+        Module.SinkPort    outp = createOutputPort("out", WIDTH, "");
         Module.SourcePort  in1p = createInputPort("in1", WIDTH_PACKET);
         Module.SourcePort  in2p = createInputPort("in2", WIDTH_PACKET);
-        new Event(new Object[] { in1p, outp },
+
+        // FIXME: biased towards in2p side
+        new Event(new Object[] { in1p, outp, "!"+in2p.getReq() },
                   new Action[] { in1p, outp,
                                  new AssignAction(outp, in1p) });
         new Event(new Object[] { in2p, outp },
@@ -32,12 +36,12 @@ public class FunnelModule extends Module {
         private FabricElement in1 = null;
         private FabricElement in2 = null;
         public FabricElement out = null;
-        public Module.Port getOutputPort() { return getOutputPort("out"); }
+        public Module.SourcePort getOutputPort() { return getOutputPort("out"); }
         public Module.Port getInputPort()  { throw new RuntimeException("funnel has multiple inputs"); }
-        public FunnelInstance(Module thisModule, Module.Port p1, Module.Port p2) {
+        public FunnelInstance(Module thisModule, Module.SourcePort p1, Module.SourcePort p2) {
             super(thisModule, new FunnelModule());
-            p1.connect(this.getInputPort("in1"));
-            p2.connect(this.getInputPort("in2"));
+            if (p1 != null) p1.connect(this.getInputPort("in1"));
+            if (p2 != null) p2.connect(this.getInputPort("in2"));
         }
         public FunnelInstance(Module thisModule, FabricElement in1, FabricElement in2) {
             super(thisModule, new FunnelModule());
index ee7d4a6..0b3c73a 100644 (file)
@@ -26,22 +26,24 @@ public class HornModule extends Module {
                        int bot_of_addr_field,
                        int bot) {
         super("horn");
-        Module.SourcePort in   = createInputPort("in",    WIDTH_PACKET);
-        Module.SinkPort   out0 = createOutputPort("out0", WIDTH_PACKET, "");
-        Module.SinkPort   out1 = createOutputPort("out1", WIDTH_PACKET, "");
-        Module.Latch      out  = new Module.Latch("out",  WIDTH_PACKET);
-        out0.forceNoLatch = true;
-        out1.forceNoLatch = true;
-        addCrap("assign out0 = out;");
-        addCrap("assign out1 = out;");
-        String shifted_packet = "{ ";
-        if (top_of_addr_field < top) shifted_packet += " in["+top+":"+(top_of_addr_field+1)+"], ";
-        shifted_packet += " (in["+(top_of_addr_field)+":"+bot_of_addr_field+"] >> 1) ";
-        if (bot_of_addr_field > 0) shifted_packet += ",  in["+(bot_of_addr_field-1)+":0]  ";
-        shifted_packet += " }";
-        new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==0)" },
+        Module.SourcePort in   = createInputPort("in",    top+1);
+        Module.SinkPort   out0 = createOutputPort("out0", top+1, "");
+        Module.SinkPort   out1 = createOutputPort("out1", top+1, "");
+        Module.Latch      out  = new Module.Latch("out",  top+1);
+        out.connect(out0);
+        out.connect(out1);
+        Value shifted_packet =
+            new CatValue(new Value[] {
+                    (top_of_addr_field < top) ? in.getBits(top, top_of_addr_field+1) : null,
+                    //in.getBits(bot_of_addr_field, bot_of_addr_field),
+                    // we drop address bits instead of rotating to help synthesis eliminate unused junk
+                    new SimpleValue("1'b0"),
+                    in.getBits(top_of_addr_field, bot_of_addr_field+1),
+                    (bot_of_addr_field > 0) ? in.getBits(bot_of_addr_field-1, 0) : null,
+                });
+        new Event(new Object[] { in, out0, out1, in.testBit(bot_of_addr_field, false) },
                   new Action[] { in, out0, new AssignAction(out, shifted_packet) });
-        new Event(new Object[] { in, out0, out1, "(in["+bot_of_addr_field+"]==1)" },
+        new Event(new Object[] { in, out0, out1, in.testBit(bot_of_addr_field, true) },
                   new Action[] { in, out1, new AssignAction(out, shifted_packet) });
     }
 
@@ -49,7 +51,7 @@ public class HornModule extends Module {
         private FabricElement out0;
         private FabricElement out1;
         public void addInput(FabricElement in, Module.Port source) { source.connect(getInputPort("in")); }
-        public Module.Port getOutputPort() { throw new RuntimeException("horn has multiple outputs"); }
+        public Module.SourcePort getOutputPort() { throw new RuntimeException("horn has multiple outputs"); }
         public Module.Port getInputPort()  { return getInputPort("in"); }
         public HornInstance(Module thisModule, FabricElement out0, FabricElement out1) {
             super(thisModule, new HornModule());
diff --git a/src/edu/berkeley/fleet/fpga/bram.inc b/src/edu/berkeley/fleet/fpga/bram.inc
new file mode 100644 (file)
index 0000000..f0c8334
--- /dev/null
@@ -0,0 +1,23 @@
+/* bram.inc */
+module `BRAM_NAME(clk, rst, we, a, dpra, di, spo, dpo); 
+    input  clk; 
+    input  rst; 
+    input  we; 
+    input  [(`BRAM_ADDR_WIDTH-1):0] a; 
+    input  [(`BRAM_ADDR_WIDTH-1):0] dpra; 
+    input  [(`BRAM_DATA_WIDTH-1):0] di; 
+    output [(`BRAM_DATA_WIDTH-1):0] spo; 
+    output [(`BRAM_DATA_WIDTH-1):0] dpo; 
+    reg    [(`BRAM_DATA_WIDTH-1):0] ram [((`BRAM_SIZE)-1):0];
+    reg    [(`BRAM_ADDR_WIDTH-1):0] read_a; 
+    reg    [(`BRAM_ADDR_WIDTH-1):0] read_dpra; 
+    always @(posedge clk) begin 
+        if (we) 
+            ram[a] <= di; 
+        read_a <= a; 
+        read_dpra <= dpra; 
+    end
+    assign spo = ram[read_a]; 
+    assign dpo = ram[read_dpra]; 
+endmodule 
+/* bram.inc */
diff --git a/src/edu/berkeley/fleet/fpga/bram14.v b/src/edu/berkeley/fleet/fpga/bram14.v
new file mode 100644 (file)
index 0000000..8a23c0b
--- /dev/null
@@ -0,0 +1,6 @@
+`define BRAM_ADDR_WIDTH 14
+`define BRAM_DATA_WIDTH `INSTRUCTION_WIDTH
+`define BRAM_SIZE (1<<(`BRAM_ADDR_WIDTH))
+`define BRAM_NAME bram14
+
+`include "bram.inc"
diff --git a/src/edu/berkeley/fleet/fpga/empty.vhd b/src/edu/berkeley/fleet/fpga/empty.vhd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/edu/berkeley/fleet/fpga/fifo.inc b/src/edu/berkeley/fleet/fpga/fifo.inc
new file mode 100644 (file)
index 0000000..308fa79
--- /dev/null
@@ -0,0 +1,167 @@
+
+    input clk;
+    input rst;
+    wire fifostage_3_in_a;
+wire fifostage_3_in_r;
+wire   [47:0]fifostage_3_in;
+
+    wire fifostage_6_out_r;
+wire [47:0]fifostage_6_out;
+wire fifostage_6_out_a;
+
+    wire fifostage_0_in_a;
+wire fifostage_0_in_r;
+wire   [47:0]fifostage_0_in;
+
+    wire fifostage_1_out_r;
+wire [47:0]fifostage_1_out;
+wire fifostage_1_out_a;
+
+    wire fifostage_3_out_r;
+wire [47:0]fifostage_3_out;
+wire fifostage_3_out_a;
+
+    wire fifostage_4_out_r;
+wire [47:0]fifostage_4_out;
+wire fifostage_4_out_a;
+
+    wire fifostage_2_in_a;
+wire fifostage_2_in_r;
+wire   [47:0]fifostage_2_in;
+
+    wire fifostage_7_out_r;
+wire [47:0]fifostage_7_out;
+wire fifostage_7_out_a;
+
+    output out_r_;
+input out_a;
+output [47:0]out_;
+wire out_r;
+wire   [47:0]out;
+
+    wire fifostage_7_in_a;
+wire fifostage_7_in_r;
+wire   [47:0]fifostage_7_in;
+
+    wire fifostage_0_out_r;
+wire [47:0]fifostage_0_out;
+wire fifostage_0_out_a;
+
+    wire fifostage_1_in_a;
+wire fifostage_1_in_r;
+wire   [47:0]fifostage_1_in;
+
+    wire fifostage_2_out_r;
+wire [47:0]fifostage_2_out;
+wire fifostage_2_out_a;
+
+    wire fifostage_6_in_a;
+wire fifostage_6_in_r;
+wire   [47:0]fifostage_6_in;
+
+    wire fifostage_4_in_a;
+wire fifostage_4_in_r;
+wire   [47:0]fifostage_4_in;
+
+    input in_r;
+output in_a_;
+input [47:0]in;
+wire in_a;
+
+    wire fifostage_5_in_a;
+wire fifostage_5_in_r;
+wire   [47:0]fifostage_5_in;
+
+    wire fifostage_5_out_r;
+wire [47:0]fifostage_5_out;
+wire fifostage_5_out_a;
+
+    
+    assign fifostage_7_in_r = fifostage_6_out_r;
+assign fifostage_6_out_a = fifostage_7_in_a;
+assign fifostage_7_in   = fifostage_6_out;
+
+    
+    assign fifostage_2_in_r = fifostage_1_out_r;
+assign fifostage_1_out_a = fifostage_2_in_a;
+assign fifostage_2_in   = fifostage_1_out;
+
+    assign fifostage_4_in_r = fifostage_3_out_r;
+assign fifostage_3_out_a = fifostage_4_in_a;
+assign fifostage_4_in   = fifostage_3_out;
+
+    assign fifostage_5_in_r = fifostage_4_out_r;
+assign fifostage_4_out_a = fifostage_5_in_a;
+assign fifostage_5_in   = fifostage_4_out;
+
+    
+    assign out_r = fifostage_7_out_r;
+assign fifostage_7_out_a = out_a;
+assign out   = fifostage_7_out;
+
+    assign out_r_ = out_r;
+assign out_ = out;
+
+    
+    assign fifostage_1_in_r = fifostage_0_out_r;
+assign fifostage_0_out_a = fifostage_1_in_a;
+assign fifostage_1_in   = fifostage_0_out;
+
+    
+    assign fifostage_3_in_r = fifostage_2_out_r;
+assign fifostage_2_out_a = fifostage_3_in_a;
+assign fifostage_3_in   = fifostage_2_out;
+
+    
+    
+    assign in_a_ = in_a;
+assign fifostage_0_in_r = in_r;
+assign in_a = fifostage_0_in_a;
+assign fifostage_0_in   = in;
+
+    
+    assign fifostage_6_in_r = fifostage_5_out_r;
+assign fifostage_5_out_a = fifostage_6_in_a;
+assign fifostage_6_in   = fifostage_5_out;
+
+  fifostage fifostage_6(clk, rst 
+, fifostage_6_in_r, fifostage_6_in_a, fifostage_6_in
+, fifostage_6_out_r, fifostage_6_out_a, fifostage_6_out
+   );
+  fifostage fifostage_0(clk, rst 
+, fifostage_0_in_r, fifostage_0_in_a, fifostage_0_in
+, fifostage_0_out_r, fifostage_0_out_a, fifostage_0_out
+   );
+  fifostage fifostage_3(clk, rst 
+, fifostage_3_in_r, fifostage_3_in_a, fifostage_3_in
+, fifostage_3_out_r, fifostage_3_out_a, fifostage_3_out
+   );
+  fifostage fifostage_7(clk, rst 
+, fifostage_7_in_r, fifostage_7_in_a, fifostage_7_in
+, fifostage_7_out_r, fifostage_7_out_a, fifostage_7_out
+   );
+  fifostage fifostage_5(clk, rst 
+, fifostage_5_in_r, fifostage_5_in_a, fifostage_5_in
+, fifostage_5_out_r, fifostage_5_out_a, fifostage_5_out
+   );
+  fifostage fifostage_4(clk, rst 
+, fifostage_4_in_r, fifostage_4_in_a, fifostage_4_in
+, fifostage_4_out_r, fifostage_4_out_a, fifostage_4_out
+   );
+  fifostage fifostage_2(clk, rst 
+, fifostage_2_in_r, fifostage_2_in_a, fifostage_2_in
+, fifostage_2_out_r, fifostage_2_out_a, fifostage_2_out
+   );
+  fifostage fifostage_1(clk, rst 
+, fifostage_1_in_r, fifostage_1_in_a, fifostage_1_in
+, fifostage_1_out_r, fifostage_1_out_a, fifostage_1_out
+   );
+
+always @(posedge clk) begin
+  if (!rst) begin
+  end else begin
+    begin end
+    end
+  end
+
+endmodule
diff --git a/src/edu/berkeley/fleet/fpga/macros.v b/src/edu/berkeley/fleet/fpga/macros.v
deleted file mode 100644 (file)
index 1e4ef57..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-`include "bitfields.v"
-
-`define defreg(signame,width,regname) reg width regname; wire width signame;  assign signame = regname; initial regname = 0;
-`define input(r, a, a_, w, d)  input r;  output a_; reg a; assign a_=a; input  w d; initial a=0;
-`define output(r, r_, a, w, d) output r_; input a;  reg r; assign r_=r; output w d; initial r=0;
-
-`define onread(req, ack)        if (!req && ack) ack <= 0;    else if (req && !ack)  begin ack <=1;
-`define onwrite(req, ack)       if (!req && !ack) req <= 1; else if (req && ack)   begin req <= 0;
-
index 60dfc53..3035ecc 100644 (file)
@@ -24,10 +24,79 @@ Net sys_clk_pin IOSTANDARD = LVCMOS25;
 Net sys_rst_pin LOC=H7;
 Net sys_rst_pin PULLUP;
 Net sys_rst_pin IOSTANDARD = LVCMOS33;
+
 ### System level constraints
-#Net sys_clk_pin TNM_NET = sys_clk_pin;
-#TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 10000 ps;
-#Net sys_rst_pin TIG;
+
+Net sys_clk_pin TNM_NET = sys_clk_pin;
+TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 10 ns HIGH 50%;
+
+Net clk_unbuffered TNM_NET = clk_unbuffered;
+TIMESPEC TS_clk_unbuffered = PERIOD clk_unbuffered 20 ns;
+
+Net vga_clk_unbuffered TNM_NET = vga_clk_unbuffered;
+TIMESPEC TS_vga_clk_unbuffered = PERIOD vga_clk_unbuffered 40 ns;
+
+Net sys_rst_pin TIG;
+
+NET "sys_clk_pin"               TNM="SYS_CLK";
+NET "*/clkgen/write_clk_u"    TNM="WRITE_CLK";
+NET "*/clkgen/write_clk90_u"  TNM="WRITE_CLK";
+NET "*/clkgen/read_clk_u"     TNM="READ_CLK";
+TIMESPEC "TS_SYS_DDRREAD"=FROM "SYS_CLK" TO "WRITE_CLK" TIG;
+TIMESPEC "TS_DDRREAD_SYS"=FROM "WRITE_CLK" TO "SYS_CLK" TIG;
+TIMESPEC "TS_SYS_DDRWRITE"=FROM "SYS_CLK" TO "READ_CLK" TIG;
+TIMESPEC "TS_DDRWRITE_SYS"=FROM "READ_CLK" TO "SYS_CLK" TIG;
+TIMESPEC "TS_DDRREAD_DDRWRITE"=FROM "READ_CLK" TO "WRITE_CLK" TIG;
+TIMESPEC "TS_DDRWRITE_DDRREAD"=FROM "WRITE_CLK" TO "READ_CLK" TIG;
+
+net "vga_hsync" loc   = f9;
+net "vga_hsync" slew  = slow;
+net "vga_hsync" drive = 2;
+
+net "vga_vsync" loc   = h10;
+net "vga_vsync" slew  = slow;
+net "vga_vsync" drive = 2;
+
+net "vga_clkout"  loc ="c12";
+net "vga_clkout"  slew = fast;
+net "vga_clkout"  drive = 8;
+
+net "vga_r<7>" loc ="h8";
+net "vga_r<6>" loc ="c5";
+net "vga_r<5>" loc ="h9";
+net "vga_r<4>" loc ="g12";
+net "vga_r<3>" loc ="g11";
+net "vga_r<2>" loc ="g10";
+net "vga_r<1>" loc ="f11";
+net "vga_r<0>" loc ="f10";
+net "vga_r<*>" slew = slow;
+net "vga_r<*>" drive = 2;
+
+net "vga_g<7>" loc ="d5";
+net "vga_g<6>" loc ="d4";
+net "vga_g<5>" loc ="f8";
+net "vga_g<4>" loc ="e13";
+net "vga_g<3>" loc ="e12";
+net "vga_g<2>" loc ="e11";
+net "vga_g<1>" loc ="e9";
+net "vga_g<0>" loc ="e8";
+net "vga_g<*>" slew = slow;
+net "vga_g<*>" drive = 2;
+
+net "vga_b<7>" loc ="c4";
+net "vga_b<6>" loc ="c3";
+net "vga_b<5>" loc ="d12";
+net "vga_b<4>" loc ="d11";
+net "vga_b<3>" loc ="d10";
+net "vga_b<2>" loc ="d9";
+net "vga_b<1>" loc ="c13";
+net "vga_b<0>" loc ="g8";
+net "vga_b<*>" slew = slow;
+net "vga_b<*>" drive = 2;
+
+net "vga_*" iostandard = lvcmos33;
+
+
 #NET "C405RSTCORERESETREQ" TPTHRU = "RST_GRP";
 #NET "C405RSTCHIPRESETREQ" TPTHRU = "RST_GRP";
 #NET "C405RSTSYSRESETREQ" TPTHRU = "RST_GRP";
@@ -220,30 +289,30 @@ Net fpga_0_RS232_Uart_1_sout_pin PULLUP;
 #
 ##### Module LEDs_8Bit constraints
 #
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<0> LOC=AF19;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<0> IOSTANDARD = LVCMOS25;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<0> TIG;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<1> LOC=AD5;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<1> IOSTANDARD = LVCMOS33;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<1> TIG;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<2> LOC=AD6;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<2> IOSTANDARD = LVCMOS33;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<2> TIG;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<3> LOC=AD7;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<3> IOSTANDARD = LVCMOS33;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<3> TIG;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<4> LOC=AB8;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<4> IOSTANDARD = LVCMOS33;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<4> TIG;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<5> LOC=AC7;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<5> IOSTANDARD = LVCMOS33;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<5> TIG;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<6> LOC=AC9;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<6> IOSTANDARD = LVCMOS33;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<6> TIG;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<7> LOC=AC10;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<7> IOSTANDARD = LVCMOS33;
-#Net fpga_0_LEDs_8Bit_GPIO_IO_pin<7> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<0> LOC=AF19;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<0> IOSTANDARD = LVCMOS25;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<0> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<1> LOC=AD5;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<1> IOSTANDARD = LVCMOS33;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<1> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<2> LOC=AD6;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<2> IOSTANDARD = LVCMOS33;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<2> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<3> LOC=AD7;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<3> IOSTANDARD = LVCMOS33;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<3> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<4> LOC=AB8;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<4> IOSTANDARD = LVCMOS33;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<4> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<5> LOC=AC7;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<5> IOSTANDARD = LVCMOS33;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<5> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<6> LOC=AC9;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<6> IOSTANDARD = LVCMOS33;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<6> TIG;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<7> LOC=AC10;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<7> IOSTANDARD = LVCMOS33;
+Net fpga_0_LEDs_8Bit_GPIO_IO_pin<7> TIG;
 #
 ##### Module LCD_OPTIONAL constraints
 #
@@ -694,3 +763,371 @@ Net fpga_0_RS232_Uart_1_sout_pin PULLUP;
 #NET "MGT106AB_RXN<0>" LOC = "AP17"; #RXN
 #NET "MGT106AB_RXP<0>" LOC = "AP18"; #RXP 
 #
+
+
+
+## DDR ##############################################################################
+
+
+## IO Devices constraints
+
+#### Module ORGate_1 constraints
+
+# Net fpga_0_ORGate_1_Res_pin LOC=AE18;
+# Net fpga_0_ORGate_1_Res_pin TIG;
+# Net fpga_0_ORGate_1_Res_1_pin LOC=AE17;
+# Net fpga_0_ORGate_1_Res_1_pin TIG;
+# Net fpga_0_ORGate_1_Res_2_pin LOC=R11;
+# Net fpga_0_ORGate_1_Res_2_pin IOSTANDARD = PCI33_3;
+
+#### Module DDR2_SDRAM constraints
+
+# Net fpga_0_DDR2_SDRAM_DDR2_ODT_pin LOC=AA25;
+# Net fpga_0_DDR2_SDRAM_DDR2_ODT_pin IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<0> LOC=H28;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<0> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<1> LOC=K28;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<1> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<2> LOC=L28;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<2> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<3> LOC=M25;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<3> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<4> LOC=Y24;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<4> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<5> LOC=N27;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<5> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<6> LOC=AD26;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<6> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<7> LOC=AC25;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<7> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<8> LOC=R26;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<8> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<9> LOC=R28;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<9> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<10> LOC=T26;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<10> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<11> LOC=T28;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<11> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<12> LOC=U27;
+# Net fpga_0_DDR2_SDRAM_DDR2_Addr_pin<12> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_BankAddr_pin<0> LOC=V28;
+# Net fpga_0_DDR2_SDRAM_DDR2_BankAddr_pin<0> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_BankAddr_pin<1> LOC=W26;
+# Net fpga_0_DDR2_SDRAM_DDR2_BankAddr_pin<1> IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_CAS_n_pin LOC=R31;
+# Net fpga_0_DDR2_SDRAM_DDR2_CAS_n_pin IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_CE_pin LOC=AJ31;
+# Net fpga_0_DDR2_SDRAM_DDR2_CE_pin IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_CS_n_pin LOC=AJ30;
+# Net fpga_0_DDR2_SDRAM_DDR2_CS_n_pin IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_RAS_n_pin LOC=R32;
+# Net fpga_0_DDR2_SDRAM_DDR2_RAS_n_pin IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_WE_n_pin LOC=T31;
+# Net fpga_0_DDR2_SDRAM_DDR2_WE_n_pin IOSTANDARD = SSTL18_I;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<0> LOC=AH30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<0> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<1> LOC=M31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<1> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<2> LOC=T30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<2> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<3> LOC=U28;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<3> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<4> LOC=AJ32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<4> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<5> LOC=AG31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<5> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<6> LOC=AG30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<6> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<7> LOC=AF29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DM_pin<7> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<0> LOC=F29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<0> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<1> LOC=K29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<1> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<2> LOC=P27;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<2> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<3> LOC=P32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<3> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<4> LOC=W27;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<4> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<5> LOC=W31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<5> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<6> LOC=AG32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<6> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<7> LOC=AE32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS<7> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<0> LOC=E29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<0> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<1> LOC=J29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<1> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<2> LOC=P26;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<2> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<3> LOC=N32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<3> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<4> LOC=V27;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<4> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<5> LOC=W30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<5> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<6> LOC=AH32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<6> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<7> LOC=AE31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQS_n<7> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<0> LOC=C32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<0> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<1> LOC=D32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<1> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<2> LOC=E32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<2> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<3> LOC=G32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<3> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<4> LOC=H32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<4> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<5> LOC=J32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<5> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<6> LOC=K32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<6> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<7> LOC=M32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<7> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<8> LOC=N28;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<8> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<9> LOC=D31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<9> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<10> LOC=E31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<10> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<11> LOC=F31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<11> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<12> LOC=G31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<12> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<13> LOC=J31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<13> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<14> LOC=K31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<14> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<15> LOC=L31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<15> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<16> LOC=C30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<16> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<17> LOC=D30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<17> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<18> LOC=F30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<18> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<19> LOC=G30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<19> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<20> LOC=Y28;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<20> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<21> LOC=Y27;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<21> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<22> LOC=L30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<22> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<23> LOC=M30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<23> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<24> LOC=N30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<24> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<25> LOC=C29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<25> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<26> LOC=D29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<26> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<27> LOC=J30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<27> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<28> LOC=L29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<28> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<29> LOC=N29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<29> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<30> LOC=P29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<30> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<31> LOC=R29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<31> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<32> LOC=T29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<32> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<33> LOC=U32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<33> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<34> LOC=V32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<34> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<35> LOC=W32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<35> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<36> LOC=Y32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<36> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<37> LOC=AB32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<37> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<38> LOC=AC32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<38> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<39> LOC=AD32;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<39> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<40> LOC=AB27;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<40> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<41> LOC=U31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<41> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<42> LOC=W25;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<42> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<43> LOC=Y31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<43> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<44> LOC=AA31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<44> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<45> LOC=AB31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<45> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<46> LOC=AD31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<46> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<47> LOC=AB28;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<47> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<48> LOC=AF31;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<48> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<49> LOC=U30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<49> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<50> LOC=V30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<50> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<51> LOC=Y26;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<51> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<52> LOC=AA30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<52> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<53> LOC=AB30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<53> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<54> LOC=AC30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<54> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<55> LOC=AD30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<55> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<56> LOC=AF30;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<56> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<57> LOC=V29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<57> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<58> LOC=W29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<58> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<59> LOC=Y29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<59> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<60> LOC=AA29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<60> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<61> LOC=AC29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<61> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<62> LOC=AD29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<62> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<63> LOC=AE29;
+# Net fpga_0_DDR2_SDRAM_DDR2_DQ<63> IOSTANDARD = SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_Clk_pin LOC=H30;
+# Net fpga_0_DDR2_SDRAM_DDR2_Clk_pin IOSTANDARD = DIFF_SSTL18_II;
+# Net fpga_0_DDR2_SDRAM_DDR2_Clk_n_pin LOC=H29;
+# Net fpga_0_DDR2_SDRAM_DDR2_Clk_n_pin IOSTANDARD = DIFF_SSTL18_II;
+
+#### Module DDR_SDRAM constraints
+
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<12> LOC=J24;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<12> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<11> LOC=K26;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<11> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<10> LOC=K24;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<10> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<9> LOC=K23;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<9> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<8> LOC=L26;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<8> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<7> LOC=L25;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<7> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<6> LOC=L24;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<6> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<5> LOC=M23;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<5> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<4> LOC=N24;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<4> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<3> LOC=N23;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<3> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<2> LOC=N22;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<2> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<1> LOC=P22;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<1> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<0> LOC=P24;
+Net fpga_0_DDR_SDRAM_DDR_Addr_pin<0> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_BankAddr_pin<1> LOC=J26;
+Net fpga_0_DDR_SDRAM_DDR_BankAddr_pin<1> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_BankAddr_pin<0> LOC=J25;
+Net fpga_0_DDR_SDRAM_DDR_BankAddr_pin<0> IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_CAS_n_pin LOC=D26;
+Net fpga_0_DDR_SDRAM_DDR_CAS_n_pin IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_CE_pin LOC=H14;
+Net fpga_0_DDR_SDRAM_DDR_CE_pin IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_CS_n_pin LOC=C27;
+Net fpga_0_DDR_SDRAM_DDR_CS_n_pin IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_RAS_n_pin LOC=D27;
+Net fpga_0_DDR_SDRAM_DDR_RAS_n_pin IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_WE_n_pin LOC=E27;
+Net fpga_0_DDR_SDRAM_DDR_WE_n_pin IOSTANDARD = SSTL2_I;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<0> LOC=F21;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<0> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<1> LOC=G22;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<1> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<2> LOC=E23;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<2> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<3> LOC=G23;
+Net fpga_0_DDR_SDRAM_DDR_DM_pin<3> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQS<0> LOC=F20;
+Net fpga_0_DDR_SDRAM_DDR_DQS<0> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQS<1> LOC=G20;
+Net fpga_0_DDR_SDRAM_DDR_DQS<1> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQS<2> LOC=G25;
+Net fpga_0_DDR_SDRAM_DDR_DQS<2> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQS<3> LOC=F25;
+Net fpga_0_DDR_SDRAM_DDR_DQS<3> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<0> LOC=E17;
+Net fpga_0_DDR_SDRAM_DDR_DQ<0> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<1> LOC=E18;
+Net fpga_0_DDR_SDRAM_DDR_DQ<1> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<2> LOC=F18;
+Net fpga_0_DDR_SDRAM_DDR_DQ<2> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<3> LOC=G18;
+Net fpga_0_DDR_SDRAM_DDR_DQ<3> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<4> LOC=F19;
+Net fpga_0_DDR_SDRAM_DDR_DQ<4> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<5> LOC=E19;
+Net fpga_0_DDR_SDRAM_DDR_DQ<5> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<6> LOC=D21;
+Net fpga_0_DDR_SDRAM_DDR_DQ<6> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<7> LOC=E21;
+Net fpga_0_DDR_SDRAM_DDR_DQ<7> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<8> LOC=G21;
+Net fpga_0_DDR_SDRAM_DDR_DQ<8> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<9> LOC=H20;
+Net fpga_0_DDR_SDRAM_DDR_DQ<9> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<10> LOC=J20;
+Net fpga_0_DDR_SDRAM_DDR_DQ<10> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<11> LOC=J21;
+Net fpga_0_DDR_SDRAM_DDR_DQ<11> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<12> LOC=K21;
+Net fpga_0_DDR_SDRAM_DDR_DQ<12> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<13> LOC=L21;
+Net fpga_0_DDR_SDRAM_DDR_DQ<13> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<14> LOC=J22;
+Net fpga_0_DDR_SDRAM_DDR_DQ<14> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<15> LOC=H22;
+Net fpga_0_DDR_SDRAM_DDR_DQ<15> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<16> LOC=C22;
+Net fpga_0_DDR_SDRAM_DDR_DQ<16> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<17> LOC=C23;
+Net fpga_0_DDR_SDRAM_DDR_DQ<17> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<18> LOC=C24;
+Net fpga_0_DDR_SDRAM_DDR_DQ<18> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<19> LOC=C25;
+Net fpga_0_DDR_SDRAM_DDR_DQ<19> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<20> LOC=D22;
+Net fpga_0_DDR_SDRAM_DDR_DQ<20> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<21> LOC=D24;
+Net fpga_0_DDR_SDRAM_DDR_DQ<21> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<22> LOC=D25;
+Net fpga_0_DDR_SDRAM_DDR_DQ<22> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<23> LOC=C28;
+Net fpga_0_DDR_SDRAM_DDR_DQ<23> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<24> LOC=F23;
+Net fpga_0_DDR_SDRAM_DDR_DQ<24> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<25> LOC=F24;
+Net fpga_0_DDR_SDRAM_DDR_DQ<25> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<26> LOC=F26;
+Net fpga_0_DDR_SDRAM_DDR_DQ<26> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<27> LOC=G26;
+Net fpga_0_DDR_SDRAM_DDR_DQ<27> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<28> LOC=H25;
+Net fpga_0_DDR_SDRAM_DDR_DQ<28> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<29> LOC=H24;
+Net fpga_0_DDR_SDRAM_DDR_DQ<29> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<30> LOC=E24;
+Net fpga_0_DDR_SDRAM_DDR_DQ<30> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_DQ<31> LOC=E22;
+Net fpga_0_DDR_SDRAM_DDR_DQ<31> IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_Clk_pin LOC=F28;
+Net fpga_0_DDR_SDRAM_DDR_Clk_pin IOSTANDARD = SSTL2_II;
+Net fpga_0_DDR_SDRAM_DDR_Clk_n_pin LOC=E28;
+Net fpga_0_DDR_SDRAM_DDR_Clk_n_pin IOSTANDARD = SSTL2_II;
index 548a633..1a10194 100644 (file)
@@ -1,11 +1,36 @@
 
 module main
- (sys_clk_pin,   /* I think this is 100Mhz */
+ (sys_clk_pin,   /* 100Mhz */
   sys_rst_pin,
   fpga_0_RS232_Uart_1_ctsN_pin,
   fpga_0_RS232_Uart_1_rtsN_pin,
   fpga_0_RS232_Uart_1_sin_pin,
-  fpga_0_RS232_Uart_1_sout_pin
+  fpga_0_RS232_Uart_1_sout_pin,
+
+  fpga_0_DDR_SDRAM_DDR_Clk_pin,
+  fpga_0_DDR_SDRAM_DDR_Clk_n_pin,
+  fpga_0_DDR_SDRAM_DDR_Addr_pin,
+  fpga_0_DDR_SDRAM_DDR_BankAddr_pin,
+  fpga_0_DDR_SDRAM_DDR_CAS_n_pin,
+  fpga_0_DDR_SDRAM_DDR_CE_pin,
+  fpga_0_DDR_SDRAM_DDR_CS_n_pin,
+  fpga_0_DDR_SDRAM_DDR_RAS_n_pin,
+  fpga_0_DDR_SDRAM_DDR_WE_n_pin,
+  fpga_0_DDR_SDRAM_DDR_DM_pin,
+  fpga_0_DDR_SDRAM_DDR_DQS,
+  fpga_0_DDR_SDRAM_DDR_DQ,
+
+  vga_psave,
+  vga_hsync,
+  vga_vsync,
+  vga_sync,
+  vga_blank,
+  vga_r,
+  vga_g,
+  vga_b,
+  vga_clkout,
+
+  fpga_0_LEDs_8Bit_GPIO_IO_pin
  );
 
   input  sys_clk_pin;
@@ -15,8 +40,98 @@ module main
   input  fpga_0_RS232_Uart_1_sin_pin;
   output fpga_0_RS232_Uart_1_sout_pin;
 
+  output fpga_0_DDR_SDRAM_DDR_Clk_pin;
+  output fpga_0_DDR_SDRAM_DDR_Clk_n_pin;
+  output [12:0] fpga_0_DDR_SDRAM_DDR_Addr_pin;
+  output [1:0] fpga_0_DDR_SDRAM_DDR_BankAddr_pin;
+  output fpga_0_DDR_SDRAM_DDR_CAS_n_pin;
+  output fpga_0_DDR_SDRAM_DDR_CE_pin;
+  output fpga_0_DDR_SDRAM_DDR_CS_n_pin;
+  output fpga_0_DDR_SDRAM_DDR_RAS_n_pin;
+  output fpga_0_DDR_SDRAM_DDR_WE_n_pin;
+  output [3:0] fpga_0_DDR_SDRAM_DDR_DM_pin;
+  inout [3:0] fpga_0_DDR_SDRAM_DDR_DQS;
+  inout [31:0] fpga_0_DDR_SDRAM_DDR_DQ;
+
+  wire  [31:0]  dram_addr;
+  wire          dram_addr_r;
+  wire          dram_addr_a;
+  wire          dram_isread;
+  wire  [63:0]  dram_write_data;
+  wire          dram_write_data_push;
+  wire          dram_write_data_full;
+  wire   [63:0] dram_read_data;
+  wire          dram_read_data_pop;
+  wire          dram_read_data_empty;
+  wire   [1:0]  dram_read_data_latency;
+
+  output vga_psave;
+  output vga_hsync;
+  output vga_vsync;
+  output vga_sync;
+  output vga_blank;
+  output [7:0] vga_r;
+  output [7:0] vga_g;
+  output [7:0] vga_b;
+  output vga_clkout;
+
   wire clk;
-  assign clk = sys_clk_pin;
+  wire clk_fb;
+  wire clk50mhz;
+  wire clk_unbuffered;
+
+  wire vga_clk;
+  wire vga_clk_fb;
+  wire vga_clk_unbuffered;
+
+  output [7:0] fpga_0_LEDs_8Bit_GPIO_IO_pin;
+  wire [7:0] leds;
+  assign fpga_0_LEDs_8Bit_GPIO_IO_pin = ~leds;
+
+  assign leds[5:0] = dram_read_data[5:0];
+  assign leds[6] = dram_addr_r;
+  assign leds[7] = dram_addr_a;
+
+
+  //assign clk = sys_clk_pin;
+/*
+  reg clk_unbuffered;
+  initial clk_unbuffered = 0;
+
+  always @(posedge sys_clk_pin) begin
+    clk_unbuffered = ~clk_unbuffered;
+  end
+
+  assign clk_unbuffered = sys_clk_pin;
+*/
+  BUFG GBUF_FOR_MUX_CLOCK (.I(clk_unbuffered), .O(clk));
+
+  DCM
+   #(
+      .CLKFX_MULTIPLY(4),
+      .CLKFX_DIVIDE(8),
+      .CLKIN_PERIOD("10 ns")
+    ) mydcm(
+      .CLKIN (sys_clk_pin),
+      .CLKFB(clk_fb),
+      .CLKFX (clk_unbuffered),
+      .CLK0  (clk_fb)
+    );
+
+  BUFG GBUF_FOR_VGA_CLOCK (.I(vga_clk_unbuffered), .O(vga_clk));
+  DCM  // 25Mhz VGA clock
+   #(
+      .CLKFX_MULTIPLY(4),
+      .CLKFX_DIVIDE(16),
+      .CLKIN_PERIOD("20 ns")
+    ) vgadcm (
+      .CLKIN (clk_unbuffered),
+      .CLKFB(vga_clk_fb),
+      .CLKFX (vga_clk_unbuffered),
+      .CLK0  (vga_clk_fb)
+    );
+
+
   wire break_o;
   wire break;
   reg break_last;
@@ -44,8 +159,9 @@ module main
 
   wire sio_ce;
   wire sio_ce_x4;
-  //sasc_brg sasc_brg(clk, ser_rst, 10, 217, sio_ce, sio_ce_x4);
-  sasc_brg sasc_brg(clk, ser_rst, 8, 65, sio_ce, sio_ce_x4);
+  //sasc_brg sasc_brg(clk, ser_rst, 8, 65, sio_ce, sio_ce_x4);
+  //  sasc_brg sasc_brg(clk, ser_rst, 3, 65, sio_ce, sio_ce_x4);
+  sasc_brg sasc_brg(sys_clk_pin, ser_rst, 8, 65, sio_ce, sio_ce_x4);
   sasc_top sasc_top(clk, ser_rst,
                     fpga_0_RS232_Uart_1_sin_pin,
                     fpga_0_RS232_Uart_1_sout_pin,
@@ -87,7 +203,29 @@ module main
     */
    root my_root(clk, rst && !break_o,
                 root_in_r,  root_in_a,  root_in_d,
-                root_out_r, root_out_a, root_out_d);
+                root_out_r, root_out_a, root_out_d,
+                dram_addr,
+                dram_addr_r,
+                dram_addr_a,
+                dram_isread,
+                dram_write_data,
+                dram_write_data_push,
+                dram_write_data_full,
+                dram_read_data,
+                dram_read_data_pop,
+                dram_read_data_empty,
+                dram_read_data_latency,
+                vga_clk,
+                vga_psave,
+                vga_hsync,
+                vga_vsync,
+                vga_sync,
+                vga_blank,
+                vga_r,
+                vga_g,
+                vga_b,
+                vga_clkout
+               );
 /*
    fifo4 my_root(clk, rst,
                 root_in_r,  root_in_a,  root_in_d,
@@ -158,6 +296,41 @@ module main
      data_to_fleet_read_enable_reg = 0;
      data_to_host_write_enable_reg = 0;
    end
-endmodule
 
+   ddr_ctrl 
+   #(
+       .clk_freq( 50000000 ),
+       .clk_multiply( 12 ),
+       .clk_divide( 5 ),
+       .phase_shift( 0 ),
+       .wait200_init( 26 )
+   ) ddr_ctrl (
+          .ddr_a( fpga_0_DDR_SDRAM_DDR_Addr_pin ),
+          .ddr_clk( fpga_0_DDR_SDRAM_DDR_Clk_pin ),
+          .ddr_clk_n( fpga_0_DDR_SDRAM_DDR_Clk_n_pin ),
+          .ddr_ba( fpga_0_DDR_SDRAM_DDR_BankAddr_pin ),
+          .ddr_dq( fpga_0_DDR_SDRAM_DDR_DQ ),
+          .ddr_dm( fpga_0_DDR_SDRAM_DDR_DM_pin ),
+          .ddr_dqs( fpga_0_DDR_SDRAM_DDR_DQS ),
+          .ddr_cs_n( fpga_0_DDR_SDRAM_DDR_CS_n_pin ),
+          .ddr_ras_n( fpga_0_DDR_SDRAM_DDR_RAS_n_pin ),
+          .ddr_cas_n( fpga_0_DDR_SDRAM_DDR_CAS_n_pin ),
+          .ddr_we_n( fpga_0_DDR_SDRAM_DDR_WE_n_pin ),
+          .ddr_cke( fpga_0_DDR_SDRAM_DDR_CE_pin ),
+   
+          .clk(clk),
+          .reset(!rst),
+          .rot(3'b011),
+   
+          .fml_wr(!dram_isread && dram_addr_r),
+          .fml_done(dram_addr_a),
+          .fml_rd( dram_isread && dram_addr_r),
+          .fml_adr(dram_addr),
+          .fml_din(dram_write_data),
+          .fml_dout(dram_read_data),
+//          .fml_msk(16'hffff)
+          .fml_msk(16'h0)
+   );
 
+endmodule
+   
index 9fa27f3..9f891ae 100644 (file)
@@ -1,4 +1,4 @@
 set -tmpdir ./tmp
 set -xsthdpdir ./xst
 run
--ifn main.prj -ifmt mixed -ofn main -ofmt NGC -p xc4vfx60 -top main -opt_mode Area -opt_level 1 -iuc NO -lso main.lso -keep_hierarchy NO -rtlview Yes -glob_opt AllClockNets -read_cores YES -write_timing_constraints NO -cross_clock_analysis NO -hierarchy_separator / -bus_delimiter <> -case maintain -slice_utilization_ratio 100 -verilog2001 YES -fsm_extract Yes -fsm_encoding Auto -safe_implementation No -fsm_style lut -ram_extract Yes -ram_style Auto -rom_extract Yes -mux_style Auto -decoder_extract YES -priority_extract YES -shreg_extract YES -shift_extract YES -xor_collapse YES -rom_style Auto -mux_extract YES -resource_sharing YES -mult_style auto -iobuf YES -max_fanout 500 -bufg 1 -register_duplication YES -register_balancing No -slice_packing Yes -optimize_primitives Yes -tristate2logic Yes -use_clock_enable Yes -use_sync_set Yes -use_sync_reset Yes -iob auto -equivalent_register_removal YES -slice_utilization_ratio_maxmargin 5 
+-ifn main.prj -ifmt mixed -ofn main -ofmt NGC -p xc4vfx60-11ff1152 -top main -opt_mode speed -opt_level 1 -iuc NO -lso main.lso -keep_hierarchy NO -rtlview Yes -glob_opt AllClockNets -read_cores YES -write_timing_constraints NO -cross_clock_analysis YES -hierarchy_separator / -bus_delimiter <> -case maintain -slice_utilization_ratio 100 -verilog2001 YES -fsm_extract Yes -fsm_encoding Auto -safe_implementation No -fsm_style lut -ram_extract Yes -ram_style Auto -rom_extract Yes -mux_style Auto -decoder_extract YES -priority_extract YES -shreg_extract YES -shift_extract YES -xor_collapse YES -rom_style Auto -mux_extract YES -resource_sharing YES -mult_style auto -iobuf YES -max_fanout 10000 -bufg 1 -register_duplication YES -register_balancing Yes -slice_packing Yes -optimize_primitives Yes -tristate2logic Yes -use_clock_enable Yes -use_sync_set Yes -use_sync_reset Yes -iob auto -equivalent_register_removal YES -slice_utilization_ratio_maxmargin 5 
diff --git a/src/edu/berkeley/fleet/fpga/mem/async_fifo.v b/src/edu/berkeley/fleet/fpga/mem/async_fifo.v
new file mode 100644 (file)
index 0000000..885dfbe
--- /dev/null
@@ -0,0 +1,116 @@
+//==========================================
+// Function : Asynchronous FIFO (w/ 2 asynchronous clocks).
+// Coder    : Alex Claros F.
+// Date     : 15/May/2005.
+// Notes    : This implementation is based on the article 
+//            'Asynchronous FIFO in Virtex-II FPGAs'
+//            writen by Peter Alfke. This TechXclusive 
+//            article can be downloaded from the
+//            Xilinx website. It has some minor modifications.
+//=========================================
+
+`timescale 1ns / 1ps
+
+module async_fifo
+  #(parameter    DATA_WIDTH    = 8,
+                 ADDRESS_WIDTH = 4,
+                 FIFO_DEPTH    = (1 << ADDRESS_WIDTH))
+     //Reading port
+    (output wire [DATA_WIDTH-1:0]        Data_out, 
+     output reg                          Empty_out,
+     input wire                          ReadEn_in,
+     input wire                          RClk,        
+     //Writing port.    
+     input wire  [DATA_WIDTH-1:0]        Data_in,  
+     output reg                          Full_out,
+     input wire                          WriteEn_in,
+     input wire                          WClk,
+        
+     input wire                          Clear_in);
+
+    /////Internal connections & variables//////
+    reg   [DATA_WIDTH-1:0]              Mem [FIFO_DEPTH-1:0];
+    wire  [ADDRESS_WIDTH-1:0]           pNextWordToWrite, pNextWordToRead;
+    wire                                EqualAddresses;
+    wire                                NextWriteAddressEn, NextReadAddressEn;
+    wire                                Set_Status, Rst_Status;
+    reg                                 Status;
+    wire                                PresetFull, PresetEmpty;
+    
+    //////////////Code///////////////
+    //Data ports logic:
+    //(Uses a dual-port RAM).
+    //'Data_out' logic:
+    assign  Data_out = Mem[pNextWordToRead];
+//    always @ (posedge RClk)
+//        if (!PresetEmpty)
+//            Data_out <= Mem[pNextWordToRead];
+//        if (ReadEn_in & !Empty_out)
+            
+    //'Data_in' logic:
+    always @ (posedge WClk)
+        if (WriteEn_in & !Full_out)
+            Mem[pNextWordToWrite] <= Data_in;
+
+    //Fifo addresses support logic: 
+    //'Next Addresses' enable logic:
+    assign NextWriteAddressEn = WriteEn_in & ~Full_out;
+    assign NextReadAddressEn  = ReadEn_in  & ~Empty_out;
+           
+    //Addreses (Gray counters) logic:
+    GrayCounter #(
+               .COUNTER_WIDTH( ADDRESS_WIDTH )
+    ) GrayCounter_pWr (
+        .GrayCount_out(pNextWordToWrite),
+        .Enable_in(NextWriteAddressEn),
+        .Clear_in(Clear_in),
+        
+        .Clk(WClk)
+       );
+       
+    GrayCounter #(
+               .COUNTER_WIDTH( ADDRESS_WIDTH )
+    ) GrayCounter_pRd (
+        .GrayCount_out(pNextWordToRead),
+        .Enable_in(NextReadAddressEn),
+        .Clear_in(Clear_in),
+        .Clk(RClk)
+       );
+     
+
+    //'EqualAddresses' logic:
+    assign EqualAddresses = (pNextWordToWrite == pNextWordToRead);
+
+    //'Quadrant selectors' logic:
+    assign Set_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ~^ pNextWordToRead[ADDRESS_WIDTH-1]) &
+                         (pNextWordToWrite[ADDRESS_WIDTH-1] ^  pNextWordToRead[ADDRESS_WIDTH-2]);
+                            
+    assign Rst_Status = (pNextWordToWrite[ADDRESS_WIDTH-2] ^  pNextWordToRead[ADDRESS_WIDTH-1]) &
+                         (pNextWordToWrite[ADDRESS_WIDTH-1] ~^ pNextWordToRead[ADDRESS_WIDTH-2]);
+                         
+    //'Status' latch logic:
+    always @ (Set_Status, Rst_Status, Clear_in) //D Latch w/ Asynchronous Clear & Preset.
+        if (Rst_Status | Clear_in)
+            Status = 0;  //Going 'Empty'.
+        else if (Set_Status)
+            Status = 1;  //Going 'Full'.
+            
+    //'Full_out' logic for the writing port:
+    assign PresetFull = Status & EqualAddresses;  //'Full' Fifo.
+    
+    always @ (posedge WClk, posedge PresetFull) //D Flip-Flop w/ Asynchronous Preset.
+        if (PresetFull)
+            Full_out <= 1;
+        else
+            Full_out <= 0;
+            
+    //'Empty_out' logic for the reading port:
+    assign PresetEmpty = ~Status & EqualAddresses;  //'Empty' Fifo.
+    
+    always @ (posedge RClk, posedge PresetEmpty)  //D Flip-Flop w/ Asynchronous Preset.
+        if (PresetEmpty)
+            Empty_out <= 1;
+        else
+            Empty_out <= 0;
+            
+endmodule
diff --git a/src/edu/berkeley/fleet/fpga/mem/ddr_clkgen.v b/src/edu/berkeley/fleet/fpga/mem/ddr_clkgen.v
new file mode 100644 (file)
index 0000000..3827a74
--- /dev/null
@@ -0,0 +1,181 @@
+//---------------------------------------------------------------------------
+// Wishbone DDR Controller
+// 
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//---------------------------------------------------------------------------
+
+`timescale 1ns / 1ps
+`include "ddr_include.v"
+
+module ddr_clkgen
+#(
+       parameter phase_shift  = 0,
+       parameter clk_multiply = 13,
+       parameter clk_divide   = 5
+) (
+       input        clk,
+       input        reset,
+       output       locked,
+       //
+       output       read_clk,
+       output       write_clk,
+       output       write_clk90,
+       // 
+       input  [2:0] rot
+);
+
+
+//----------------------------------------------------------------------------
+// rotary decoder
+//----------------------------------------------------------------------------
+rotary rotdec0 (
+       .clk(       clk        ),
+       .reset(     reset      ),
+       .rot(       rot        ),
+       // output
+       .rot_btn(   rot_btn    ),
+       .rot_event( rot_event  ),
+       .rot_left(  rot_left   )
+);
+
+//----------------------------------------------------------------------------
+// ~133 MHz DDR Clock generator
+//----------------------------------------------------------------------------
+wire  read_clk_u;
+wire  dcm_fx_locked;
+
+DCM #(
+       .CLKDV_DIVIDE(2.0),          // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
+                                 //   7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
+       .CLKFX_DIVIDE(clk_divide),   // Can be any integer from 1 to 32
+       .CLKFX_MULTIPLY(clk_multiply), // Can be any integer from 2 to 32
+       .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature
+       .CLKIN_PERIOD(),             // Specify period of input clock
+       .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE
+       .CLK_FEEDBACK("NONE"),       // Specify clock feedback of NONE, 1X or 2X
+       .DESKEW_ADJUST("SOURCE_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or
+                                 //   an integer from 0 to 15
+       .DFS_FREQUENCY_MODE("LOW"),  // HIGH or LOW frequency mode for frequency synthesis
+       .DLL_FREQUENCY_MODE("LOW"),  // HIGH or LOW frequency mode for DLL
+       .DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE
+       .FACTORY_JF(16'hC080),       // FACTORY JF values
+       .PHASE_SHIFT(0),             // Amount of fixed phase shift from -255 to 255
+       .STARTUP_WAIT("FALSE")       // Delay configuration DONE until DCM LOCK, TRUE/FALSE
+) dcm_fx (
+       .DSSEN(),
+       .CLK0(),                   // 0 degree DCM CLK output
+       .CLK180(),                 // 180 degree DCM CLK output
+       .CLK270(),                 // 270 degree DCM CLK output
+       .CLK2X(),                  // 2X DCM CLK output
+       .CLK2X180(),               // 2X, 180 degree DCM CLK out
+       .CLK90(),                  // 90 degree DCM CLK output
+       .CLKDV(),                  // Divided DCM CLK out (CLKDV_DIVIDE)
+       .CLKFX(    read_clk_u ),   // DCM CLK synthesis out (M/D)
+       .CLKFX180(),               // 180 degree CLK synthesis out
+       .LOCKED(   dcm_fx_locked), // DCM LOCK status output
+       .PSDONE(),                 // Dynamic phase adjust done output
+       .STATUS(),                 // 8-bit DCM status bits output
+       .CLKFB(),                  // DCM clock feedback
+       .CLKIN(    clk   ),        // Clock input (from IBUFG, BUFG or DCM)
+       .PSCLK(    gnd   ),        // Dynamic phase adjust clock input
+       .PSEN(     gnd   ),        // Dynamic phase adjust enable input
+       .PSINCDEC( gnd   ),        // Dynamic phase adjust increment/decrement
+       .RST(      reset )         // DCM asynchronous reset input
+);
+
+//----------------------------------------------------------------------------
+// BUFG read clock
+//----------------------------------------------------------------------------
+BUFG bufg_fx_clk (
+       .O(read_clk),             // Clock buffer output
+       .I(read_clk_u)            // Clock buffer input
+);
+
+//----------------------------------------------------------------------------
+// Phase shifted clock for write path 
+//----------------------------------------------------------------------------
+wire  phase_dcm_reset;
+wire  phase_dcm_locked;
+wire  write_clk_u, write_clk90_u, write_clk180_u, write_clk270_u;
+
+DCM #(
+       .CLKDV_DIVIDE(2.0),     // Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5
+                            //   7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0
+       .CLKFX_DIVIDE(2),       // Can be any integer from 1 to 32
+       .CLKFX_MULTIPLY(2),     // Can be any integer from 2 to 32
+       .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature
+       .CLKIN_PERIOD(),        // Specify period of input clock
+       .CLK_FEEDBACK("1X"),    // Specify clock feedback of NONE, 1X or 2X
+       .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or
+                                          //   an integer from 0 to 15
+       .DFS_FREQUENCY_MODE("LOW"),  // HIGH or LOW frequency mode for frequency synthesis
+       .DLL_FREQUENCY_MODE("LOW"),  // HIGH or LOW frequency mode for DLL
+       .DUTY_CYCLE_CORRECTION("TRUE"), // Duty cycle correction, TRUE or FALSE
+       .FACTORY_JF(16'hC080),   // FACTORY JF values
+       .CLKOUT_PHASE_SHIFT("VARIABLE"), // Specify phase shift of NONE, FIXED or VARIABLE
+       .PHASE_SHIFT( phase_shift ), // Amount of fixed phase shift from -255 to 255
+       .STARTUP_WAIT("FALSE")   // Delay configuration DONE until DCM LOCK, TRUE/FALSE
+) dcm_phase (
+       .DSSEN(),
+       .CLK0(   write_clk_u ),      // 0 degree DCM CLK output
+       .CLK90(  write_clk90_u ),    // 90 degree DCM CLK output
+       .CLK180( write_clk180_u ),   // 180 degree DCM CLK output
+       .CLK270( write_clk270_u ),   // 270 degree DCM CLK output
+       .CLK2X(),                    // 2X DCM CLK output
+       .CLK2X180(),                 // 2X, 180 degree DCM CLK out
+       .CLKDV(),                    // Divided DCM CLK out (CLKDV_DIVIDE)
+       .CLKFX(),                    // DCM CLK synthesis out (M/D)
+       .CLKFX180(),                 // 180 degree CLK synthesis out
+       .LOCKED( phase_dcm_locked ), // DCM LOCK status output
+       .PSDONE(),                   // Dynamic phase adjust done output
+       .STATUS(),                   // 8-bit DCM status bits output
+       .CLKFB( write_clk ),         // DCM clock feedback
+       .CLKIN( read_clk ),          // Clock input (from IBUFG, BUFG or DCM)
+       .PSCLK( clk ),               // Dynamic phase adjust clock input
+       .PSEN( rot_event ),          // Dynamic phase adjust enable input
+       .PSINCDEC( rot_left ),       // Dynamic phase adjust increment/decrement
+       .RST( phase_dcm_reset )      // DCM asynchronous reset input
+);
+
+reg [3:0] reset_counter;
+assign phase_dcm_reset = reset | (reset_counter != 0);
+
+always @(posedge clk)
+begin
+       if (reset) 
+               reset_counter <= 1;
+       else begin
+               if (dcm_fx_locked & (reset_counter != 0))
+                       reset_counter <= reset_counter + 1;
+       end
+end
+
+
+//----------------------------------------------------------------------------
+// BUFG write clock
+//----------------------------------------------------------------------------
+
+BUFG bufg_write_clk (
+       .O(write_clk  ),          // Clock buffer output
+       .I(write_clk_u)           // Clock buffer input
+);
+
+BUFG bufg_write_clk90 (
+       .O(write_clk90  ),        // Clock buffer output
+       .I(write_clk90_u)         // Clock buffer input
+);
+
+//----------------------------------------------------------------------------
+// LOCKED logic
+//----------------------------------------------------------------------------
+reg phase_dcm_locked_delayed;
+
+always @(posedge write_clk)
+begin
+       phase_dcm_locked_delayed <= phase_dcm_locked;
+end
+
+assign locked = ~reset & phase_dcm_locked_delayed;
+
+
+endmodule
diff --git a/src/edu/berkeley/fleet/fpga/mem/ddr_ctrl.v b/src/edu/berkeley/fleet/fpga/mem/ddr_ctrl.v
new file mode 100644 (file)
index 0000000..45218bd
--- /dev/null
@@ -0,0 +1,477 @@
+//----------------------------------------------------------------------------
+// Pipelined, asyncronous DDR Controller
+//
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//----------------------------------------------------------------------------
+module ddr_ctrl 
+#(
+       parameter clk_freq     = 50000000,
+       parameter clk_multiply = 12,
+       parameter clk_divide   = 5,
+       parameter phase_shift  = 0,
+       parameter wait200_init = 26
+) (
+       input                   clk, 
+       input                   reset,
+       //  DDR ports
+       output                  ddr_clk,
+       output                  ddr_clk_n,
+       input                   ddr_clk_fb,
+       output                  ddr_ras_n,
+       output                  ddr_cas_n,
+       output                  ddr_we_n,
+       output                  ddr_cke,
+       output                  ddr_cs_n,
+       output [  `A_RNG]       ddr_a,
+       output [ `BA_RNG]       ddr_ba,
+       inout  [ `DQ_RNG]       ddr_dq,
+       inout  [`DQS_RNG]       ddr_dqs,
+       output [ `DM_RNG]       ddr_dm,
+       // FML (FastMemoryLink)
+       input                   fml_wr,
+       input                   fml_rd,
+       output reg              fml_done,
+       input  [`FML_ADR_RNG]   fml_adr,
+       input  [`FML_DAT_RNG]   fml_din,
+       input  [`FML_MSK_RNG]   fml_msk,
+       output reg [`FML_DAT_RNG]   fml_dout,
+       // Temporary DCM control input
+       input  [2:0]            rot      // XXX
+);
+
+wire [ `DQ_RNG]       ddr_dq_i,  ddr_dq_o;
+wire [`DQS_RNG]       ddr_dqs_i, ddr_dqs_o;
+wire                  ddr_dqs_oe;
+
+//----------------------------------------------------------------------------
+// clock generator
+//----------------------------------------------------------------------------
+wire clk_locked;
+wire write_clk, write_clk90;
+wire read_clk;
+
+wire reset_int = reset | ~clk_locked;
+
+ddr_clkgen #(
+       .phase_shift(  phase_shift  ),
+       .clk_multiply( clk_multiply ),
+       .clk_divide(   clk_divide   )
+) clkgen (
+       .clk(             clk            ),
+       .reset(           reset          ),
+       .locked(          clk_locked     ),
+       // ddr-clk 
+       .read_clk(        read_clk       ),
+       .write_clk(       write_clk      ),
+       .write_clk90(     write_clk90    ),
+       // phase shift control
+       .rot(             rot            )      // XXX
+);
+
+//----------------------------------------------------------------------------
+// async_fifos (cmd, wdata, rdata)
+//----------------------------------------------------------------------------
+wire                  cba_fifo_full;
+reg  [`CBA_RNG]       cba_fifo_din;
+reg                   cba_fifo_we;
+
+wire                  wfifo_full;
+reg   [`WFIFO_RNG]    wfifo_din;
+reg                   wfifo_we;
+
+
+wire [`RFIFO_RNG]     rfifo_dout;
+wire                  rfifo_empty;
+wire                  rfifo_next;
+
+//----------------------------------------------------------------------------
+// High-speed cmd, write and read datapath
+//----------------------------------------------------------------------------
+ddr_wpath wpath0 (
+       .clk(         write_clk    ),
+       .clk90(       write_clk90  ),
+       .reset(       reset_int    ),
+       // CBA async fifo
+       .cba_clk(     clk           ),
+       .cba_din(     cba_fifo_din  ),
+       .cba_wr(      cba_fifo_we   ),
+       .cba_full(    cba_fifo_full ),
+       // WDATA async fifo
+       .wdata_clk(   clk           ),
+       .wdata_din(   wfifo_din     ),
+       .wdata_wr(    wfifo_we      ),
+       .wdata_full(  wfifo_full    ),
+       //
+       .sample(     sample      ), 
+       // DDR
+       .ddr_clk(     ddr_clk    ),
+       .ddr_clk_n(   ddr_clk_n  ),
+       .ddr_ras_n(   ddr_ras_n  ),
+       .ddr_cas_n(   ddr_cas_n  ),
+       .ddr_we_n(    ddr_we_n   ),
+       .ddr_a(       ddr_a      ),
+       .ddr_ba(      ddr_ba     ),
+       .ddr_dm(      ddr_dm     ),
+       .ddr_dq(      ddr_dq_o   ),
+       .ddr_dqs(     ddr_dqs_o  ),
+       .ddr_dqs_oe(  ddr_dqs_oe )
+);
+
+ddr_rpath rpath0 (
+       .clk(         read_clk   ),
+       .reset(       reset_int  ),
+       // 
+       .sample(      sample     ),
+       //
+       .rfifo_clk(   clk        ),
+       .rfifo_empty( rfifo_empty),
+       .rfifo_dout(  rfifo_dout ),
+       .rfifo_next(  rfifo_next ),
+       // DDR
+       .ddr_dq(      ddr_dq_i   ),
+       .ddr_dqs(     ddr_dqs_i  )
+);
+
+//----------------------------------------------------------------------------
+// 7.8 us pulse generator
+//----------------------------------------------------------------------------
+wire pulse78;
+reg  ar_req;
+reg  ar_done;
+
+ddr_pulse78 #(
+       .clk_freq( clk_freq )
+) pulse78_gen (
+       .clk(      clk        ),
+       .reset(    reset_int  ),
+       .pulse78(  pulse78    )
+);
+
+//----------------------------------------------------------------------------
+// Auto Refresh request generator
+//----------------------------------------------------------------------------
+always @(posedge clk)
+       if (reset_int)
+               ar_req <= 0;
+       else
+               ar_req <= pulse78 | (ar_req & ~ar_done);
+
+// operations we might want to submit
+wire [`CBA_RNG] ar_pre_cba;
+wire [`CBA_RNG] ar_ar_cba;
+
+assign ar_pre_cba   = { `DDR_CMD_PRE, 2'b00, 13'b1111111111111 };
+assign ar_ar_cba    = { `DDR_CMD_AR,  2'b00, 13'b0000000000000 };
+
+//----------------------------------------------------------------------------
+// Init & management
+//----------------------------------------------------------------------------
+wire                 init_req;
+reg                  init_ack;
+wire [`CBA_RNG]      init_cba;
+wire                 init_done;
+wire                 wait200;
+
+ddr_init #(
+       .wait200_init( wait200_init )
+) init (
+       .clk(         clk         ),
+       .reset(       reset_int   ),
+       .pulse78(     pulse78     ),
+       .wait200(     wait200     ),
+       .init_done(   init_done   ),
+       //
+       .mngt_req(    init_req    ),
+       .mngt_ack(    init_ack    ),
+       .mngt_cba(    init_cba    )
+);
+
+//----------------------------------------------------------------------------
+// Active Bank Information 
+//----------------------------------------------------------------------------
+reg [`ROW_RNG] ba_row [3:0];
+reg [3:0]      ba_active;
+
+//----------------------------------------------------------------------------
+// Handle write FIFO
+//----------------------------------------------------------------------------
+wire wfifo_proc_reset;
+wire wfifo_proc_start;
+reg  wfifo_proc_done;
+
+parameter w_idle   = 0;
+parameter w_1      = 1;
+parameter w_2      = 2;
+parameter w_3      = 3;
+parameter w_finish = 4;
+
+reg [2:0] wstate;
+
+always @(posedge clk)
+begin
+       if (reset_int) begin
+               wstate          <= w_idle;
+               wfifo_proc_done <= 0;
+       end else begin
+               wfifo_we <= 0;
+
+               case (wstate)
+                       w_idle: begin
+                               if (wfifo_proc_start & ~wfifo_full) begin
+                                       wfifo_din[`WFIFO_D0_RNG] <= fml_din[15: 0];
+                                       wfifo_din[`WFIFO_D1_RNG] <= fml_din[31:16];
+                                       wfifo_din[`WFIFO_M0_RNG] <= fml_msk[ 1: 0];
+                                       wfifo_din[`WFIFO_M1_RNG] <= fml_msk[ 3: 2];
+                                       wfifo_we                 <= 1;
+                                       wstate                   <= w_1;
+                               end
+                       end
+                       w_1: begin
+                               if (~wfifo_full) begin
+                                       wfifo_din[`WFIFO_D0_RNG] <= fml_din[47:32];
+                                       wfifo_din[`WFIFO_D1_RNG] <= fml_din[63:48];
+                                       wfifo_din[`WFIFO_M0_RNG] <= fml_msk[ 5: 4];
+                                       wfifo_din[`WFIFO_M1_RNG] <= fml_msk[ 7: 6];
+                                       wfifo_we                 <= 1;
+                                       wstate                   <= w_2;
+                               end
+                       end
+                       w_2: begin
+                               if (~wfifo_full) begin
+                                       wfifo_din[`WFIFO_D0_RNG] <= fml_din[79:64];
+                                       wfifo_din[`WFIFO_D1_RNG] <= fml_din[95:80];
+                                       wfifo_din[`WFIFO_M0_RNG] <= fml_msk[ 9: 8];
+                                       wfifo_din[`WFIFO_M1_RNG] <= fml_msk[11:10];
+                                       wfifo_we                 <= 1;
+                                       wstate                   <= w_3;
+                               end
+                       end
+                       w_3: begin
+                               if (~wfifo_full) begin
+                                       wfifo_din[`WFIFO_D0_RNG] <= fml_din[111: 96];
+                                       wfifo_din[`WFIFO_D1_RNG] <= fml_din[127:112];
+                                       wfifo_din[`WFIFO_M0_RNG] <= fml_msk[12:12];
+                                       wfifo_din[`WFIFO_M1_RNG] <= fml_msk[15:14];
+                                       wfifo_we                 <= 1;
+                                       wstate                   <= w_finish;
+                                       wfifo_proc_done          <= 1;
+                               end
+                       end
+                       w_finish: begin
+                               if (wfifo_proc_reset) begin
+                                       wstate          <= w_idle;
+                                       wfifo_proc_done <= 0;
+                               end
+                       end
+               endcase
+       end
+end
+
+//----------------------------------------------------------------------------
+// Handle read FIFO
+//----------------------------------------------------------------------------
+wire rfifo_proc_reset;
+wire rfifo_proc_start;
+reg  rfifo_proc_done ;
+
+parameter r_idle   = 0;
+parameter r_1      = 1;
+parameter r_2      = 2;
+parameter r_3      = 3;
+parameter r_finish = 4;
+
+reg [2:0] rstate;
+
+assign rfifo_next = ~rfifo_empty;
+
+always @(posedge clk)
+begin
+       if (reset_int) begin
+               rstate          <= r_idle;
+               rfifo_proc_done <= 0;
+       end else begin
+               case (rstate)
+                       r_idle: begin
+                               if (rfifo_proc_start & ~rfifo_empty) begin
+                                       fml_dout[31:0]   <= rfifo_dout;
+                                       rstate           <= r_1;
+                               end
+                       end
+                       r_1: begin
+                               if (~rfifo_empty) begin
+                                       fml_dout[63:32]  <= rfifo_dout;
+                                       rstate           <= r_2;
+                               end
+                       end
+                       r_2: begin
+                               if (~rfifo_empty) begin
+                                       fml_dout[95:64]  <= rfifo_dout;
+                                       rstate           <= r_3;
+                               end
+                       end
+                       r_3: begin
+                               if (~rfifo_empty) begin
+                                       fml_dout[127:96] <= rfifo_dout;
+                                       rstate           <= r_finish;
+                                       rfifo_proc_done  <= 1;
+                               end
+                       end
+                       r_finish: begin
+                               if (rfifo_proc_reset) begin
+                                       rfifo_proc_done  <= 0;
+                                       rstate           <= r_idle;
+                               end
+                       end
+               endcase
+       end
+end
+
+//----------------------------------------------------------------------------
+// FML decoding
+//----------------------------------------------------------------------------
+wire [`FML_ADR_BA_RNG]    fml_ba  = fml_adr[`FML_ADR_BA_RNG];
+wire [`FML_ADR_ROW_RNG]   fml_row = fml_adr[`FML_ADR_ROW_RNG];
+wire [`FML_ADR_COL_RNG]   fml_col = fml_adr[`FML_ADR_COL_RNG];
+
+wire [`FML_ADR_ROW_RNG]   fml_cur_row;   // current active row in sel. bank
+assign fml_cur_row    = ba_row[fml_ba];
+
+wire   fml_row_active;  // is row in selected ba really active?
+assign fml_row_active = ba_active[fml_ba]; 
+
+
+/*
+wire   fml_row_active = (fml_ba == 0) ? ba0_active :     // is row in selected
+                        (fml_ba == 1) ? ba1_active :     // bank really active?
+                        (fml_ba == 2) ? ba2_active :
+                                        ba3_active ;
+*/
+
+// request operation iff correct bank is active
+wire fml_req       = fml_rd | fml_wr;
+wire fml_row_match = (fml_row == fml_cur_row) & fml_row_active;
+wire fml_pre_req   = fml_req & ~fml_row_match & fml_row_active;
+wire fml_act_req   = fml_req & ~fml_row_active;
+wire fml_read_req  = fml_rd  &  fml_row_match & ~fml_done;
+wire fml_write_req = fml_wr  &  fml_row_match & ~fml_done;
+
+// actual operations we might want to submit
+wire [`CBA_RNG] fml_pre_cba;
+wire [`CBA_RNG] fml_act_cba;
+wire [`CBA_RNG] fml_read_cba;
+wire [`CBA_RNG] fml_write_cba;
+
+assign fml_pre_cba   = { `DDR_CMD_PRE,   fml_ba, 13'b0  };
+assign fml_act_cba   = { `DDR_CMD_ACT,   fml_ba, fml_row };
+assign fml_read_cba  = { `DDR_CMD_READ,  fml_ba, {3'b000}, fml_col, {3'b000} };
+assign fml_write_cba = { `DDR_CMD_WRITE, fml_ba, {3'b000}, fml_col, {3'b000} };
+
+//----------------------------------------------------------------------------
+// Schedule and issue commands
+//----------------------------------------------------------------------------
+
+parameter s_init      = 0;
+parameter s_idle      = 1;
+parameter s_ar        = 2;
+parameter s_reading   = 3;
+
+reg [1:0] state;
+
+always @(posedge clk)
+begin
+       if (reset_int) begin
+               state        <= s_init;
+               ba_active    <= 0;
+               ba_row[0]    <= 0;
+               ba_row[1]    <= 0;
+               ba_row[2]    <= 0;
+               ba_row[3]    <= 0;
+
+               fml_done     <= 0;
+               init_ack     <= 0;
+               cba_fifo_we  <= 0;
+               ar_done      <= 0;
+       end else begin
+               fml_done     <= 0;
+               init_ack     <= 0;
+               cba_fifo_we  <= 0;
+               ar_done      <= 0;
+
+               case (state)
+                       s_init: begin
+                               if (init_done)
+                                       state <= s_idle;
+
+                               if (init_req & ~cba_fifo_full) begin
+                                       cba_fifo_we       <= 1;
+                                       cba_fifo_din      <= init_cba;
+                                       init_ack          <= 1;
+                               end
+                       end
+                       s_idle: begin
+                               if (fml_read_req & ~cba_fifo_full) begin
+                                       cba_fifo_we       <= 1;
+                                       cba_fifo_din      <= fml_read_cba;
+                                       state             <= s_reading;
+                               end else if (fml_write_req & ~cba_fifo_full & wfifo_proc_done) begin
+                                       cba_fifo_we       <= 1;
+                                       cba_fifo_din      <= fml_write_cba;
+                                       fml_done          <= 1;
+                               end else if (ar_req & ~cba_fifo_full) begin
+                                       cba_fifo_we       <= 1;
+                                       cba_fifo_din      <= ar_pre_cba;
+                                       ar_done           <= 1;
+                                       ba_active         <= 'b0;
+                                       state             <= s_ar;
+                               end else if (fml_pre_req & ~cba_fifo_full) begin
+                                       cba_fifo_we       <= 1;
+                                       cba_fifo_din      <= fml_pre_cba;
+                                       ba_active[fml_ba] <= 0;
+                               end else if (fml_act_req & ~cba_fifo_full) begin
+                                       cba_fifo_we       <= 1;
+                                       cba_fifo_din      <= fml_act_cba;
+                                       ba_active[fml_ba] <= 1;
+                                       ba_row[fml_ba]    <= fml_row;
+                               end
+                       end
+                       s_ar: begin
+                               if (~cba_fifo_full) begin
+                                       cba_fifo_we       <= 1;
+                                       cba_fifo_din      <= ar_ar_cba;
+                                       state             <= s_idle;
+                               end
+                       end
+                       s_reading: begin
+                               if (rfifo_proc_done) begin
+                                       fml_done          <= 1;
+                                       state             <= s_idle;
+                               end
+                       end
+               endcase
+       end
+end
+
+// start and stop rfifo engine
+assign rfifo_proc_start = fml_read_req;
+assign rfifo_proc_reset = fml_done;
+
+// start and stop wfifo engine
+assign wfifo_proc_start = fml_wr;
+assign wfifo_proc_reset = fml_done;
+
+//----------------------------------------------------------------------------
+// Demux dqs and dq
+//----------------------------------------------------------------------------
+assign ddr_cke   = ~wait200;     // bring up CKE as soon 200us wait is finished
+
+assign ddr_dqs = ddr_dqs_oe!=1'b0 ? ddr_dqs_o : 'bz;
+assign ddr_dq  = ddr_dqs_oe!=1'b0 ? ddr_dq_o  : 'bz;
+
+assign ddr_dqs_i = ddr_dqs;
+assign ddr_dq_i  = ddr_dq;
+
+assign ddr_cs_n = 0;
+
+endmodule
+
+// vim: set ts=4
diff --git a/src/edu/berkeley/fleet/fpga/mem/ddr_include.v b/src/edu/berkeley/fleet/fpga/mem/ddr_include.v
new file mode 100644 (file)
index 0000000..f77be87
--- /dev/null
@@ -0,0 +1,89 @@
+//---------------------------------------------------------------------------
+// DDR Controller
+// 
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//---------------------------------------------------------------------------
+
+`ifdef DDR_INCLUDE_V
+`else
+`define DDR_INCLUDE_V
+
+`timescale 1ns/10ps
+
+//---------------------------------------------------------------------------
+// Frequency 
+//---------------------------------------------------------------------------
+`define SYS_CLK_FREQUENCY   50000     // in kHz
+`define DDR_CLK_MULTIPLY    5        
+`define DDR_CLK_DIVIDE      2
+
+//---------------------------------------------------------------------------
+// FML ranges
+//---------------------------------------------------------------------------
+`define FML_ADR_RNG     25:4 
+`define FML_ADR_BA_RNG  25:24
+`define FML_ADR_ROW_RNG 23:11
+`define FML_ADR_COL_RNG 10:4
+`define FML_DAT_RNG    127:0
+`define FML_MSK_RNG     15:0
+
+//---------------------------------------------------------------------------
+// Width
+//---------------------------------------------------------------------------
+`define CMD_WIDTH  3
+`define A_WIDTH    13
+`define BA_WIDTH   2
+`define DQ_WIDTH   16
+`define DQS_WIDTH  2
+`define DM_WIDTH   2
+
+`define RFIFO_WIDTH  (2 * `DQ_WIDTH )
+`define WFIFO_WIDTH  (2 * (`DQ_WIDTH + `DM_WIDTH))
+`define CBA_WIDTH    (`CMD_WIDTH+`BA_WIDTH+`A_WIDTH)
+
+// Ranges
+`define CMD_RNG      (`CMD_WIDTH-1):0
+`define A_RNG        (`A_WIDTH-1):0
+`define BA_RNG       (`BA_WIDTH-1):0
+`define DQ_RNG       (`DQ_WIDTH-1):0
+`define DQS_RNG      (`DQS_WIDTH-1):0
+`define DM_RNG       (`DM_WIDTH-1):0
+
+`define RFIFO_RNG    (`RFIFO_WIDTH-1):0
+`define WFIFO_RNG    (`WFIFO_WIDTH-1):0
+`define WFIFO_D0_RNG (1*`DQ_WIDTH-1):0
+`define WFIFO_D1_RNG (2*`DQ_WIDTH-1):(`DQ_WIDTH)
+`define WFIFO_M0_RNG (2*`DQ_WIDTH+1*`DM_WIDTH-1):(2*`DQ_WIDTH+0*`DM_WIDTH)
+`define WFIFO_M1_RNG (2*`DQ_WIDTH+2*`DM_WIDTH-1):(2*`DQ_WIDTH+1*`DM_WIDTH)
+`define CBA_RNG      (`CBA_WIDTH-1):0
+`define CBA_CMD_RNG  (`CBA_WIDTH-1):(`CBA_WIDTH-3)
+`define CBA_BA_RNG   (`CBA_WIDTH-4):(`CBA_WIDTH-5)
+`define CBA_A_RNG    (`CBA_WIDTH-6):0
+
+`define ROW_RNG      12:0
+
+//---------------------------------------------------------------------------
+// DDR 
+//---------------------------------------------------------------------------
+`define DDR_CMD_NOP   3'b111
+`define DDR_CMD_ACT   3'b011
+`define DDR_CMD_READ  3'b101
+`define DDR_CMD_WRITE 3'b100
+`define DDR_CMD_TERM  3'b110
+`define DDR_CMD_PRE   3'b010
+`define DDR_CMD_AR    3'b001
+`define DDR_CMD_MRS   3'b000
+
+`define T_MRD   2           // Mode register set 
+`define T_RP    2           // Precharge Command Period
+`define T_RFC   8           // Precharge Command Period
+
+`define DDR_INIT_EMRS  `A_WIDTH'b0000000000000  // DLL enable
+`define DDR_INIT_MRS1  `A_WIDTH'b0000101100011  // BURST=8, CL=2.5, DLL RESET
+`define DDR_INIT_MRS2  `A_WIDTH'b0000001100011  // BURST=8, CL=2.5
+
+`define ADR_BA_RNG    25:24
+`define ADR_ROW_RNG   23:11
+`define ADR_COL_RNG   10:4
+
+`endif
diff --git a/src/edu/berkeley/fleet/fpga/mem/ddr_init.v b/src/edu/berkeley/fleet/fpga/mem/ddr_init.v
new file mode 100644 (file)
index 0000000..343d0af
--- /dev/null
@@ -0,0 +1,191 @@
+//----------------------------------------------------------------------------
+// Wishbone DDR Controller
+// 
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//----------------------------------------------------------------------------
+`include "ddr_include.v"
+
+module ddr_init 
+#(
+       parameter               wait200_init = 26
+) (
+       input                   clk, 
+       input                   reset,
+       input                   pulse78,
+       output                  wait200,
+       output                  init_done,
+       //
+       output                  mngt_req,
+       input                   mngt_ack,
+       output [`CBA_RNG]       mngt_cba       // CMD, BA and ADDRESS
+);
+
+reg              cmd_req_reg;
+reg [`CMD_RNG]   cmd_cmd_reg;
+reg [ `BA_RNG]   cmd_ba_reg;
+reg [  `A_RNG]   cmd_a_reg;
+reg [7:0]        cmd_idle_reg;
+
+//---------------------------------------------------------------------------
+// Initial 200us delay
+//---------------------------------------------------------------------------
+
+// `define WAIT200_INIT 26
+// `define WAIT200_INIT 1
+
+reg [4:0] wait200_counter;
+reg       wait200_reg;
+
+always @(posedge clk)
+begin
+       if (reset) begin
+               wait200_reg     <= 1;
+               wait200_counter <= wait200_init;
+       end else begin
+               if (wait200_counter == 0)
+                       wait200_reg <= 0;
+
+               if (wait200_reg & pulse78)
+                       wait200_counter <= wait200_counter - 1;
+       end
+end
+
+assign wait200 = wait200_reg;
+
+//---------------------------------------------------------------------------
+// Auto refresh counter
+//---------------------------------------------------------------------------
+
+reg [2:0] ar_counter;
+wire      ar_cmd_acked;
+wire      ar_needed;
+wire      ar_badly_needed;
+
+assign ar_cmd_acked    = (cmd_cmd_reg == `DDR_CMD_AR) & mngt_ack;
+assign ar_needed       = (ar_counter != 0) & ~ar_cmd_acked; 
+assign ar_badly_needed = ar_counter[2] == 1'b1;  // >= 4
+
+always @(posedge clk)
+begin
+       if (reset) begin
+               ar_counter <= 0;
+       end else begin
+               if (~init_done)
+                       ar_counter <= 0;
+               else if (pulse78 & ~ar_cmd_acked) 
+                       ar_counter <= ar_counter + 1;
+               else if (ar_cmd_acked & ~pulse78) 
+                       ar_counter <= ar_counter - 1;
+       end
+end
+
+//----------------------------------------------------------------------------
+// DDR Initialization State Machine
+//----------------------------------------------------------------------------
+
+parameter s_wait200 = 0;
+parameter s_init1   = 1;
+parameter s_init2   = 2;
+parameter s_init3   = 3;
+parameter s_init4   = 4;
+parameter s_init5   = 5;
+parameter s_init6   = 6;
+parameter s_waitack = 7;
+parameter s_idle    = 8;
+
+reg [3:0]        state;
+reg              init_done_reg;
+
+assign mngt_cba     = {cmd_cmd_reg, cmd_ba_reg, cmd_a_reg};
+assign mngt_req     = cmd_req_reg;
+assign mngt_pri_req = ~init_done_reg;
+assign init_done    = init_done_reg;
+
+always @(posedge clk or posedge reset)
+begin
+       if (reset) begin
+               init_done_reg <= 0;
+               state         <= s_wait200;
+               cmd_idle_reg  <= 0;
+               cmd_req_reg   <= 0;
+               cmd_cmd_reg   <= 'b0;
+               cmd_ba_reg    <= 'b0;
+               cmd_a_reg     <= 'b0;
+       end else begin
+               case (state)
+                       s_wait200: begin
+                               if (~wait200_reg) begin
+                                               state         <= s_init1;
+                                               cmd_req_reg   <= 1;
+                                               cmd_cmd_reg   <= `DDR_CMD_PRE;   // PRE ALL
+                                               cmd_a_reg[10] <= 1'b1;
+                                       end
+                               end
+                       s_init1: begin
+                                       if (mngt_ack) begin
+                                               state         <= s_init2;
+                                               cmd_req_reg   <= 1;
+                                               cmd_cmd_reg   <= `DDR_CMD_MRS;   // EMRS
+                                               cmd_ba_reg    <= 2'b01;
+                                               cmd_a_reg     <= `DDR_INIT_EMRS;
+                                       end
+                               end
+                       s_init2: begin
+                                       if (mngt_ack) begin
+                                               state         <= s_init3;
+                                               cmd_req_reg   <= 1;
+                                               cmd_cmd_reg   <= `DDR_CMD_MRS;   // MRS
+                                               cmd_ba_reg    <= 2'b00;
+                                               cmd_a_reg     <= `DDR_INIT_MRS1;
+                                       end
+                               end
+                       s_init3: begin
+                                       if (mngt_ack) begin
+                                               state         <= s_init4;
+                                               cmd_req_reg   <= 1;
+                                               cmd_cmd_reg   <= `DDR_CMD_PRE;   // PRE ALL
+                                               cmd_a_reg[10] <= 1'b1;
+                                       end
+                               end
+                       s_init4: begin
+                                       if (mngt_ack) begin
+                                               state         <= s_init5;
+                                               cmd_req_reg   <= 1;
+                                               cmd_cmd_reg   <= `DDR_CMD_AR;   // AR
+                                       end
+                               end
+                       s_init5: begin
+                                       if (mngt_ack) begin
+                                               state         <= s_init6;
+                                               cmd_req_reg   <= 1;
+                                               cmd_cmd_reg   <= `DDR_CMD_AR;   // AR
+                                       end
+                               end
+                       s_init6: begin
+                                       if (mngt_ack) begin
+                                               init_done_reg <= 1;
+                                               state         <= s_waitack;
+                                               cmd_req_reg   <= 1;
+                                               cmd_cmd_reg   <= `DDR_CMD_MRS;  // MRS
+                                               cmd_ba_reg    <= 2'b00;
+                                               cmd_a_reg     <= `DDR_INIT_MRS2;
+                                       end
+                               end
+                       s_waitack: begin
+                                       if (mngt_ack) begin
+                                               state         <= s_idle;
+                                               cmd_req_reg   <= 0;
+                                               cmd_cmd_reg   <= 'b0;
+                                               cmd_ba_reg    <= 'b0;
+                                               cmd_a_reg     <= 'b0;
+                                       end
+                               end
+                       s_idle: begin
+                               end
+               endcase ///////////////////////////////////////// INIT STATE MACHINE ///
+       end
+end
+
+
+endmodule
+
diff --git a/src/edu/berkeley/fleet/fpga/mem/ddr_pulse78.v b/src/edu/berkeley/fleet/fpga/mem/ddr_pulse78.v
new file mode 100644 (file)
index 0000000..396576e
--- /dev/null
@@ -0,0 +1,43 @@
+//----------------------------------------------------------------------------
+// Wishbone DDR Controller
+// 
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//----------------------------------------------------------------------------
+`include "ddr_include.v"
+
+module ddr_pulse78 #(
+       parameter    clk_freq = 50000000
+) (
+       input        clk,
+       input        reset,
+       //
+       output   reg pulse78
+);
+
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+`define PULSE78_RNG  10:0
+
+parameter pulse78_init = 78 * (clk_freq/10000000);
+
+reg [`PULSE78_RNG] counter;
+
+always @(posedge clk)
+begin
+       if (reset) begin
+               counter <= pulse78_init;
+               pulse78 <= 0;
+       end else begin
+               if (counter == 0) begin
+                       counter <= pulse78_init;
+                       pulse78 <= 1'b1;
+               end else begin
+                       counter <= counter - 1;
+                       pulse78 <= 0;
+               end
+       end
+end
+
+endmodule
+
diff --git a/src/edu/berkeley/fleet/fpga/mem/ddr_rpath.v b/src/edu/berkeley/fleet/fpga/mem/ddr_rpath.v
new file mode 100644 (file)
index 0000000..3286003
--- /dev/null
@@ -0,0 +1,112 @@
+//----------------------------------------------------------------------------
+// Wishbone DDR Controller
+// 
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//----------------------------------------------------------------------------
+
+`include "ddr_include.v"
+
+module ddr_rpath
+(
+       input                  clk,
+       input                  reset,
+       // sample activate
+       input                  sample,
+       // RDATA async fifo
+       input                  rfifo_clk,
+       output                 rfifo_empty,
+       output [`RFIFO_RNG]    rfifo_dout,
+       input                  rfifo_next,
+       // DDR 
+       input [ `DQ_RNG]       ddr_dq,
+       input [`DQS_RNG]       ddr_dqs
+);
+
+//----------------------------------------------------------------------------
+// RDATA async. fifo
+//----------------------------------------------------------------------------
+
+wire [`RFIFO_RNG]      rfifo_din;
+wire                   rfifo_wr;
+wire                   rfifo_full;
+
+async_fifo #(
+       .DATA_WIDTH( `RFIFO_WIDTH ),
+       .ADDRESS_WIDTH( 3 )
+) rfifo (
+       .Data_out(   rfifo_dout  ),
+       .Empty_out(  rfifo_empty ),
+       .ReadEn_in(  rfifo_next  ),
+       .RClk(       rfifo_clk   ),
+       //
+       .Data_in(    rfifo_din   ),
+       .WriteEn_in( rfifo_wr    ),
+       .Full_out(   rfifo_full  ),
+       .WClk(      ~clk         ),
+       .Clear_in(   reset       )
+);
+
+
+//----------------------------------------------------------------------------
+// Clean up incoming 'sample' signal and generate sample_dq
+//----------------------------------------------------------------------------
+
+// anti-meta-state
+//reg       sample180; 
+//always @(negedge clk) sample180 <= sample;
+wire sample180 = sample;
+
+
+reg       sample_dq;          // authoritive sample flag (after cleanup)
+reg       sample_dq_delayed;  // write to rfifo?
+reg [3:0] sample_count;       // make sure sample_dq is up exactly 
+                              // BURSTLENGTH/2 cycles
+
+always @(posedge clk or posedge reset)
+begin
+       if (reset) begin
+               sample_dq         <= 0;
+               sample_dq_delayed <= 0;
+               sample_count      <= 0;
+       end else begin
+               sample_dq_delayed <= sample_dq;
+               if (sample_count == 0) begin
+                       if (sample180) begin
+                               sample_dq    <= 1;
+                               sample_count <= 1;
+                       end
+               end else if (sample_count == 4) begin
+                       sample_dq    <= 0;
+                       sample_count <= 0;
+               end else
+                       sample_count <= sample_count + 1;
+                       
+       end
+end
+
+//----------------------------------------------------------------------------
+// Sampe DQ and fill RFIFO
+//----------------------------------------------------------------------------
+reg [15:0] ddr_dq_low, ddr_dq_high;
+
+always @(negedge clk )
+begin
+       if (reset)
+               ddr_dq_low <= 'b0;
+       else
+               ddr_dq_low <= ddr_dq;
+end
+
+always @(posedge clk)
+begin
+       if (reset)
+               ddr_dq_high <= 'b0;
+       else
+               ddr_dq_high <= ddr_dq;
+end
+
+assign rfifo_wr  = sample_dq_delayed;
+assign rfifo_din = { ddr_dq_high, ddr_dq_low };
+
+endmodule
+
diff --git a/src/edu/berkeley/fleet/fpga/mem/ddr_wpath.v b/src/edu/berkeley/fleet/fpga/mem/ddr_wpath.v
new file mode 100644 (file)
index 0000000..f1f1ee3
--- /dev/null
@@ -0,0 +1,286 @@
+//----------------------------------------------------------------------------
+//
+// Wishbone DDR Controller -- fast write data-path
+// 
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//
+//----------------------------------------------------------------------------
+
+`include "ddr_include.v"
+
+module ddr_wpath (
+       input                  clk,
+       input                  clk90,
+       input                  reset,
+       // CBA async fifo
+       input                  cba_clk,
+       input [`CBA_RNG]       cba_din,
+       input                  cba_wr,
+       output                 cba_full,
+       // WDATA async fifo
+       input                  wdata_clk,
+       input [`WFIFO_RNG]     wdata_din,
+       input                  wdata_wr,
+       output                 wdata_full,
+       // sample to rdata
+       output                 sample,
+       // DDR 
+       output                 ddr_clk,
+       output                 ddr_clk_n,
+       output                 ddr_ras_n,
+       output                 ddr_cas_n,
+       output                 ddr_we_n,
+       output [  `A_RNG]      ddr_a,
+       output [ `BA_RNG]      ddr_ba,
+       output [ `DM_RNG]      ddr_dm,
+       output [ `DQ_RNG]      ddr_dq,
+       output [`DQS_RNG]      ddr_dqs,
+       output                 ddr_dqs_oe
+);
+
+wire gnd = 1'b0;
+wire vcc = 1'b1;
+
+//----------------------------------------------------------------------------
+// CBA async. fifo
+//----------------------------------------------------------------------------
+wire [`CBA_RNG]        cba_data;
+wire                   cba_empty;
+wire                   cba_ack;
+
+wire                   cba_avail = ~cba_empty;
+
+async_fifo #(
+       .DATA_WIDTH( `CBA_WIDTH ),
+       .ADDRESS_WIDTH( 3 )
+) cba_fifo (
+       .Data_out(   cba_data  ),
+       .Empty_out(  cba_empty ),
+       .ReadEn_in(  cba_ack   ),
+       .RClk(       clk       ),
+       //
+       .Data_in(    cba_din   ),
+       .WriteEn_in( cba_wr    ),
+       .Full_out(   cba_full  ),
+       .WClk(       cba_clk   ),
+       .Clear_in(   reset     )
+);
+
+//----------------------------------------------------------------------------
+// WDATA async. fifo
+//----------------------------------------------------------------------------
+wire [`WFIFO_RNG]      wdata_data;
+wire                   wdata_empty;
+wire                   wdata_ack;
+
+wire                   wdata_avail = ~wdata_empty;
+
+async_fifo #(
+       .DATA_WIDTH( `WFIFO_WIDTH ),
+       .ADDRESS_WIDTH( 3 )
+) wdata_fifo (
+       .Data_out(   wdata_data  ),
+       .Empty_out(  wdata_empty ),
+       .ReadEn_in(  wdata_ack   ),
+       .RClk(      ~clk90       ),
+       //
+       .Data_in(    wdata_din   ),
+       .WriteEn_in( wdata_wr    ),
+       .Full_out(   wdata_full  ),
+       .WClk(       wdata_clk   ),
+       .Clear_in(   reset       )
+);
+
+
+//----------------------------------------------------------------------------
+// Handle CBA 
+//----------------------------------------------------------------------------
+reg  [3:0]      delay_count;
+
+reg [`CBA_RNG]  ddr_cba;
+wire [`CBA_RNG] CBA_NOP = { `DDR_CMD_NOP, 15'b0 };
+
+assign cba_ack = cba_avail & (delay_count == 0);
+
+wire [`CMD_RNG] cba_cmd = cba_data[(`CBA_WIDTH-1):(`CBA_WIDTH-3)];
+
+always @(posedge clk)
+begin
+       if (reset) begin
+               delay_count <= 0;
+               ddr_cba     <= CBA_NOP;
+       end else begin
+               if (delay_count != 0) begin
+                       delay_count <= delay_count - 1;
+                       ddr_cba     <= CBA_NOP;
+        end
+
+               if (!cba_ack) begin
+                       ddr_cba  <= CBA_NOP;
+               end else begin
+                       ddr_cba <= cba_data;
+
+                       case (cba_cmd)
+                               `DDR_CMD_MRS   : delay_count <= 2;
+                               `DDR_CMD_AR    : delay_count <= 14;
+                               `DDR_CMD_ACT   : delay_count <= 4;
+                               `DDR_CMD_PRE   : delay_count <= 2;
+                               `DDR_CMD_READ  : delay_count <= 6;   // XXX
+                               `DDR_CMD_WRITE : delay_count <= 8;   // XXX
+                       endcase
+               end
+       end
+end
+                       
+
+//----------------------------------------------------------------------------
+// READ-SHIFT-REGISTER
+//----------------------------------------------------------------------------
+reg [0:7] read_shr;
+wire      read_cmd = (cba_cmd == `DDR_CMD_READ) & cba_ack;
+assign    sample   = read_shr[1];
+
+always @(posedge clk)
+begin
+       if (reset)
+               read_shr <= 'b0;
+       else begin
+               if (read_cmd)
+                       read_shr <= { 8'b00011111 };
+               else
+                       read_shr <= { read_shr[1:7], 1'b0 };
+       end
+end
+
+//----------------------------------------------------------------------------
+// WRITE-SHIFT-REGISTER
+//----------------------------------------------------------------------------
+
+reg [0:4] write_shr;
+wire      write_cmd = (cba_cmd == `DDR_CMD_WRITE) & cba_ack;
+
+always @(posedge clk)
+begin
+       if (reset)
+               write_shr <= 'b0;
+       else begin
+               if (write_cmd)
+                       write_shr <= { 5'b11111 };
+               else
+                       write_shr <= { write_shr[1:4], 1'b0 };
+       end
+end
+
+//----------------------------------------------------------------------------
+// DDR_DQS, DDR_DQS_OE
+//----------------------------------------------------------------------------
+genvar i;
+
+reg ddr_dqs_oe_reg;
+assign ddr_dqs_oe = ddr_dqs_oe_reg;
+
+always @(negedge clk)
+begin
+  ddr_dqs_oe_reg <= write_shr[0];
+end
+
+FDDRRSE ddr_clk_reg (
+       .Q(   ddr_clk      ),
+       .C0(  clk90        ),
+       .C1( ~clk90        ),
+       .CE(  vcc          ),
+       .D0(  vcc          ),
+       .D1(  gnd          ),
+       .R(   gnd          ),
+       .S(   gnd          )
+);
+
+FDDRRSE ddr_clk_n_reg (
+       .Q(   ddr_clk_n    ),
+       .C0(  clk90        ),
+       .C1( ~clk90        ),
+       .CE(  vcc          ),
+       .D0(  gnd          ),
+       .D1(  vcc          ),
+       .R(   gnd          ),
+       .S(   gnd          )
+);
+
+
+generate 
+for (i=0; i<`DQS_WIDTH; i=i+1) begin : DQS
+       FDDRRSE ddr_dqs_reg (
+               .Q(   ddr_dqs[i]   ),
+               .C0(  clk          ),
+               .C1( ~clk          ),
+               .CE(  vcc          ),
+               .D0(  write_shr[1] ),
+               .D1(  gnd          ),
+               .R(   gnd          ),
+               .S(   gnd          )
+       );
+end
+endgenerate
+
+
+//----------------------------------------------------------------------------
+// DQ data output
+//----------------------------------------------------------------------------
+wire [`DQ_RNG] buf_d0;        
+wire [`DM_RNG] buf_m0;
+reg  [`DQ_RNG] buf_d1;       // pipleine high word data
+reg  [`DM_RNG] buf_m1;       // pipleine high word mask
+
+assign buf_d0 = wdata_data[`WFIFO_D0_RNG];
+assign buf_m0 = wdata_data[`WFIFO_M0_RNG];
+
+always @(negedge clk90)
+begin
+       buf_d1 <= wdata_data[`WFIFO_D1_RNG];
+       buf_m1 <= wdata_data[`WFIFO_M1_RNG];
+end
+
+assign wdata_ack = write_shr[1];
+
+// generate DDR_DQ register
+generate 
+for (i=0; i<`DQ_WIDTH; i=i+1) begin : DQ_REG
+       FDDRRSE ddr_dq_reg (
+               .Q(   ddr_dq[i]    ),
+               .C0( ~clk90        ),
+               .C1(  clk90        ),
+               .CE(  vcc          ),
+               .D0(  buf_d0[i]    ),
+               .D1(  buf_d1[i]    ),
+               .R(   gnd          ),
+               .S(   gnd          )
+       );
+end
+endgenerate
+
+// generate DDR_DM register
+generate 
+for (i=0; i<`DM_WIDTH; i=i+1) begin : DM_REG
+       FDDRRSE ddr_dm_reg (
+               .Q(   ddr_dm[i]    ),
+               .C0( ~clk90        ),
+               .C1(  clk90        ),
+               .CE(  vcc          ),
+               .D0(  buf_m0[i]    ),
+               .D1(  buf_m1[i]    ),
+               .R(   gnd          ),
+               .S(   gnd          )
+       );
+end
+endgenerate
+
+//----------------------------------------------------------------------------
+// Connect ddr_cba to actual DDR pins
+//----------------------------------------------------------------------------
+assign ddr_a     = ddr_cba[(`A_WIDTH-1):0];
+assign ddr_ba    = ddr_cba[(`A_WIDTH+`BA_WIDTH-1):(`A_WIDTH)];
+assign ddr_ras_n = ddr_cba[(`CBA_WIDTH-1)];
+assign ddr_cas_n = ddr_cba[(`CBA_WIDTH-2)];
+assign ddr_we_n  = ddr_cba[(`CBA_WIDTH-3)];
+
+endmodule
diff --git a/src/edu/berkeley/fleet/fpga/mem/gray_counter.v b/src/edu/berkeley/fleet/fpga/mem/gray_counter.v
new file mode 100644 (file)
index 0000000..ff3b29b
--- /dev/null
@@ -0,0 +1,35 @@
+//==========================================
+// Function : Code Gray counter.
+// Coder    : Alex Claros F.
+// Date     : 15/May/2005.
+//=======================================
+
+`timescale 1ns/1ps
+
+module GrayCounter
+   #(parameter   COUNTER_WIDTH = 2)
+   
+    (output reg  [COUNTER_WIDTH-1:0]    GrayCount_out,  //'Gray' code count output.
+    
+     input wire                         Enable_in,  //Count enable.
+     input wire                         Clear_in,   //Count reset.
+    
+     input wire                         Clk);
+
+    /////////Internal connections & variables///////
+    reg    [COUNTER_WIDTH-1:0]         BinaryCount;
+
+    /////////Code///////////////////////
+    
+    always @ (posedge Clk)
+        if (Clear_in) begin
+            BinaryCount   <= {COUNTER_WIDTH{1'b 0}} + 1;  //Gray count begins @ '1' with
+            GrayCount_out <= {COUNTER_WIDTH{1'b 0}};      // first 'Enable_in'.
+        end
+        else if (Enable_in) begin
+            BinaryCount   <= BinaryCount + 1;
+            GrayCount_out <= {BinaryCount[COUNTER_WIDTH-1],
+                              BinaryCount[COUNTER_WIDTH-2:0] ^ BinaryCount[COUNTER_WIDTH-1:1]};
+        end
+    
+endmodule
diff --git a/src/edu/berkeley/fleet/fpga/mem/rotary.v b/src/edu/berkeley/fleet/fpga/mem/rotary.v
new file mode 100644 (file)
index 0000000..83c2349
--- /dev/null
@@ -0,0 +1,70 @@
+//----------------------------------------------------------------------------
+// Decode rotary encoder to clk-syncronous signals
+//
+// (c) Joerg Bornschein (<jb@capsec.org>)
+//----------------------------------------------------------------------------
+
+module rotary (
+       input        clk,
+       input        reset,
+       input [2:0]  rot,
+       //
+       output reg   rot_btn,
+       output reg   rot_event,
+       output reg   rot_left
+);
+
+//----------------------------------------------------------------------------
+// decode rotary encoder
+//----------------------------------------------------------------------------
+reg [1:0] rot_q;
+
+always @(posedge clk)
+begin
+       case (rot[1:0])
+               2'b00: rot_q <= { rot_q[1], 1'b0 };
+               2'b01: rot_q <= { 1'b0, rot_q[0] };
+               2'b10: rot_q <= { 1'b1, rot_q[0] };
+               2'b11: rot_q <= { rot_q[1], 1'b1 };
+       endcase
+end
+
+reg [1:0] rot_q_delayed;
+
+always @(posedge clk)
+begin
+       rot_q_delayed <= rot_q;
+
+       if (rot_q[0] && ~rot_q_delayed[0]) begin
+               rot_event <= 1;
+               rot_left  <= rot_q[1];
+       end else
+               rot_event <= 0;
+end
+
+//----------------------------------------------------------------------------
+// debounce push button (rot[2])
+//----------------------------------------------------------------------------
+reg [2:0]  rot_d;
+reg [15:0] dead_count;
+
+always @(posedge clk)
+begin
+       if (reset) begin
+               rot_btn    <= 0;
+               dead_count <= 0;
+       end else begin
+               rot_btn <= 1'b0;
+               rot_d   <= { rot_d[1:0], rot[2] };
+
+               if (dead_count == 0) begin
+                       if ( rot_d[2:1] == 2'b01 ) begin
+                               rot_btn    <= 1'b1;
+                               dead_count <= dead_count - 1;
+                       end
+               end else
+                       dead_count <= dead_count - 1;
+       end
+end
+
+endmodule
diff --git a/src/edu/berkeley/fleet/fpga/mem/wb_vga.v b/src/edu/berkeley/fleet/fpga/mem/wb_vga.v
new file mode 100644 (file)
index 0000000..a70b21b
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * WISHBONE VGA framebuffer
+ * Copyright (C) 2008 Sebastien Bourdeauducq - http://lekernel.net
+ * This file is part of Milkymist.
+ *
+ * Milkymist is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+module wb_vga(
+       /* Clock and Reset signals are shared between the two buses */
+       input wb_clk_i,
+       input wb_rst_i,
+       
+       /* Wishbone master for reading the framebuffer */
+       output [31:0] fbwb_adr_o,
+       output reg fbwb_stb_o,
+       input fbwb_ack_i,
+       input [31:0] fbwb_dat_i,
+
+       /* Wishbone slave for configuration registers */
+       input [31:0] wb_adr_i,
+       input wb_cyc_i,
+       input wb_stb_i,
+       input wb_we_i,
+       output wb_ack_o,
+       output reg [31:0] wb_dat_o,
+       input [31:0] wb_dat_i,
+
+       /* VGA signals */
+       input vga_clk,
+       output vga_psave,
+       output reg vga_hsync,
+       output reg vga_vsync,
+       output vga_sync,
+       output vga_blank,
+       output reg [7:0] vga_r,
+       output reg [7:0] vga_g,
+       output reg [7:0] vga_b,
+       output vga_clkout
+);
+
+/* Internal state */
+
+/* We need to access at least 640*480 = 307200 words.
+ * 2^19 = 524288
+ */
+reg [21:0] fbaddr;
+reg [21:0] fbaddr_next;
+
+reg hactive;
+reg hactive_next;
+reg [9:0] hcounter;
+reg [9:0] hcounter_next;
+
+reg vactive;
+reg vactive_next;
+reg [9:0] vcounter;
+reg [9:0] vcounter_next;
+
+/* Configuration registers */
+
+reg enable;                    // 00 (0)
+reg enablesync;                        // 04 (1)
+
+reg [29:0] fboffset;           // 08 (2)
+reg [29:0] fboffsetsync;       // 0C (3)
+
+reg [9:0] hres;                        // 10 (4)
+reg [8:0] hblank;              // 14 (5)
+reg [8:0] hsyncmin;            // 18 (6)
+reg [8:0] hsyncmax;            // 1C (7)
+
+reg [9:0] vres;                        // 20 (8)
+reg [8:0] vblank;              // 24 (9)
+reg [8:0] vsyncmin;            // 28 (a)
+reg [8:0] vsyncmax;            // 2C (b)
+
+assign wb_ack_o = wb_cyc_i & wb_stb_i;
+
+always @(posedge wb_clk_i or posedge wb_rst_i) begin
+       if(wb_rst_i) begin
+               enable <= 1;
+               enablesync <= 1;
+               
+               fboffset <= 0;
+               fboffsetsync <= 0;
+               
+               hres <= 639;
+               hblank <= 159;
+               hsyncmin <= 48;
+               hsyncmax <= 143;
+               
+               vres <= 479;
+               vblank <= 43;
+               vsyncmin <= 31;
+               vsyncmax <= 32;
+
+       end else begin
+               if(wb_cyc_i & wb_stb_i & wb_we_i) begin
+                       case(wb_adr_i[5:2])
+                               // enable is READ ONLY
+                               4'h1: enablesync <= wb_dat_i[0];
+                               
+                               // fboffset is READ ONLY
+                               4'h3: fboffsetsync <= wb_dat_i[31:2];
+                               
+                               4'h4: hres <= wb_dat_i[9:0];
+                               4'h5: hblank <= wb_dat_i[8:0];
+                               4'h6: hsyncmin <= wb_dat_i[8:0];
+                               4'h7: hsyncmax <= wb_dat_i[8:0];
+                               
+                               4'h8: vres <= wb_dat_i[9:0];
+                               4'h9: vblank <= wb_dat_i[8:0];
+                               4'ha: vsyncmin <= wb_dat_i[8:0];
+                               4'hb: vsyncmax <= wb_dat_i[8:0];
+                       endcase
+               end
+               /* Update synchronized registers */
+               if((~hactive && ~vactive) || ~enable) begin
+                       fboffset <= fboffsetsync;
+                       enable <= enablesync;
+               end
+       end
+end
+
+always @(wb_adr_i
+       or enable or enablesync
+       or fboffset or fboffsetsync 
+       or hres or hblank or hsyncmin or hsyncmax
+       or vres or vblank or vsyncmin or vsyncmax) begin
+       case(wb_adr_i[5:2])
+               4'h0: wb_dat_o <= {31'b0, enable};
+               4'h1: wb_dat_o <= {31'b0, enablesync};
+
+               4'h2: wb_dat_o <= {fboffset, 2'b00};
+               4'h3: wb_dat_o <= {fboffsetsync, 2'b00};
+               
+               4'h4: wb_dat_o <= {22'b0, hres};
+               4'h5: wb_dat_o <= {23'b0, hblank};
+               4'h6: wb_dat_o <= {23'b0, hsyncmin};
+               4'h7: wb_dat_o <= {23'b0, hsyncmax};
+               
+               4'h8: wb_dat_o <= {22'b0, vres};
+               4'h9: wb_dat_o <= {23'b0, vblank};
+               4'ha: wb_dat_o <= {23'b0, vsyncmin};
+               4'hb: wb_dat_o <= {23'b0, vsyncmax};
+               default: wb_dat_o <= 32'hx;
+       endcase
+end
+
+/* FIFO */
+
+wire [25:0] pixelfifo_dout;
+wire pixelfifo_empty;
+wire pixelfifo_next;
+
+reg [25:0] pixelfifo_din;
+wire pixelfifo_full;
+reg pixelfifo_wr;
+
+async_fifo #(
+       .DATA_WIDTH(26),
+       .ADDRESS_WIDTH(4)
+) pixelfifo (
+       .Data_out(pixelfifo_dout),
+       .Empty_out(pixelfifo_empty),
+       .ReadEn_in(pixelfifo_next),
+       .RClk(vga_clk),
+
+       .Data_in(pixelfifo_din),
+       .Full_out(pixelfifo_full),
+       .WriteEn_in(pixelfifo_wr),
+       .WClk(wb_clk_i),
+       
+       .Clear_in(wb_rst_i)
+);
+
+/* Wishbone master interface and Sequencer */
+
+assign fbwb_adr_o = {{8'b0, fbaddr_next} + fboffset, 2'b00};
+
+always @(posedge wb_clk_i or posedge wb_rst_i) begin
+       if(wb_rst_i) begin
+               hactive <= 0;
+               hcounter <= 0;
+               vactive <= 0;
+               vcounter <= 0;
+               fbaddr <= 0;
+       end else begin
+               if(~enable) begin
+                       hactive <= 0;
+                       hcounter <= 0;
+                       vactive <= 0;
+                       vcounter <= 0;
+                       fbaddr <= 0;
+               end else begin
+                       hactive <= hactive_next;
+                       hcounter <= hcounter_next;
+                       vactive <= vactive_next;
+                       vcounter <= vcounter_next;
+                       fbaddr <= fbaddr_next;
+               end
+       end
+end
+
+always @(hactive or hcounter or vactive or vcounter or hblank or hres or vblank or vres or pixelfifo_full or fbwb_stb_o or fbwb_ack_i) begin
+       if(~pixelfifo_full && (~fbwb_stb_o || fbwb_ack_i)) begin
+               if(hcounter == 0) begin
+                       if(hactive) begin
+                               hactive_next <= 0;
+                               hcounter_next <= hblank; /* horizontal back + front porches */
+                               vactive_next <= vactive;
+                               vcounter_next <= vcounter;
+                       end else begin
+                               hactive_next <= 1;
+                               hcounter_next <= hres; /* horizontal active video */
+                               if(vcounter == 0) begin
+                                       if(vactive) begin
+                                               vactive_next <= 0;
+                                               vcounter_next <= vblank; /* vertical back + front porches */
+                                       end else begin
+                                               vactive_next <= 1;
+                                               vcounter_next <= vres; /* vertical active video */
+                                       end
+                               end else begin
+                                       vactive_next <= vactive;
+                                       vcounter_next <= vcounter - 1;
+                               end
+                       end
+               end else begin
+                       hactive_next <= hactive;
+                       hcounter_next <= hcounter - 1;
+                       vactive_next <= vactive;
+                       vcounter_next <= vcounter;
+               end
+               pixelfifo_wr = 1;
+       end else begin
+               hactive_next <= hactive;
+               hcounter_next <= hcounter;
+               vactive_next <= vactive;
+               vcounter_next <= vcounter;
+               pixelfifo_wr = 0;
+       end
+end
+
+always @(hactive or hcounter or vactive or vcounter or hsyncmin or hsyncmax or vsyncmin or vsyncmax) begin
+       /* HSYNC generator (negative logic) */
+       if(~hactive && (hcounter[8:0] >= hsyncmin) && (hcounter[8:0] <= hsyncmax)) begin
+               pixelfifo_din[24] <= 0;
+       end else begin
+               pixelfifo_din[24] <= 1;
+       end
+
+       /* VSYNC generator (negative logic) */
+       if(~vactive && (vcounter[8:0] >= vsyncmin) && (vcounter[8:0] <= vsyncmax)) begin
+               pixelfifo_din[25] <= 0;
+       end else begin
+               pixelfifo_din[25] <= 1;
+       end
+end
+
+always @(hactive or vactive or pixelfifo_full or fbwb_dat_i or fbwb_ack_i or fbaddr) begin
+       /* Image generator */
+       if(hactive && vactive) begin
+               pixelfifo_din[23:0] <= fbwb_dat_i[23:0];
+               if(~pixelfifo_full) begin
+                       fbwb_stb_o <= 1;
+                       if(fbwb_ack_i)
+                               fbaddr_next <= fbaddr + 1;
+                       else
+                               fbaddr_next <= fbaddr;
+               end else begin
+                       fbwb_stb_o <= 0;
+                       fbaddr_next <= fbaddr;
+               end
+       end else begin
+               /* Blank (porches and sync) */
+               pixelfifo_din[23:0] <= 24'h000000;
+               if(~vactive)
+                       fbaddr_next <= 0;
+               else
+                       fbaddr_next <= fbaddr;
+               fbwb_stb_o <= 0;
+       end
+end
+
+/* VGA signal generation */
+
+assign vga_sync = 0;
+assign vga_psave = 1;
+assign vga_blank = 1;
+
+assign vga_clkout = vga_clk;
+
+assign pixelfifo_next = 1;
+
+/* We register everything to avoid glitches on the outputs,
+ * especially on sync signals */
+
+always @(posedge vga_clk) begin
+       vga_vsync <= pixelfifo_dout[25];
+       vga_hsync <= pixelfifo_dout[24];
+       vga_r <= pixelfifo_dout[23:16];
+       vga_g <= pixelfifo_dout[15:8];
+       vga_b <= pixelfifo_dout[7:0];
+end
+
+endmodule
+
diff --git a/src/edu/berkeley/fleet/fpga/ramfifo.inc b/src/edu/berkeley/fleet/fpga/ramfifo.inc
new file mode 100644 (file)
index 0000000..f8977f5
--- /dev/null
@@ -0,0 +1,92 @@
+module `MODULE_NAME(clk, rst, 
+               in_r, in_a_, in_d,
+               out_r_, out_a, out_d_); 
+    input  clk; 
+    input  rst; 
+    input  in_r;
+    output in_a_;
+    output out_r_;
+    input  out_a;
+    input  [(`WIDTH-1):0] in_d;
+    output [(`WIDTH-1):0] out_d_;
+
+    reg in_a;
+    reg out_r;
+    assign in_a_ = in_a;
+    assign out_r_ = out_r;
+
+    wire[((1<<(`ADDR_BITS))-1):0] controlx;
+    reg[((1<<(`ADDR_BITS))-1):0] control;
+    initial control = 0;
+
+    genvar i;
+    generate
+      if (`ADDR_BITS > 1) begin: OUT
+      for(i=1; i<=((1<<`ADDR_BITS)-2) ; i=i+1) begin : OUT
+        assign controlx[i] =
+           ( control[i-1] && !control[i]                 ) ? 1 :
+           (                  control[i] && !control[i+1]) ? 0 :
+           control[i];
+      end
+      end
+    endgenerate
+
+    reg[3:0] addr;
+    initial  addr = 4'b1111;
+
+    genvar j;
+    generate
+      for(j=0; j<`WIDTH ; j=j+1) begin : OUTX
+         SRL16E SRL16E (.Q (out_d_[j]),
+                        .A0 (addr[0]),
+                        .A1 (addr[1]),
+                        .A2 (addr[2]),
+                        .A3 (addr[3]),
+                        .CE (in_r && !in_a && !control[0]),
+                        .CLK (clk),
+                        .D (in_d[j]));
+         defparam SRL16E.INIT = 0;
+      end
+    endgenerate
+
+    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 begin
+          inchead = 0;
+          inctail = 0;
+          if (!in_r && in_a) in_a <= 0;
+          if (control[0]) begin
+             if (!control[1]) control[0] <= 0;
+          end else if (in_r && !in_a) begin
+            control[0] <= 1;
+            inctail = 1;
+            in_a <= 1;
+          end
+  
+          control[(1<<`ADDR_BITS)-1:1] <= controlx[(1<<`ADDR_BITS)-1:1];
+  
+          if (control[(1<<`ADDR_BITS)-1] && !out_r && !out_a) begin
+            out_r <= 1;
+          end
+          if (out_r && out_a) begin
+            out_r <= 0;
+            inchead = 1;
+          end
+          if (          inchead && !inctail) begin
+            addr <= addr-1;
+          end else if (!inchead &&  inctail) begin
+            addr <= addr+1;
+          end
+      end
+    end
+endmodule 
diff --git a/src/edu/berkeley/fleet/fpga/ramfifo8.v b/src/edu/berkeley/fleet/fpga/ramfifo8.v
new file mode 100644 (file)
index 0000000..4ef7919
--- /dev/null
@@ -0,0 +1,5 @@
+`define ADDR_BITS 3
+`define WIDTH 37
+`define MODULE_NAME ramfifo8
+`include "ramfifo.inc"
+
index 8da080f..67f538f 100644 (file)
@@ -23,6 +23,31 @@ public class Verilog {
         public String toString() { return s; }
     }
 
+    public static class CatValue implements Value {
+        private final Value[] values;
+        public CatValue(Value[] values) { this.values = values; }
+        public Value getBits(int high, int low) {
+            throw new RuntimeException();
+        }
+        public Assignable getAssignableBits(int high, int low) {
+            throw new RuntimeException();
+        }
+        public String toString() { return getVerilogName(); }
+        public String getVerilogName() {
+            StringBuffer sb = new StringBuffer();
+            sb.append("{ ");
+            boolean first = true;
+            for(int i=0; i<values.length; i++) {
+                if (values[i]==null) continue;
+                if (!first) sb.append(", ");
+                sb.append(values[i].getVerilogName());
+                first = false;
+            }
+            sb.append(" }");
+            return sb.toString();
+        }
+    }
+
     public static interface Action {
         public String getVerilogAction();
     }
@@ -110,6 +135,8 @@ public class Verilog {
             pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v")));
             dump(pw, true);
             pw.flush();
+            for(InstantiatedModule m : instantiatedModules)
+                m.module.dump(prefix);
         }
         public int id = 0;
         public final String name;
@@ -127,7 +154,7 @@ public class Verilog {
         
         public StringBuffer crap = new StringBuffer();
         public StringBuffer precrap = new StringBuffer();
-        public void addCrap(String s) { crap.append(s); crap.append('\n'); }
+        //public void addCrap(String s) { crap.append(s); crap.append('\n'); }
         public void addPreCrap(String s) { precrap.append(s); precrap.append('\n'); }
         public void addPreCrap0(String s) { precrap.append(s); }
 
@@ -202,6 +229,9 @@ public class Verilog {
                 pw.println("  reg ["+(width-1)+":0] "+name+";");
                 pw.println("  initial "+name+"="+initial+";");
             }
+            public void connect(SinkPort driven) {
+                driven.latchDriver = this;
+            }
         }
 
         public abstract class Port implements Action, Assignable, Trigger {
@@ -246,6 +276,31 @@ public class Verilog {
                 pw.println("  " + module.getName() + " " + getName() + "(clk, rst ");
                 for(String s : module.portorder)
                     pw.println(", " + getPort(s).getSimpleInterface());
+                if (module.name.equals("dram")) {
+                    pw.println("    , dram_addr");
+                    pw.println("    , dram_addr_r");
+                    pw.println("    , dram_addr_a");
+                    pw.println("    , dram_isread");
+                    pw.println("    , dram_write_data");
+                    pw.println("    , dram_write_data_push");
+                    pw.println("    , dram_write_data_full");
+                    pw.println("    , dram_read_data");
+                    pw.println("    , dram_read_data_pop");
+                    pw.println("    , dram_read_data_empty");
+                    pw.println("    , dram_read_data_latency");
+                }
+                if (module.name.equals("video")) {
+                    pw.println("    , vga_clk");
+                    pw.println("    , vga_psave");
+                    pw.println("    , vga_hsync");
+                    pw.println("    , vga_vsync");
+                    pw.println("    , vga_sync");
+                    pw.println("    , vga_blank");
+                    pw.println("    , vga_r");
+                    pw.println("    , vga_g");
+                    pw.println("    , vga_b");
+                    pw.println("    , vga_clkout");
+                }
                 pw.println("   );");
             }
             public Port getPort(String name) {
@@ -272,7 +327,6 @@ public class Verilog {
         }
 
         public class SourcePort extends Port implements Value {
-            public SinkPort driven = null;
             public SourcePort(String name, int width, boolean external) { 
                 super(name, width, external); }
             public Value getBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
@@ -281,6 +335,9 @@ public class Verilog {
             public String getVerilogAction() { return getAck() + " <= 1;"; }
             public String getInterface() { return getReq()+", "+getAck()+"_, "+name+""; }
             public String getSimpleInterface() { return getReq()+", "+getAck()+", "+name+""; }
+            public String testBit(int index, boolean value) {
+                return "("+name+"["+index+"]=="+(value?1:0)+")";
+            }
             public String getDeclaration() {
                 StringBuffer sb = new StringBuffer();
                 if (external) {
@@ -304,20 +361,17 @@ public class Verilog {
                 StringBuffer sb = new StringBuffer();
                 if (external)
                     sb.append("assign " +                 name +"_a_ = " + name + "_a;\n");
-                if (driven != null) {
-                    sb.append("assign " + driven.name +"_r = " + name + "_r;\n");
-                    sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
-                    sb.append("assign " + driven.name +"   = " + name + ";\n");
-                }
                 return sb.toString();
             }
             public void connect(SinkPort driven) {
-                this.driven = driven;
+                driven.driver = this;
             }
         }
         public class SinkPort extends Port {
+            public SourcePort driver = null;
             public boolean forceNoLatch = false;
             public SinkPort driven = null;
+            public Latch latchDriver = null;
             public final String resetBehavior;
             public Assignable getAssignableBits(int high, int low) { return new SimpleValue(getVerilogName(), high, low); }
             public String getVerilogAction() { return getReq() + " <= 1;"; }
@@ -337,7 +391,7 @@ public class Verilog {
                     sb.append("wire "   +                 name +"_a;\n");
                 }
 
-                if (forceNoLatch) {
+                if (forceNoLatch ||  latchDriver!=null) {
                     sb.append("reg "    +                  name +"_r;\n");
                     sb.append("initial " +                 name +"_r = 0;\n");
                     sb.append("wire   ["+(width-1)+":0]" + name +";\n");
@@ -348,15 +402,16 @@ public class Verilog {
                     sb.append("reg "    +                  name +"_r;\n");
                     sb.append("initial " +                 name +"_r = 0;\n");
                     sb.append("reg    ["+(width-1)+":0]" + name +";\n");
-                    sb.append("initial " +                 name +" = 0;\n");
+                    if (!"/*NORESET*/".equals(resetBehavior))
+                        sb.append("initial " +                 name +" = 0;\n");
                 }
                 return sb.toString();
             }
             public String doReset() {
-                return forceNoLatch
+                return (forceNoLatch||latchDriver!=null)
                     ? name+"_r<=0;"
                     : hasLatch
-                    ? (name+"_r<=0; "+name+"<=0;")
+                    ? (name+"_r<=0; "+("/*NORESET*/".equals(resetBehavior) ? "" : (name+"<=0;")))
                     : "";
             }
             public String getAssignments() {
@@ -370,24 +425,79 @@ public class Verilog {
                     sb.append("assign " + name +"_a = " + driven.name + "_a;\n");
                     sb.append("assign " + driven.name +"   = " + name + ";\n");
                 }
+                if (driver != null) {
+                    sb.append("assign " + name +"_r = " + driver.name + "_r;\n");
+                    sb.append("assign " + driver.name +"_a = " + name + "_a;\n");
+                    sb.append("assign " + name +"   = " + driver.name + ";\n");
+                }
+                if (latchDriver != null) {
+                    sb.append("assign " + name +"   = " + latchDriver.name + ";\n");
+                }
                 return sb.toString();
             }
             public void connect(SinkPort driven) {
                 this.driven = driven;
+                throw new RuntimeException();
             }
         }
 
         public void dump(PrintWriter pw, boolean fix) {
-            pw.println("`include \"macros.v\"");
+            pw.println("`include \"bitfields.v\"");
             pw.println("module "+name+"(clk, rst ");
             for(String name : portorder) {
                 Port p = ports.get(name);
                 pw.println("    , " + p.getInterface());
             }
+            if (this.name.equals("root")) {
+                pw.println("    , dram_addr");
+                pw.println("    , dram_addr_r");
+                pw.println("    , dram_addr_a");
+                pw.println("    , dram_isread");
+                pw.println("    , dram_write_data");
+                pw.println("    , dram_write_data_push");
+                pw.println("    , dram_write_data_full");
+                pw.println("    , dram_read_data");
+                pw.println("    , dram_read_data_pop");
+                pw.println("    , dram_read_data_empty");
+                pw.println("    , dram_read_data_latency");
+                pw.println("    , vga_clk");
+                pw.println("    , vga_psave");
+                pw.println("    , vga_hsync");
+                pw.println("    , vga_vsync");
+                pw.println("    , vga_sync");
+                pw.println("    , vga_blank");
+                pw.println("    , vga_r");
+                pw.println("    , vga_g");
+                pw.println("    , vga_b");
+                pw.println("    , vga_clkout");
+            }
             pw.println("   );");
             pw.println();
             pw.println("    input clk;");
             pw.println("    input rst;");
+            if (this.name.equals("root")) {
+                pw.println("output  [31:0] dram_addr;");
+                pw.println("output         dram_addr_r;");
+                pw.println("input          dram_addr_a;");
+                pw.println("output         dram_isread;");
+                pw.println("output  [31:0] dram_write_data;");
+                pw.println("output         dram_write_data_push;");
+                pw.println("input          dram_write_data_full;");
+                pw.println("input   [31:0] dram_read_data;");
+                pw.println("output         dram_read_data_pop;");
+                pw.println("input          dram_read_data_empty;");
+                pw.println("input   [1:0]  dram_read_data_latency;");
+                pw.println("input          vga_clk;");
+                pw.println("output         vga_psave;");
+                pw.println("output         vga_hsync;");
+                pw.println("output         vga_vsync;");
+                pw.println("output         vga_sync;");
+                pw.println("output         vga_blank;");
+                pw.println("output   [7:0] vga_r;");
+                pw.println("output   [7:0] vga_g;");
+                pw.println("output   [7:0] vga_b;");
+                pw.println("output         vga_clkout;");
+            }
             for(String name : ports.keySet()) {
                 Port p = ports.get(name);
                 pw.println("    " + p.getDeclaration());
@@ -454,7 +564,7 @@ public class Verilog {
                     else                      pw.print(" && " + o);
                 }
                 pw.println(") begin ");
-                for(Object a : actions) pw.println(((Action)a).getVerilogAction());
+                for(Object a : actions) if (a!=null) pw.println(((Action)a).getVerilogAction());
                 if (fix) pw.println("end /*else*/ ");
                 else     pw.println("end else ");
             }
diff --git a/src/edu/berkeley/fleet/fpga/vram.v b/src/edu/berkeley/fleet/fpga/vram.v
new file mode 100644 (file)
index 0000000..1aca82f
--- /dev/null
@@ -0,0 +1,6 @@
+`define BRAM_ADDR_WIDTH 19
+`define BRAM_DATA_WIDTH 3
+`define BRAM_SIZE (640*480)
+`define BRAM_NAME vram
+
+`include "bram.inc"