Skip to content

Commit 5649e88

Browse files
author
Sebastien Bourdeauducq
committedFeb 11, 2013
Use Mibuild
1 parent f68fcef commit 5649e88

File tree

9 files changed

+230
-333
lines changed

9 files changed

+230
-333
lines changed
 

‎Makefile

+2-22
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,7 @@
1-
PYTHON=python3
2-
31
all: build/soc.bit
42

5-
# We need to change to the build directory because the Xilinx tools
6-
# tend to dump a mess of various files in the current directory.
7-
8-
build/soc.prj build/soc.ucf:
9-
$(PYTHON) build.py
10-
11-
build/soc.ngc: build/soc.prj
12-
cd build && xst -ifn ../soc.xst
13-
14-
build/soc.ngd: build/soc.ngc build/soc.ucf
15-
cd build && ngdbuild -uc soc.ucf soc.ngc
16-
17-
build/soc.ncd: build/soc.ngd
18-
cd build && map -ol high -w soc.ngd
19-
20-
build/soc-routed.ncd: build/soc.ncd
21-
cd build && par -ol high -w soc.ncd soc-routed.ncd
22-
23-
build/soc.bit build/soc.bin: build/soc-routed.ncd
24-
cd build && bitgen -g LCK_cycle:6 -g Binary:Yes -g INIT_9K:Yes -w soc-routed.ncd soc.bit
3+
build/soc.bit build/soc.bin:
4+
./build.py
255

266
load: build/soc.bit
277
jtag -n load.jtag

‎build.py

100644100755
+56-36
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,63 @@
1+
#!/usr/bin/env python3
2+
13
import os
4+
from mibuild.platforms import m1
25
import top
36

