framebuffer: FIFO
This commit is contained in:
parent
acdd34e4ae
commit
16c6e4f4a7
|
@ -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):
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue