-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathframebuffer.py
More file actions
97 lines (80 loc) · 2.44 KB
/
framebuffer.py
File metadata and controls
97 lines (80 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from amaranth import *
from structures import Coords, Color
class FrameBufferRAM(Elaboratable):
def __init__(self, width, height, init):
self.mem = Memory(width=3, depth=width*height, init=init)
self.rp = self.mem.read_port(transparent=False, domain="px")
self.wp = self.mem.write_port(domain="px")
def elaborate(self, _platform):
m = Module()
m.submodules += self.rp
m.submodules += self.wp
return m
def pixels_to_fb(pix):
init = []
for x in range(160):
for y in range(120):
init += [pix[y][x]]
init += [0]*8 # pad to width of 128
return init
class FrameBuffer(Elaboratable):
def __init__(self):
self.width = 160
self.height = 120
self.fb_width = 128
self.fb_height = 160
self.coords_r = Coords(self.width, self.height)
self.coords_w = Coords(self.width, self.height)
self.w_data = Signal(3)
self.write = Signal()
self.swap = Signal()
self.read_fill = Signal()
self.fill_data = Signal(3)
self.palette = Array(Signal(12) for _ in range(16))
self.color = Color(12)
def elaborate(self, _platform):
m = Module()
pix = [[0]*160 for _ in range(120)]
for i in range(7):
for x in range(i*10,i*10+20):
for y in range(i*10+20,i*10+40):
pix[y-3][x+40] = i+1
init0 = pixels_to_fb(pix)
pix = [[0]*160 for _ in range(120)]
for i in range(7):
for x in range(i*10,i*10+20):
for y in range(i*10+20,i*10+40):
pix[y-3][x+40] = 7-i
init1 = pixels_to_fb(pix)
m.submodules.fb0 = fb0 = FrameBufferRAM(self.fb_width, self.fb_height, init0)
m.submodules.fb1 = fb1 = FrameBufferRAM(self.fb_width, self.fb_height, init1)
selected = Signal() # selected fb is the one we write to
with m.If(self.swap):
m.d.px += selected.eq(~selected)
m.d.comb += [
fb0.rp.en.eq(~selected),
fb1.rp.en.eq(selected),
]
with m.If(selected):
m.d.comb += [
fb0.wp.addr.eq(self.coords_w.xy),
fb0.wp.data.eq(self.w_data),
fb0.wp.en.eq(self.write),
fb1.rp.addr.eq(self.coords_r.xy),
fb1.wp.addr.eq(self.coords_r.xy),
fb1.wp.data.eq(self.fill_data),
fb1.wp.en.eq(self.read_fill),
self.color.rgb.eq(self.palette[fb1.rp.data]),
]
with m.Else():
m.d.comb += [
fb1.wp.addr.eq(self.coords_w.xy),
fb1.wp.data.eq(self.w_data),
fb1.wp.en.eq(self.write),
fb0.rp.addr.eq(self.coords_r.xy),
fb0.wp.addr.eq(self.coords_r.xy),
fb0.wp.data.eq(self.fill_data),
fb0.wp.en.eq(self.read_fill),
self.color.rgb.eq(self.palette[fb0.rp.data]),
]
return m