4-
# list Verilog sources before changing directory
5-
verilog_sources = []
6-
def add_core_dir(d):
7-
root = os.path.join("verilog", d)
8-
files = os.listdir(root)
9-
for f in files:
10-
if f[-2:] == ".v":
11-
verilog_sources.append(os.path.join(root, f))
12-
def add_core_files(d, files):
13-
for f in files:
14-
verilog_sources.append(os.path.join("verilog", d, f))
15-
add_core_dir("generic")
16-
add_core_dir("m1crg")
17-
add_core_dir("s6ddrphy")
18-
add_core_files("lm32", ["lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
19-
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
20-
"lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
21-
"lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
22-
"lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
23-
"jtag_tap_spartan6.v"])
24-
add_core_dir("minimac3")
7+
def main():
8+
plat = m1.Platform()
9+
soc = top.SoC()
10+
11+
# set pin constraints
12+
plat.request("clk50", obj=soc.crg.clk50_pad)
13+
plat.request("user_btn", 1, obj=soc.crg.trigger_reset)
14+
plat.request("norflash_rst_n", obj=soc.crg.norflash_rst_n)
15+
plat.request("vga_clock", obj=soc.crg.vga_clk_pad)
16+
plat.request("ddram_clock", obj=soc.crg, name_map=lambda s: "ddr_clk_pad_" + s)
17+
plat.request("eth_clocks", obj=soc.crg, name_map=lambda s: "eth_" + s + "_clk_pad")
18+
19+
plat.request("norflash", obj=soc.norflash)
20+
plat.request("serial", obj=soc.uart)
21+
plat.request("ddram", obj=soc.ddrphy, name_map=lambda s: "sd_" + s)
22+
plat.request("eth", obj=soc.minimac, name_map=lambda s: "phy_" + s)
23+
plat.request("vga", obj=soc.fb, name_map=lambda s: "vga_" + s)
24+
25+
# set extra constraints
26+
plat.add_platform_command("""
27+
NET "{clk50}" TNM_NET = "GRPclk50";
28+
TIMESPEC "TSclk50" = PERIOD "GRPclk50" 20 ns HIGH 50%;
29+
INST "m1crg/wr_bufpll" LOC = "BUFPLL_X0Y2";
30+
INST "m1crg/rd_bufpll" LOC = "BUFPLL_X0Y3";
2531
26-
os.chdir("build")
32+
PIN "m1crg/bufg_x1.O" CLOCK_DEDICATED_ROUTE = FALSE;
2733
28-
def str2file(filename, contents):
29-
f = open(filename, "w")
30-
f.write(contents)
31-
f.close()
34+
NET "{phy_rx_clk}" TNM_NET = "GRPphy_rx_clk";
35+
NET "{phy_tx_clk}" TNM_NET = "GRPphy_tx_clk";
36+
TIMESPEC "TSphy_rx_clk" = PERIOD "GRPphy_rx_clk" 40 ns HIGH 50%;
37+
TIMESPEC "TSphy_tx_clk" = PERIOD "GRPphy_tx_clk" 40 ns HIGH 50%;
38+
TIMESPEC "TSphy_tx_clk_io" = FROM "GRPphy_tx_clk" TO "PADS" 10 ns;
39+
TIMESPEC "TSphy_rx_clk_io" = FROM "PADS" TO "GRPphy_rx_clk" 10 ns;
3240
33-
# generate source
34-
(src_verilog, src_ucf) = top.get()
35-
str2file("soc.v", src_verilog)
36-
str2file("soc.ucf", src_ucf)
37-
verilog_sources.append("build/soc.v")
41+
NET "asfifo*/counter_read/gray_count*" TIG;
42+
NET "asfifo*/counter_write/gray_count*" TIG;
43+
NET "asfifo*/preset_empty*" TIG;
44+
""",
45+
clk50=soc.crg.clk50_pad,
46+
phy_rx_clk=soc.crg.eth_rx_clk_pad,
47+
phy_tx_clk=soc.crg.eth_tx_clk_pad)
48+
49+
# add Verilog sources
50+
for d in ["generic", "m1crg", "s6ddrphy", "minimac3"]:
51+
plat.add_source_dir(os.path.join("verilog", d))
52+
plat.add_sources(os.path.join("verilog", "lm32"),
53+
"lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
54+
"lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
55+
"lm32_shifter.v", "lm32_multiplier_spartan6.v", "lm32_mc_arithmetic.v",
56+
"lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
57+
"lm32_dcache.v", "lm32_top.v", "lm32_debug.v", "lm32_jtag.v", "jtag_cores.v",
58+
"jtag_tap_spartan6.v")
59+
60+
plat.build_cmdline(soc.get_fragment(), clock_domains=soc.crg.get_clock_domains())
3861

39-
# generate XST project file
40-
xst_prj = ""
41-
for s in verilog_sources:
42-
xst_prj += "verilog work ../" + s + "\n"
43-
str2file("soc.prj", xst_prj)
62+
if __name__ == "__main__":
63+
main()

‎constraints.py

-110
This file was deleted.

‎milkymist/m1crg/__init__.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
from fractions import Fraction
22

33
from migen.fhdl.structure import *
4+
from mibuild.crg import CRG
45

5-
class M1CRG:
6+
class M1CRG(CRG):
67
def __init__(self, infreq, outfreq1x):
7-
self.clkin = Signal()
8+
self.clk50_pad = Signal()
89
self.trigger_reset = Signal()
910

11+
self.eth_rx_clk_pad = Signal()
12+
self.eth_tx_clk_pad = Signal()
13+
1014
self.cd_sys = ClockDomain("sys")
1115
self.cd_sys2x_270 = ClockDomain("sys2x_270")
1216
self.cd_sys4x_wr = ClockDomain("sys4x_wr")
1317
self.cd_sys4x_rd = ClockDomain("sys4x_rd")
18+
self.cd_eth_rx = ClockDomain("eth_rx")
19+
self.cd_eth_tx = ClockDomain("eth_tx")
1420
self.cd_vga = ClockDomain("vga")
1521

