mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Use the Migen asynchronous FIFO
This commit is contained in:
parent
d64b64501a
commit
4ff1175dcf
4 changed files with 9 additions and 162 deletions
6
build.py
6
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",
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in a new issue