Skip to content

Commit 8fd092c

Browse files
author
Sebastien Bourdeauducq
committedMar 28, 2013
crg: support VGA pixel clock reprogramming
1 parent 1e860c7 commit 8fd092c

File tree

4 files changed

+81
-23
lines changed

4 files changed

+81
-23
lines changed
 

‎milkymist/m1crg/__init__.py

+49-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
from migen.fhdl.structure import *
44
from migen.fhdl.specials import Instance
55
from migen.fhdl.module import Module
6+
from migen.bank.description import *
67

7-
class M1CRG(Module):
8+
class M1CRG(Module, AutoReg):
89
def __init__(self, pads, outfreq1x):
910
self.clock_domains.cd_sys = ClockDomain()
1011
self.clock_domains.cd_sys2x_270 = ClockDomain()
@@ -17,12 +18,22 @@ def __init__(self, pads, outfreq1x):
1718
self.clk4x_wr_strb = Signal()
1819
self.clk4x_rd_strb = Signal()
1920

21+
self._r_cmd_data = RegisterField(10)
22+
self._r_send_cmd_data = RegisterRaw()
23+
self._r_send_go = RegisterRaw()
24+
self._r_status = RegisterField(3, READ_ONLY, WRITE_ONLY)
25+
2026
###
2127

2228
infreq = 50*1000000
2329
ratio = Fraction(outfreq1x)/Fraction(infreq)
2430
in_period = float(Fraction(1000000000)/Fraction(infreq))
2531

32+
vga_progdata = Signal()
33+
vga_progen = Signal()
34+
vga_progdone = Signal()
35+
vga_locked = Signal()
36+
2637
self.specials += Instance("m1crg",
2738
Instance.Parameter("in_period", in_period),
2839
Instance.Parameter("f_mult", ratio.numerator),
@@ -48,4 +59,40 @@ def __init__(self, pads, outfreq1x):
4859
Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
4960
Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
5061
Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk),
51-
Instance.Output("vga_clk_pad", pads.vga_clk))
62+
Instance.Output("vga_clk_pad", pads.vga_clk),
63+
64+
Instance.Input("vga_progclk", ClockSignal()),
65+
Instance.Input("vga_progdata", vga_progdata),
66+
Instance.Input("vga_progen", vga_progen),
67+
Instance.Output("vga_progdone", vga_progdone),
68+
Instance.Output("vga_locked", vga_locked))
69+
70+
remaining_bits = Signal(max=11)
71+
transmitting = Signal()
72+
self.comb += transmitting.eq(remaining_bits != 0)
73+
sr = Signal(10)
74+
self.sync += [
75+
If(self._r_send_cmd_data.re,
76+
remaining_bits.eq(10),
77+
sr.eq(self._r_cmd_data.field.r)
78+
).Elif(transmitting,
79+
remaining_bits.eq(remaining_bits - 1),
80+
sr.eq(sr[1:])
81+
)
82+
]
83+
self.comb += [
84+
vga_progdata.eq(transmitting & sr[0]),
85+
vga_progen.eq(transmitting | self._r_send_go.re)
86+
]
87+
88+
# enforce gap between commands
89+
busy_counter = Signal(max=14)
90+
busy = Signal()
91+
self.comb += busy.eq(busy_counter != 0)
92+
self.sync += If(self._r_send_cmd_data.re,
93+
busy_counter.eq(13)
94+
).Elif(busy,
95+
busy_counter.eq(busy_counter - 1)
96+
)
97+
98+
self.comb += self._r_status.field.w.eq(Cat(busy, vga_progdone, vga_locked))

‎software/include/hw/flags.h

+4
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@
1818
#define MINIMAC_EV_RX1 0x2
1919
#define MINIMAC_EV_TX 0x4
2020

21+
#define CLKGEN_STATUS_BUSY 0x1
22+
#define CLKGEN_STATUS_PROGDONE 0x2
23+
#define CLKGEN_STATUS_LOCKED 0x4
24+
2125
#endif /* __HW_FLAGS_H */

