Use the Migen asynchronous FIFO
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 25 Apr 2013 17:43:26 +0000 (19:43 +0200)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 25 Apr 2013 17:43:26 +0000 (19:43 +0200)
build.py
milkymist/framebuffer/__init__.py
verilog/generic/asfifo.v [deleted file]
verilog/generic/asfifo_graycounter.v [deleted file]

index 4924c9c016f54473b994a359760df4eeb1ed8a76..2b2125abc2afc4bbefebfa5cae721d113b546941 100755 (executable)
--- a/build.py
+++ b/build.py
@@ -27,10 +27,6 @@ TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%;
 TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns;
 TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns;
 
-NET "asfifo*/counter_read/gray_count*" TIG;
-NET "asfifo*/counter_write/gray_count*" TIG;
-NET "asfifo*/preset_empty*" TIG;
-
 NET "{dviclk0}" TNM_NET = "GRPdviclk0";
 NET "{dviclk0}" CLOCK_DEDICATED_ROUTE = FALSE;
 TIMESPEC "TSdviclk0" = PERIOD "GRPdviclk0" 26.7 ns HIGH 50%;
@@ -44,7 +40,7 @@ TIMESPEC "TSdviclk1" = PERIOD "GRPdviclk1" 26.7 ns HIGH 50%;
                dviclk0=platform.lookup_request("dvi_in", 0).clk,
                dviclk1=platform.lookup_request("dvi_in", 1).clk)
        
-       for d in ["generic", "m1crg", "s6ddrphy", "minimac3"]:
+       for d in ["m1crg", "s6ddrphy", "minimac3"]:
                platform.add_source_dir(os.path.join("verilog", d))
        platform.add_sources(os.path.join("verilog", "lm32", "submodule", "rtl"), 
                "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
index b372a2232351a54d63b4fa0045874388d8f12de8..5b92a445cf6bc64296fa992c414b6cfb7099e33c 100644 (file)
@@ -2,6 +2,7 @@ from migen.fhdl.structure import *
 from migen.fhdl.specials import Instance
 from migen.fhdl.module import Module
 from migen.genlib.record import Record
+from migen.genlib.fifo import AsyncFIFO
 from migen.flow.actor import *
 from migen.flow.network import *
 from migen.flow.transactions import *
@@ -132,33 +133,15 @@ class FIFO(Module):
                ###
 
                data_width = 2+2*3*_bpc_dac
-               fifo_full = Signal()
-               fifo_write_en = Signal()
-               fifo_read_en = Signal()
-               fifo_data_out = Signal(data_width)
-               fifo_data_in = Signal(data_width)
-               self.specials += Instance("asfifo",
-                       Instance.Parameter("data_width", data_width),
-                       Instance.Parameter("address_width", 8),
-       
-                       Instance.Output("data_out", fifo_data_out),
-                       Instance.Output("empty"),
-                       Instance.Input("read_en", fifo_read_en),
-                       Instance.Input("clk_read", ClockSignal("vga")),
-
-                       Instance.Input("data_in", fifo_data_in),
-                       Instance.Output("full", fifo_full),
-                       Instance.Input("write_en", fifo_write_en),
-                       Instance.Input("clk_write", ClockSignal()),
-                       
-                       Instance.Input("rst", 0))
+               fifo = AsyncFIFO(data_width, 256)
+               self.add_submodule(fifo, {"write": "sys", "read": "vga"})
                fifo_in = self.dac.payload
                fifo_out = Record(_dac_layout)
                self.comb += [
-                       self.dac.ack.eq(~fifo_full),
-                       fifo_write_en.eq(self.dac.stb),
-                       fifo_data_in.eq(fifo_in.raw_bits()),
-                       fifo_out.raw_bits().eq(fifo_data_out),
+                       self.dac.ack.eq(fifo.writable),
+                       fifo.we.eq(self.dac.stb),
+                       fifo.din.eq(fifo_in.raw_bits()),
+                       fifo_out.raw_bits().eq(fifo.dout),
                        self.busy.eq(0)
                ]
 
@@ -177,7 +160,7 @@ class FIFO(Module):
                                self.vga_b.eq(fifo_out.p0.b)
                        )
                ]
