Skip to content

Commit 16c6e4f

Browse files
author
Sebastien Bourdeauducq
committedJul 1, 2012
framebuffer: FIFO
1 parent acdd34e commit 16c6e4f

File tree

3 files changed

+163
-4
lines changed

3 files changed

+163
-4
lines changed
 

‎milkymist/framebuffer/__init__.py

+36-4
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,44 @@ def __init__(self):
111111
self.vga_clk = Signal()
112112
self.vga_hsync_n = Signal()
113113
self.vga_vsync_n = Signal()
114-
self.vga_r = Signal(BV(8))
115-
self.vga_g = Signal(BV(8))
116-
self.vga_b = Signal(BV(8))
114+
self.vga_r = Signal(BV(_bpc_dac))
115+
self.vga_g = Signal(BV(_bpc_dac))
116+
self.vga_b = Signal(BV(_bpc_dac))
117117

118118
def get_fragment(self):
119-
return Fragment() # TODO
119+
data_width = 2+3*_bpc_dac
120+
asfifo = Instance("asfifo",
121+
[
122+
("data_out", BV(data_width)),
123+
("empty", BV(1)),
124+
125+
("full", BV(1))
126+
], [
127+
("read_en", BV(1)),
128+
("clk_read", self.vga_clk),
129+
130+
("data_in", BV(data_width)),
131+
("write_en", BV(1)),
132+
133+
("rst", BV(1))
134+
],
135+
parameters=[
136+
("data_width", data_width),
137+
("address_width", 8)
138+
],
139+
clkport="clk_write")
140+
t = self.token("dac")
141+
return Fragment([
142+
Cat(self.vga_hsync_n, self.vga_vsync_n, self.vga_r, self.vga_g, self.vga_b).eq(asfifo.outs["data_out"]),
143+
asfifo.ins["read_en"].eq(1),
144+
145+
self.endpoints["dac"].ack.eq(~asfifo.outs["full"]),
146+
asfifo.ins["write_en"].eq(self.endpoints["dac"].stb),
147+
asfifo.ins["data_in"].eq(Cat(~t.hsync, ~t.vsync, t.r, t.g, t.b)),
148+
149+
self.busy.eq(0),
150+
asfifo.ins["rst"].eq(0)
151+
], instances=[asfifo])
120152

121153
class Framebuffer:
122154
def __init__(self, address, asmiport):

‎verilog/generic/asfifo.v

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* This file is based on "Asynchronous FIFO" by Alex Claros F.,
3+
* itself based on the article "Asynchronous FIFO in Virtex-II FPGAs"
4+
* by Peter Alfke.
5+
*/
6+
7+
module asfifo #(
8+
parameter data_width = 8,
9+
parameter address_width = 4,
10+
parameter fifo_depth = (1 << address_width)
11+
) (
12+
/* Read port */
13+
output [data_width-1:0] data_out,
14+
output reg empty,
15+
input read_en,
16+
input clk_read,
17+
18+
/* Write port */
19+
input [data_width-1:0] data_in,
20+
output reg full,
21+
input write_en,
22+
input clk_write,
23+
24+
/* Asynchronous reset */
25+
input rst
26+
);
27+
28+
reg [data_width-1:0] mem[fifo_depth-1:0];
29+
wire [address_width-1:0] write_index, read_index;
30+
wire equal_addresses;
31+
wire write_en_safe, read_en_safe;
32+
wire set_status, clear_status;
33+
reg status;
34+
wire preset_full, preset_empty;
35+
36+
assign data_out = mem[read_index];
37+
38+
always @(posedge clk_write) begin
39+
if(write_en & !full)
40+
mem[write_index] <= data_in;
41+
end
42+
43+
assign write_en_safe = write_en & ~full;
44+
assign read_en_safe = read_en & ~empty;
45+
46+
asfifo_graycounter #(
47+
.width(address_width)
48+
) counter_write (
49+
.gray_count(write_index),
50+
.ce(write_en_safe),
51+
.rst(rst),
52+
.clk(clk_write)
53+
);
54+
55+
asfifo_graycounter #(
56+
.width(address_width)
57+
) counter_read (
58+
.gray_count(read_index),
59+
.ce(read_en_safe),
60+
.rst(rst),
61+
.clk(clk_read)
62+
);
63+
64+
assign equal_addresses = (write_index == read_index);
65+
66+
assign set_status = (write_index[address_width-2] ~^ read_index[address_width-1]) &
67+
(write_index[address_width-1] ^ read_index[address_width-2]);
68+
69+
assign clear_status = ((write_index[address_width-2] ^ read_index[address_width-1]) &
70+
(write_index[address_width-1] ~^ read_index[address_width-2]))
71+
| rst;
72+
73+
always @(posedge clear_status, posedge set_status) begin
74+
if(clear_status)
75+
status <= 1'b0;
76+
else
77+
status <= 1'b1;
78+
end
79+
80+
assign preset_full = status & equal_addresses;
81+
82+
always @(posedge clk_write, posedge preset_full) begin
83+
if(preset_full)
84+
full <= 1'b1;
85+
else
86+
full <= 1'b0;
87+
end
88+
89+
assign preset_empty = ~status & equal_addresses;
90+
91+
always @(posedge clk_read, posedge preset_empty) begin
92+
if(preset_empty)
93+
empty <= 1'b1;
94+
else
95+
empty <= 1'b0;
96+
end
97+
98+
endmodule

‎verilog/generic/asfifo_graycounter.v

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* This file is based on "Asynchronous FIFO" by Alex Claros F.,
3+
* itself based on the article "Asynchronous FIFO in Virtex-II FPGAs"
4+
* by Peter Alfke.
5+
*/
6+
7+
module asfifo_graycounter #(
8+
parameter width = 2
9+
) (
10+
output reg [width-1:0] gray_count,
11+
input ce,
12+
input rst,
13+
input clk
14+
);
15+
16+
reg [width-1:0] binary_count;
17+
18+
always @(posedge clk, posedge rst) begin
19+
if(rst) begin
20+
binary_count <= {width{1'b0}} + 1;
21+
gray_count <= {width{1'b0}};
22+
end else if(ce) begin
23+
binary_count <= binary_count + 1;
24+
gray_count <= {binary_count[width-1],
25+
binary_count[width-2:0] ^ binary_count[width-1:1]};
26+
end
27+
end
28+
29+
endmodule

0 commit comments

Comments
 (0)
Please sign in to comment.