‎top.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,18 @@ def __init__(self, platform):
6565
class SoC(Module):
6666
csr_base = 0xe0000000
6767
csr_map = {
68-
"uart": 0,
69-
"dfii": 1,
70-
"identifier": 2,
71-
"timer0": 3,
72-
"minimac": 4,
73-
"fb": 5,
74-
"asmiprobe": 6,
75-
"dvisampler0": 7,
76-
"dvisampler0_edid_mem": 8,
77-
"dvisampler1": 9,
78-
"dvisampler1_edid_mem": 10,
68+
"crg": 0,
69+
"uart": 1,
70+
"dfii": 2,
71+
"identifier": 3,
72+
"timer0": 4,
73+
"minimac": 5,
74+
"fb": 6,
75+
"asmiprobe": 7,
76+
"dvisampler0": 8,
77+
"dvisampler0_edid_mem": 9,
78+
"dvisampler1": 10,
79+
"dvisampler1_edid_mem": 11,
7980
}
8081

8182
interrupt_map = {
@@ -134,6 +135,7 @@ def __init__(self, platform):
134135
#
135136
# CSR
136137
#
138+
self.submodules.crg = m1crg.M1CRG(M1ClockPads(platform), clk_freq)
137139
self.submodules.uart = uart.UART(platform.request("serial"), clk_freq, baud=115200)
138140
self.submodules.identifier = identifier.Identifier(0x4D31, version, int(clk_freq))
139141
self.submodules.timer0 = timer.Timer()
@@ -151,11 +153,10 @@ def __init__(self, platform):
151153
#
152154
for k, v in sorted(self.interrupt_map.items(), key=itemgetter(1)):
153155
self.comb += self.cpu.interrupt[v].eq(getattr(self, k).ev.irq)
154-
156+
155157
#
156158
# Clocking
157159
#
158-
self.submodules.crg = m1crg.M1CRG(M1ClockPads(platform), clk_freq)
159160
self.comb += [
160161
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
161162
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)

‎verilog/m1crg/m1crg.v

+14-8
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,14 @@ module m1crg #(
3333

3434
/* VGA clock */
3535
output vga_clk, /* < buffered, to internal clock network */
36-
output vga_clk_pad /* < forwarded through ODDR2, to I/O */
36+
output vga_clk_pad, /* < forwarded through ODDR2, to I/O */
37+
38+
/* VGA clock control */
39+
input vga_progclk,
40+
input vga_progdata,
41+
input vga_progen,
42+
output vga_progdone,
43+
output vga_locked
3744
);
3845

3946
/*
@@ -257,7 +264,6 @@ assign eth_tx_clk = eth_tx_clk_pad;
257264
* VGA clock
258265
*/
259266

260-
// TODO: hook up the reprogramming interface
261267
DCM_CLKGEN #(
262268
.CLKFXDV_DIVIDE(2),
263269
.CLKFX_DIVIDE(4),
@@ -270,15 +276,15 @@ DCM_CLKGEN #(
270276
.CLKFX(vga_clk),
271277
.CLKFX180(),
272278
.CLKFXDV(),
273-
.LOCKED(),
274-
.PROGDONE(),
275279
.STATUS(),
276280
.CLKIN(pllout4),
277281
.FREEZEDCM(1'b0),
278-
.PROGCLK(1'b0),
279-
.PROGDATA(),
280-
.PROGEN(1'b0),
281-
.RST(1'b0)
282+
.PROGCLK(vga_progclk),
283+
.PROGDATA(vga_progdata),
284+
.PROGEN(vga_progen),
285+
.PROGDONE(vga_progdone),
286+
.LOCKED(vga_locked),
287+
.RST(~pll_lckd)
282288
);
283289

284290
ODDR2 #(

0 commit comments

Comments
 (0)
Please sign in to comment.