From 965ad38d7bbcdea879f4ea82cb89b88785331714 Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 21 Aug 2008 11:32:31 +0100 Subject: [PATCH] massive overhaul of fpga code --- src/edu/berkeley/fleet/fpga/Client.java | 1 + src/edu/berkeley/fleet/fpga/FabricElement.java | 2 +- src/edu/berkeley/fleet/fpga/FifoModule.java | 43 +- src/edu/berkeley/fleet/fpga/Fpga.java | 229 ++++++---- src/edu/berkeley/fleet/fpga/FpgaDestination.java | 2 +- src/edu/berkeley/fleet/fpga/FpgaDock.java | 194 +++++---- src/edu/berkeley/fleet/fpga/FpgaPath.java | 4 - src/edu/berkeley/fleet/fpga/FpgaShip.java | 2 +- src/edu/berkeley/fleet/fpga/FunnelModule.java | 16 +- src/edu/berkeley/fleet/fpga/HornModule.java | 34 +- src/edu/berkeley/fleet/fpga/bram.inc | 23 + src/edu/berkeley/fleet/fpga/bram14.v | 6 + src/edu/berkeley/fleet/fpga/fifo.inc | 167 ++++++++ src/edu/berkeley/fleet/fpga/macros.v | 9 - src/edu/berkeley/fleet/fpga/main.ucf | 491 ++++++++++++++++++++-- src/edu/berkeley/fleet/fpga/main.v | 187 +++++++- src/edu/berkeley/fleet/fpga/main.xst | 2 +- src/edu/berkeley/fleet/fpga/mem/async_fifo.v | 116 +++++ src/edu/berkeley/fleet/fpga/mem/ddr_clkgen.v | 181 ++++++++ src/edu/berkeley/fleet/fpga/mem/ddr_ctrl.v | 477 +++++++++++++++++++++ src/edu/berkeley/fleet/fpga/mem/ddr_include.v | 89 ++++ src/edu/berkeley/fleet/fpga/mem/ddr_init.v | 191 +++++++++ src/edu/berkeley/fleet/fpga/mem/ddr_pulse78.v | 43 ++ src/edu/berkeley/fleet/fpga/mem/ddr_rpath.v | 112 +++++ src/edu/berkeley/fleet/fpga/mem/ddr_wpath.v | 286 +++++++++++++ src/edu/berkeley/fleet/fpga/mem/gray_counter.v | 35 ++ src/edu/berkeley/fleet/fpga/mem/rotary.v | 70 +++ src/edu/berkeley/fleet/fpga/mem/wb_vga.v | 322 ++++++++++++++ src/edu/berkeley/fleet/fpga/ramfifo.inc | 92 ++++ src/edu/berkeley/fleet/fpga/ramfifo8.v | 5 + src/edu/berkeley/fleet/fpga/verilog/Verilog.java | 138 +++++- src/edu/berkeley/fleet/fpga/vram.v | 6 + 32 files changed, 3324 insertions(+), 251 deletions(-) create mode 100644 src/edu/berkeley/fleet/fpga/bram.inc create mode 100644 src/edu/berkeley/fleet/fpga/bram14.v create mode 100644 src/edu/berkeley/fleet/fpga/empty.vhd create mode 100644 src/edu/berkeley/fleet/fpga/fifo.inc delete mode 100644 src/edu/berkeley/fleet/fpga/macros.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/async_fifo.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/ddr_clkgen.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/ddr_ctrl.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/ddr_include.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/ddr_init.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/ddr_pulse78.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/ddr_rpath.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/ddr_wpath.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/gray_counter.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/rotary.v create mode 100644 src/edu/berkeley/fleet/fpga/mem/wb_vga.v create mode 100644 src/edu/berkeley/fleet/fpga/ramfifo.inc create mode 100644 src/edu/berkeley/fleet/fpga/ramfifo8.v create mode 100644 src/edu/berkeley/fleet/fpga/vram.v diff --git a/src/edu/berkeley/fleet/fpga/Client.java b/src/edu/berkeley/fleet/fpga/Client.java index 709ce15..c563917 100644 --- a/src/edu/berkeley/fleet/fpga/Client.java +++ b/src/edu/berkeley/fleet/fpga/Client.java @@ -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"); diff --git a/src/edu/berkeley/fleet/fpga/FabricElement.java b/src/edu/berkeley/fleet/fpga/FabricElement.java index 59de514..d5a4c9b 100644 --- a/src/edu/berkeley/fleet/fpga/FabricElement.java +++ b/src/edu/berkeley/fleet/fpga/FabricElement.java @@ -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(); } diff --git a/src/edu/berkeley/fleet/fpga/FifoModule.java b/src/edu/berkeley/fleet/fpga/FifoModule.java index 3cb6bc5..26e75c7 100644 --- a/src/edu/berkeley/fleet/fpga/FifoModule.java +++ b/src/edu/berkeley/fleet/fpga/FifoModule.java @@ -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= 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(); + } } diff --git a/src/edu/berkeley/fleet/fpga/Fpga.java b/src/edu/berkeley/fleet/fpga/Fpga.java index 7b113ac..86d13e8 100644 --- a/src/edu/berkeley/fleet/fpga/Fpga.java +++ b/src/edu/berkeley/fleet/fpga/Fpga.java @@ -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 ships = new LinkedHashMap(); + public Iterator iterator() { return (Iterator)(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 ships = new LinkedHashMap(); - public Iterator iterator() { return (Iterator)(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)(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(); + ArrayList inbox_dests = new ArrayList(); + ArrayList outbox_sources = new ArrayList(); + ArrayList outbox_dests = new ArrayList(); + ArrayList instruction_dests = new ArrayList(); + int numdocks = 0; + for(FpgaShip ship : (Iterable)(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(); + ArrayList sources = new ArrayList(); + 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(); - ArrayList dests = new ArrayList(); - for(FpgaShip ship : (Iterable)(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; + } } diff --git a/src/edu/berkeley/fleet/fpga/FpgaDestination.java b/src/edu/berkeley/fleet/fpga/FpgaDestination.java index 9a61077..436e11f 100644 --- a/src/edu/berkeley/fleet/fpga/FpgaDestination.java +++ b/src/edu/berkeley/fleet/fpga/FpgaDestination.java @@ -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(); } diff --git a/src/edu/berkeley/fleet/fpga/FpgaDock.java b/src/edu/berkeley/fleet/fpga/FpgaDock.java index 820d2b7..8a53829 100644 --- a/src/edu/berkeley/fleet/fpga/FpgaDock.java +++ b/src/edu/berkeley/fleet/fpga/FpgaDock.java @@ -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) |" + diff --git a/src/edu/berkeley/fleet/fpga/FpgaPath.java b/src/edu/berkeley/fleet/fpga/FpgaPath.java index ff00574..e022be3 100644 --- a/src/edu/berkeley/fleet/fpga/FpgaPath.java +++ b/src/edu/berkeley/fleet/fpga/FpgaPath.java @@ -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.*; diff --git a/src/edu/berkeley/fleet/fpga/FpgaShip.java b/src/edu/berkeley/fleet/fpga/FpgaShip.java index ac193cd..45acd36 100644 --- a/src/edu/berkeley/fleet/fpga/FpgaShip.java +++ b/src/edu/berkeley/fleet/fpga/FpgaShip.java @@ -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")) diff --git a/src/edu/berkeley/fleet/fpga/FunnelModule.java b/src/edu/berkeley/fleet/fpga/FunnelModule.java index bda75e8..49679a5 100644 --- a/src/edu/berkeley/fleet/fpga/FunnelModule.java +++ b/src/edu/berkeley/fleet/fpga/FunnelModule.java @@ -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()); diff --git a/src/edu/berkeley/fleet/fpga/HornModule.java b/src/edu/berkeley/fleet/fpga/HornModule.java index ee7d4a6..0b3c73a 100644 --- a/src/edu/berkeley/fleet/fpga/HornModule.java +++ b/src/edu/berkeley/fleet/fpga/HornModule.java @@ -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 index 0000000..f0c8334 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/bram.inc @@ -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 index 0000000..8a23c0b --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/bram14.v @@ -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 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 index 0000000..308fa79 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/fifo.inc @@ -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 index 1e4ef57..0000000 --- a/src/edu/berkeley/fleet/fpga/macros.v +++ /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; - diff --git a/src/edu/berkeley/fleet/fpga/main.ucf b/src/edu/berkeley/fleet/fpga/main.ucf index 60dfc53..3035ecc 100644 --- a/src/edu/berkeley/fleet/fpga/main.ucf +++ b/src/edu/berkeley/fleet/fpga/main.ucf @@ -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; diff --git a/src/edu/berkeley/fleet/fpga/main.v b/src/edu/berkeley/fleet/fpga/main.v index 548a633..1a10194 100644 --- a/src/edu/berkeley/fleet/fpga/main.v +++ b/src/edu/berkeley/fleet/fpga/main.v @@ -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 + diff --git a/src/edu/berkeley/fleet/fpga/main.xst b/src/edu/berkeley/fleet/fpga/main.xst index 9fa27f3..9f891ae 100644 --- a/src/edu/berkeley/fleet/fpga/main.xst +++ b/src/edu/berkeley/fleet/fpga/main.xst @@ -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 index 0000000..885dfbe --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/async_fifo.v @@ -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 index 0000000..3827a74 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/ddr_clkgen.v @@ -0,0 +1,181 @@ +//--------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//--------------------------------------------------------------------------- + +`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 index 0000000..45218bd --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/ddr_ctrl.v @@ -0,0 +1,477 @@ +//---------------------------------------------------------------------------- +// Pipelined, asyncronous DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- +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 index 0000000..f77be87 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/ddr_include.v @@ -0,0 +1,89 @@ +//--------------------------------------------------------------------------- +// DDR Controller +// +// (c) Joerg Bornschein () +//--------------------------------------------------------------------------- + +`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 index 0000000..343d0af --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/ddr_init.v @@ -0,0 +1,191 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- +`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 index 0000000..396576e --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/ddr_pulse78.v @@ -0,0 +1,43 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- +`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 index 0000000..3286003 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/ddr_rpath.v @@ -0,0 +1,112 @@ +//---------------------------------------------------------------------------- +// Wishbone DDR Controller +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- + +`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 index 0000000..f1f1ee3 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/ddr_wpath.v @@ -0,0 +1,286 @@ +//---------------------------------------------------------------------------- +// +// Wishbone DDR Controller -- fast write data-path +// +// (c) Joerg Bornschein () +// +//---------------------------------------------------------------------------- + +`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 index 0000000..ff3b29b --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/gray_counter.v @@ -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 index 0000000..83c2349 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/rotary.v @@ -0,0 +1,70 @@ +//---------------------------------------------------------------------------- +// Decode rotary encoder to clk-syncronous signals +// +// (c) Joerg Bornschein () +//---------------------------------------------------------------------------- + +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 index 0000000..a70b21b --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/mem/wb_vga.v @@ -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 index 0000000..f8977f5 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/ramfifo.inc @@ -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 index 0000000..4ef7919 --- /dev/null +++ b/src/edu/berkeley/fleet/fpga/ramfifo8.v @@ -0,0 +1,5 @@ +`define ADDR_BITS 3 +`define WIDTH 37 +`define MODULE_NAME ramfifo8 +`include "ramfifo.inc" + diff --git a/src/edu/berkeley/fleet/fpga/verilog/Verilog.java b/src/edu/berkeley/fleet/fpga/verilog/Verilog.java index 8da080f..67f538f 100644 --- a/src/edu/berkeley/fleet/fpga/verilog/Verilog.java +++ b/src/edu/berkeley/fleet/fpga/verilog/Verilog.java @@ -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