framebuffer: FIFO

This commit is contained in:
Sebastien Bourdeauducq 2012-07-01 15:22:57 +02:00
parent acdd34e4ae
commit 16c6e4f4a7
3 changed files with 163 additions and 4 deletions

View File

@ -111,12 +111,44 @@ class FIFO(Actor):
self.vga_clk = Signal()
self.vga_hsync_n = Signal()
self.vga_vsync_n = Signal()
self.vga_r = Signal(BV(8))
self.vga_g = Signal(BV(8))
self.vga_b = Signal(BV(8))
self.vga_r = Signal(BV(_bpc_dac))
self.vga_g = Signal(BV(_bpc_dac))
self.vga_b = Signal(BV(_bpc_dac))
def get_fragment(self):
return Fragment() # TODO
data_width = 2+3*_bpc_dac
asfifo = Instance("asfifo",
[
("data_out", BV(data_width)),
("empty", BV(1)),
("full", BV(1))
], [
("read_en", BV(1)),
("clk_read", self.vga_clk),
("data_in", BV(data_width)),
("write_en", BV(1)),
("rst", BV(1))
],
parameters=[
("data_width", data_width),
("address_width", 8)
],
clkport="clk_write")
t = self.token("dac")
return Fragment([
Cat(self.vga_hsync_n, self.vga_vsync_n, self.vga_r, self.vga_g, self.vga_b).eq(asfifo.outs["data_out"]),
asfifo.ins["read_en"].eq(1),
self.endpoints["dac"].ack.eq(~asfifo.outs["full"]),
asfifo.ins["write_en"].eq(self.endpoints["dac"].stb),
asfifo.ins["data_in"].eq(Cat(~t.hsync, ~t.vsync, t.r, t.g, t.b)),
self.busy.eq(0),
asfifo.ins["rst"].eq(0)
], instances=[asfifo])
class Framebuffer:
def __init__(self, address, asmiport):

98
verilog/generic/asfifo.v Normal file
View File

@ -0,0 +1,98 @@
/*
* 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 [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;
assign data_out = mem[read_index];
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

@ -0,0 +1,29 @@
/*
* 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