Use the Migen asynchronous FIFO

This commit is contained in:
Sebastien Bourdeauducq 2013-04-25 19:43:26 +02:00
parent d64b64501a
commit 4ff1175dcf
4 changed files with 9 additions and 162 deletions

View File

@ -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",

View 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:

View File

@ -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

View File

@ -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