1622
ratio = Fraction(outfreq1x)/Fraction(infreq)
@@ -20,24 +26,29 @@ def __init__(self, infreq, outfreq1x):
2026
Instance.Parameter("in_period", in_period),
2127
Instance.Parameter("f_mult", ratio.numerator),
2228
Instance.Parameter("f_div", ratio.denominator),
23-
Instance.Input("clkin", self.clkin),
29+
Instance.Input("clk50_pad", self.clk50_pad),
2430
Instance.Input("trigger_reset", self.trigger_reset),
2531

32+
Instance.Input("eth_rx_clk_pad", self.eth_rx_clk_pad),
33+
Instance.Input("eth_tx_clk_pad", self.eth_tx_clk_pad),
34+
2635
Instance.Output("sys_clk", self.cd_sys.clk),
2736
Instance.Output("sys_rst", self.cd_sys.rst),
2837
Instance.Output("clk2x_270", self.cd_sys2x_270.clk),
2938
Instance.Output("clk4x_wr", self.cd_sys4x_wr.clk),
3039
Instance.Output("clk4x_rd", self.cd_sys4x_rd.clk),
40+
Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
41+
Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
3142
Instance.Output("vga_clk", self.cd_vga.clk)
3243
]
3344

3445
for name in [
35-
"ac97_rst_n",
36-
"videoin_rst_n",
37-
"flash_rst_n",
46+
"norflash_rst_n",
3847
"clk4x_wr_strb",
3948
"clk4x_rd_strb",
40-
"eth_clk_pad",
49+
"ddr_clk_pad_p",
50+
"ddr_clk_pad_n",
51+
"eth_phy_clk_pad",
4152
"vga_clk_pad"
4253
]:
4354
s = Signal(name=name)
@@ -46,6 +57,5 @@ def __init__(self, infreq, outfreq1x):
4657

4758
self._inst = Instance("m1crg", *inst_items)
4859

49-
5060
def get_fragment(self):
5161
return Fragment(instances=[self._inst])

‎milkymist/minimac3/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ def get_fragment(self):
8484
Instance.Output("wb_dat_o", self.membus.dat_r),
8585
Instance.Output("wb_ack_o", self.membus.ack),
8686

87+
Instance.ClockPort("phy_tx_clk", "eth_tx"),
8788
Instance.Output("phy_tx_data", self.phy_tx_data),
8889
Instance.Output("phy_tx_en", self.phy_tx_en),
89-
Instance.Output("phy_tx_er", self.phy_tx_er),
90-
Instance.Input("phy_tx_clk", self.phy_tx_clk),
91-
Instance.Input("phy_rx_clk", self.phy_rx_clk),
90+
Instance.Output("phy_tx_er", self.phy_tx_er),
91+
Instance.ClockPort("phy_rx_clk", "eth_rx"),
9292
Instance.Input("phy_rx_data", self.phy_rx_data),
9393
Instance.Input("phy_dv", self.phy_dv),
9494
Instance.Input("phy_rx_er", self.phy_rx_er),

‎milkymist/s6ddrphy/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ def __init__(self, a, ba, d):
1616
("clk4x_wr_strb", 1, Instance.Input),
1717
("clk4x_rd_strb", 1, Instance.Input),
1818

19-
("sd_clk_out_p", 1, Instance.Output),
20-
("sd_clk_out_n", 1, Instance.Output),
2119
("sd_a", a, Instance.Output),
2220
("sd_ba", ba, Instance.Output),
2321
("sd_cs_n", 1, Instance.Output),

‎top.py

+86-100
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from milkymist import m1crg, lm32, norflash, uart, s6ddrphy, dfii, asmicon, \
99
identifier, timer, minimac3, framebuffer, asmiprobe
1010
from cmacros import get_macros
11-
from constraints import Constraints
1211

1312
MHz = 1000000
1413
clk_freq = (83 + Fraction(1, 3))*MHz
@@ -58,103 +57,90 @@ def interrupt_n(name):
5857