-               self.comb += fifo_read_en.eq(pix_parity)
+               self.comb += fifo.re.eq(pix_parity)
 
 def sim_fifo_gen():
        while True:
diff --git a/verilog/generic/asfifo.v b/verilog/generic/asfifo.v
deleted file mode 100644 (file)
index 0cb1c20..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * This file is based on "Asynchronous FIFO" by Alex Claros F.,
- * itself based on the article "Asynchronous FIFO in Virtex-II FPGAs"
- * by Peter Alfke.
- */
-
-module asfifo #(
-       parameter data_width = 8,
-       parameter address_width = 4,
-       parameter fifo_depth = (1 << address_width)
-) (
-       /* Read port */
-       output reg [data_width-1:0] data_out,
-       output reg empty,
-       input read_en,
-       input clk_read,
-       
-       /* Write port */
-       input [data_width-1:0] data_in,
-       output reg full,
-       input write_en,
-       input clk_write,
-       
-       /* Asynchronous reset */
-       input rst
-);
-
-reg [data_width-1:0] mem[fifo_depth-1:0];
-wire [address_width-1:0] write_index, read_index;
-wire equal_addresses;
-wire write_en_safe, read_en_safe;
-wire set_status, clear_status;
-reg status;
-wire preset_full, preset_empty;
-
-reg [data_width-1:0] data_out0;
-
-always @(posedge clk_read) begin
-       data_out0 <= mem[read_index];
-       data_out <= data_out0;
-end
-
-always @(posedge clk_write) begin
-       if(write_en & !full)
-               mem[write_index] <= data_in;
-end
-
-assign write_en_safe = write_en & ~full;
-assign read_en_safe = read_en & ~empty;
-
-asfifo_graycounter #(
-       .width(address_width)
-) counter_write (
-       .gray_count(write_index),
-       .ce(write_en_safe),
-       .rst(rst),
-       .clk(clk_write)
-);
-
-asfifo_graycounter #(
-       .width(address_width)
-) counter_read (
-       .gray_count(read_index),
-       .ce(read_en_safe),
-       .rst(rst),
-       .clk(clk_read)
-);
-
-assign equal_addresses = (write_index == read_index);
-
-assign set_status = (write_index[address_width-2] ~^ read_index[address_width-1]) &
-       (write_index[address_width-1] ^ read_index[address_width-2]);
-
-assign clear_status = ((write_index[address_width-2] ^ read_index[address_width-1]) &
-       (write_index[address_width-1] ~^ read_index[address_width-2]))
-       | rst;
-
-always @(posedge clear_status, posedge set_status) begin
-       if(clear_status)
-               status <= 1'b0;
-       else
-               status <= 1'b1;
-end
-
-assign preset_full = status & equal_addresses;
-
-always @(posedge clk_write, posedge preset_full) begin
-       if(preset_full)
-               full <= 1'b1;
-       else
-               full <= 1'b0;
-end
-
-assign preset_empty = ~status & equal_addresses;
-
-always @(posedge clk_read, posedge preset_empty) begin
-       if(preset_empty)
-               empty <= 1'b1;
-       else
-               empty <= 1'b0;
-end
-
-endmodule
diff --git a/verilog/generic/asfifo_graycounter.v b/verilog/generic/asfifo_graycounter.v
deleted file mode 100644 (file)
index 531ca80..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * This file is based on "Asynchronous FIFO" by Alex Claros F.,
- * itself based on the article "Asynchronous FIFO in Virtex-II FPGAs"
- * by Peter Alfke.
- */
-
-module asfifo_graycounter #(
-       parameter width = 2
-) (
-       output reg [width-1:0] gray_count,
-       input ce,
-       input rst,
-       input clk
-);
-
-reg [width-1:0] binary_count;
-
-always @(posedge clk, posedge rst) begin
-       if(rst) begin
-               binary_count <= {width{1'b0}} + 1;
-               gray_count <= {width{1'b0}};
-       end else if(ce) begin
-               binary_count <= binary_count + 1;
-               gray_count <= {binary_count[width-1],
-                               binary_count[width-2:0] ^ binary_count[width-1:1]};
-       end
-end
-
-endmodule