5958
version = get_macros("common/version.h")["VERSION"][1:-1]
6059

61-
def get():
62-
#
63-
# ASMI
64-
#
65-
asmicon0 = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
66-
asmiport_wb = asmicon0.hub.get_port()
67-
asmiport_fb = asmicon0.hub.get_port(2)
68-
asmicon0.finalize()
69-
70-
#
71-
# DFI
72-
#
73-
ddrphy0 = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
74-
dfii0 = dfii.DFIInjector(csr_offset("DFII"),
75-
sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
76-
dficon0 = dfi.Interconnect(dfii0.master, ddrphy0.dfi)
77-
dficon1 = dfi.Interconnect(asmicon0.dfi, dfii0.slave)
60+
class SoC:
61+
def __init__(self):
62+
#
63+
# ASMI
64+
#
65+
self.asmicon = asmicon.ASMIcon(sdram_phy, sdram_geom, sdram_timing)
66+
asmiport_wb = self.asmicon.hub.get_port()
67+
asmiport_fb = self.asmicon.hub.get_port(2)
68+
self.asmicon.finalize()
69+
70+
#
71+
# DFI
72+
#
73+
self.ddrphy = s6ddrphy.S6DDRPHY(sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d)
74+
self.dfii = dfii.DFIInjector(csr_offset("DFII"),
75+
sdram_geom.mux_a, sdram_geom.bank_a, sdram_phy.dfi_d, sdram_phy.nphases)
76+
self.dficon0 = dfi.Interconnect(self.dfii.master, self.ddrphy.dfi)
77+
self.dficon1 = dfi.Interconnect(self.asmicon.dfi, self.dfii.slave)
7878

79-
#
80-
# WISHBONE
81-
#
82-
cpu0 = lm32.LM32()
83-
norflash0 = norflash.NorFlash(25, 12)
84-
sram0 = wishbone.SRAM(sram_size)
85-
minimac0 = minimac3.MiniMAC(csr_offset("MINIMAC"))
86-
wishbone2asmi0 = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
87-
wishbone2csr0 = wishbone2csr.WB2CSR()
88-
89-
# norflash 0x00000000 (shadow @0x80000000)
90-
# SRAM/debug 0x10000000 (shadow @0x90000000)
91-
# USB 0x20000000 (shadow @0xa0000000)
92-
# Ethernet 0x30000000 (shadow @0xb0000000)
93-
# SDRAM 0x40000000 (shadow @0xc0000000)
94-
# CSR bridge 0x60000000 (shadow @0xe0000000)
95-
wishbonecon0 = wishbone.InterconnectShared(
96-
[
97-
cpu0.ibus,
98-
cpu0.dbus
99-
], [
100-
(lambda a: a[26:29] == 0, norflash0.bus),
101-
(lambda a: a[26:29] == 1, sram0.bus),
102-
(lambda a: a[26:29] == 3, minimac0.membus),
103-
(lambda a: a[27:29] == 2, wishbone2asmi0.wishbone),
104-
(lambda a: a[27:29] == 3, wishbone2csr0.wishbone)
105-
],
106-
register=True)
107-
108-
#
109-
# CSR
110-
#
111-
uart0 = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
112-
identifier0 = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
113-
timer0 = timer.Timer(csr_offset("TIMER0"))
114-
fb0 = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
115-
asmiprobe0 = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), asmicon0.hub)
116-
csrcon0 = csr.Interconnect(wishbone2csr0.csr, [
117-
uart0.bank.bus,
118-
dfii0.bank.bus,
119-
identifier0.bank.bus,
120-
timer0.bank.bus,
121-
minimac0.bank.bus,
122-
fb0.bank.bus,
123-
asmiprobe0.bank.bus
124-
])
125-
126-
#
127-
# Interrupts
128-
#
129-
interrupts = Fragment([
130-
cpu0.interrupt[interrupt_n("UART")].eq(uart0.events.irq),
131-
cpu0.interrupt[interrupt_n("TIMER0")].eq(timer0.events.irq),
132-
cpu0.interrupt[interrupt_n("MINIMAC")].eq(minimac0.events.irq)
133-
])
134-
135-
#
136-
# Housekeeping
137-
#
138-
crg0 = m1crg.M1CRG(50*MHz, clk_freq)
139-
140-
ddrphy_strobes = Fragment([
141-
ddrphy0.clk4x_wr_strb.eq(crg0.clk4x_wr_strb),
142-
ddrphy0.clk4x_rd_strb.eq(crg0.clk4x_rd_strb)
143-
])
144-
frag = autofragment.from_local() \
145-
+ interrupts \
146-
+ ddrphy_strobes
147-
cst = Constraints(crg0, norflash0, uart0, ddrphy0, minimac0, fb0)
148-
src_verilog, vns = verilog.convert(frag,
149-
cst.get_ios(),
150-
name="soc",
151-
clock_domains={
152-
"sys": crg0.cd_sys,
153-
"sys2x_270": crg0.cd_sys2x_270,
154-
"sys4x_wr": crg0.cd_sys4x_wr,
155-
"sys4x_rd": crg0.cd_sys4x_rd,
156-
"vga": crg0.cd_vga
157-
},
158-
return_ns=True)
159-
src_ucf = cst.get_ucf(vns)
160-
return (src_verilog, src_ucf)
79+
#
80+
# WISHBONE
81+
#
82+
self.cpu = lm32.LM32()
83+
self.norflash = norflash.NorFlash(25, 12)
84+
self.sram = wishbone.SRAM(sram_size)
85+
self.minimac = minimac3.MiniMAC(csr_offset("MINIMAC"))
86+
self.wishbone2asmi = wishbone2asmi.WB2ASMI(l2_size//4, asmiport_wb)
87+
self.wishbone2csr = wishbone2csr.WB2CSR()
88+
89+
# norflash 0x00000000 (shadow @0x80000000)
90+
# SRAM/debug 0x10000000 (shadow @0x90000000)
91+
# USB 0x20000000 (shadow @0xa0000000)
92+
# Ethernet 0x30000000 (shadow @0xb0000000)
93+
# SDRAM 0x40000000 (shadow @0xc0000000)
94+
# CSR bridge 0x60000000 (shadow @0xe0000000)
95+
self.wishbonecon = wishbone.InterconnectShared(
96+
[
97+
self.cpu.ibus,
98+
self.cpu.dbus
99+
], [
100+
(lambda a: a[26:29] == 0, self.norflash.bus),
101+
(lambda a: a[26:29] == 1, self.sram.bus),
102+
(lambda a: a[26:29] == 3, self.minimac.membus),
103+
(lambda a: a[27:29] == 2, self.wishbone2asmi.wishbone),
104+
(lambda a: a[27:29] == 3, self.wishbone2csr.wishbone)
105+
],
106+
register=True)
107+
108+
#
109+
# CSR
110+
#
111+
self.uart = uart.UART(csr_offset("UART"), clk_freq, baud=115200)
112+
self.identifier = identifier.Identifier(csr_offset("ID"), 0x4D31, version, int(clk_freq))
113+
self.timer = timer.Timer(csr_offset("TIMER0"))
114+
self.fb = framebuffer.Framebuffer(csr_offset("FB"), asmiport_fb)
115+
self.asmiprobe = asmiprobe.ASMIprobe(csr_offset("ASMIPROBE"), self.asmicon.hub)
116+
self.csrcon = csr.Interconnect(self.wishbone2csr.csr, [
117+
self.uart.bank.bus,
118+
self.dfii.bank.bus,
119+
self.identifier.bank.bus,
120+
self.timer.bank.bus,
121+
self.minimac.bank.bus,
122+
self.fb.bank.bus,
123+
self.asmiprobe.bank.bus
124+
])
125+
126+
#
127+
# Clocking
128+
#
129+
self.crg = m1crg.M1CRG(50*MHz, clk_freq)
130+
131+
def get_fragment(self):
132+
comb = [
133+
#
134+
# Interrupts
135+
#
136+
self.cpu.interrupt[interrupt_n("UART")].eq(self.uart.events.irq),
137+
self.cpu.interrupt[interrupt_n("TIMER0")].eq(self.timer.events.irq),
138+
self.cpu.interrupt[interrupt_n("MINIMAC")].eq(self.minimac.events.irq),
139+
#
140+
# DDR PHY strobes
141+
#
142+
self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
143+
self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
144+
]
145+
glue = Fragment(comb)
146+
return glue + autofragment.from_attributes(self)

‎verilog/m1crg/m1crg.v

+65-18
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,32 @@ module m1crg #(
44
parameter f_div = 0,
55
parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
66
) (
7-
input clkin,
7+
input clk50_pad,
88
input trigger_reset,
99

1010
output sys_clk,
1111
output reg sys_rst,
1212

13-
/* Reset off-chip devices */
14-
output ac97_rst_n,
15-
output videoin_rst_n,
16-
output flash_rst_n,
13+
/* Reset NOR flash */
14+
output norflash_rst_n,
1715

1816
/* DDR PHY clocks */
1917
output clk2x_270,
2018
output clk4x_wr,
2119
output clk4x_wr_strb,
2220
output clk4x_rd,
2321
output clk4x_rd_strb,
22+
23+
/* DDR off-chip clocking */
24+
output ddr_clk_pad_p,
25+
output ddr_clk_pad_n,
2426

25-
/* Ethernet PHY clock */
26-
output reg eth_clk_pad, /* < unbuffered, to I/O */
27+
/* Ethernet PHY clocks */
28+
output reg eth_phy_clk_pad,
29+
input eth_rx_clk_pad,
30+
input eth_tx_clk_pad,
31+
output eth_rx_clk,
32+
output eth_tx_clk,
2733

2834
/* VGA clock */
2935
output vga_clk, /* < buffered, to internal clock network */
@@ -43,9 +49,6 @@ always @(posedge sys_clk) begin
4349
sys_rst <= rst_debounce != 20'd0;
4450
end
4551

46-
assign ac97_rst_n = ~sys_rst;
47-
assign videoin_rst_n = ~sys_rst;
48-
4952
/*
5053
* We must release the Flash reset before the system reset
5154
* because the Flash needs some time to come out of reset
@@ -64,28 +67,28 @@ always @(posedge sys_clk) begin
6467
flash_rstcounter <= flash_rstcounter + 8'd1;
6568
end
6669

67-
assign flash_rst_n = flash_rstcounter[7];
70+
assign norflash_rst_n = flash_rstcounter[7];
6871

6972
/*
7073
* Clock management. Inspired by the NWL reference design.
7174
*/
7275

73-
wire sdr_clkin;
76+
wire sdr_clk50;
7477
wire clkdiv;
7578

7679
IBUF #(
7780
.IOSTANDARD("DEFAULT")
7881
) clk2_iob (
79-
.I(clkin),
80-
.O(sdr_clkin)
82+
.I(clk50_pad),
83+
.O(sdr_clk50)
8184
);
8285

8386
BUFIO2 #(
8487
.DIVIDE(1),
8588
.DIVIDE_BYPASS("FALSE"),
8689
.I_INVERT("FALSE")
8790
) bufio2_inst2 (
88-
.I(sdr_clkin),
91+
.I(sdr_clk50),
8992
.IOCLK(),
9093
.DIVCLK(clkdiv),
9194
.SERDESSTROBE()
@@ -135,7 +138,7 @@ PLL_ADV #(
135138
.CLKOUT1(pllout1), /* < x4 clock for reads */
136139
.CLKOUT2(pllout2), /* < x2 90 clock to generate memory clock, clock DQS and memory address and control signals. */
137140
.CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
138-
.CLKOUT4(pllout4), /* < buffered clkin */
141+
.CLKOUT4(pllout4), /* < buffered clk50 */
139142
.CLKOUT5(),
140143
.CLKOUTDCM0(),
141144
.CLKOUTDCM1(),
@@ -191,11 +194,55 @@ BUFG bufg_x1(
191194
.O(sys_clk)
192195
);
193196

194-
/* Ethernet PHY */
197+
198+
/*
199+
* SDRAM clock
200+
*/
201+
202+
ODDR2 #(
203+
.DDR_ALIGNMENT("NONE"),
204+
.INIT(1'b0),
205+
.SRTYPE("SYNC")
206+
) sd_clk_forward_p (
207+
.Q(sd_clk_out_p),
208+
.C0(clk2x_270),
209+
.C1(~clk2x_270),
210+
.CE(1'b1),
211+
.D0(1'b1),
212+
.D1(1'b0),
213+
.R(1'b0),
214+
.S(1'b0)
215+
);
216+
ODDR2 #(
217+
.DDR_ALIGNMENT("NONE"),
218+
.INIT(1'b0),
219+
.SRTYPE("SYNC")
220+
) sd_clk_forward_n (
221+
.Q(sd_clk_out_n),
222+
.C0(clk2x_270),
223+
.C1(~clk2x_270),
224+
.CE(1'b1),
225+
.D0(1'b0),
226+
.D1(1'b1),
227+
.R(1'b0),
228+
.S(1'b0)
229+
);
230+
231+
/*
232+
* Ethernet PHY
233+
*/
234+
195235
always @(posedge pllout4)
196236
eth_clk_pad <= ~eth_clk_pad;
197237

198-
/* VGA clock */
238+
/* Let the synthesizer insert the appropriate buffers */
239+
assign eth_rx_clk = eth_rx_clk_pad;
240+
assign eth_tx_clk = eth_tx_clk_pad;
241+
242+
/*
243+
* VGA clock
244+
*/
245+
199246
// TODO: hook up the reprogramming interface
200247
DCM_CLKGEN #(
201248
.CLKFXDV_DIVIDE(2),

‎verilog/s6ddrphy/s6ddrphy.v

-34
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ module s6ddrphy #(
5959
output dfi_rddata_valid_w1,
6060

6161
/* DDR SDRAM pads */
62-
output sd_clk_out_p,
63-
output sd_clk_out_n,
6462
output reg [NUM_AD-1:0] sd_a,
6563
output reg [NUM_BA-1:0] sd_ba,
6664
output reg sd_cs_n,
@@ -73,38 +71,6 @@ module s6ddrphy #(
7371
inout [NUM_D/16-1:0] sd_dqs
7472
);
7573

76-
/*
77-
* SDRAM clock
78-
*/
79-
ODDR2 #(
80-
.DDR_ALIGNMENT("NONE"),
81-
.INIT(1'b0),
82-
.SRTYPE("SYNC")
83-
) sd_clk_forward_p (
84-
.Q(sd_clk_out_p),
85-
.C0(clk2x_270),
86-
.C1(~clk2x_270),
87-
.CE(1'b1),
88-
.D0(1'b1),
89-
.D1(1'b0),
90-
.R(1'b0),
91-
.S(1'b0)
92-
);
93-
ODDR2 #(
94-
.DDR_ALIGNMENT("NONE"),
95-
.INIT(1'b0),
96-
.SRTYPE("SYNC")
97-
) sd_clk_forward_n (
98-
.Q(sd_clk_out_n),
99-
.C0(clk2x_270),
100-
.C1(~clk2x_270),
101-
.CE(1'b1),
102-
.D0(1'b0),
103-
.D1(1'b1),
104-
.R(1'b0),
105-
.S(1'b0)
106-
);
107-
10874
/*
10975
* Command/address
11076
*/

0 commit comments

Comments
 (0)
Please sign in to comment.