track V1.2 pcb update

This commit is contained in:
Romain Dolbeau 2023-01-14 11:03:01 +01:00
parent 5585709334
commit 42c0a18371
6 changed files with 162 additions and 42 deletions

View File

@ -0,0 +1,13 @@
(
source /opt/Xilinx/Vivado/2020.1/settings64.sh
export LD_LIBRARY_PATH=/opt/Xilinx/Vivado/2020.1/lib/lnx64.o/SuSE
python3 nubus_to_fpga_soc.py --build --csr-csv csr.csv --csr-json csr.json --variant=ztex2.13a --version=V1.2 --sys-clk-freq 100e6 --goblin --goblin-res 1920x1080@60Hz --hdmi
#python3 nubus_to_fpga_soc.py --csr-csv csr.csv --csr-json csr.json --variant=ztex2.13a --version=V1.2 --sys-clk-freq 100e6
) 2>&1 | tee build_V1_2.log
# --goblin --goblin-res 1280x1024@60Hz
# --hdmi
grep -A10 'Design Timing Summary' build/ztex213_nubus_V1_2/gateware/ztex213_nubus_V1_2_timing.rpt

View File

@ -60,7 +60,11 @@ class NuBus(Module):
self.nubus_oe = nubus_oe = Signal() # improveme
# those are needed in both Nubus and cpld integrated part now
broadcast_id_3v3_n = platform.request("id_3v3_n")
raw_broadcast_id_3v3_n = platform.request("id_3v3_n")
broadcast_id_3v3_n = Signal(4)
self.comb += [
broadcast_id_3v3_n.eq(Cat(raw_broadcast_id_3v3_n, Signal(1, reset = 0))) # add missing ID3 in V1_2
]
# those are 'return' signals (O part of IO separated in I and O)
# the 3v3 signals 'see' the 5V signals from the external drivers
internal_start_3v3_n = Signal()

View File

@ -7,14 +7,14 @@ import litex
from litex.soc.interconnect import wishbone
class NuBus(Module):
def __init__(self, soc,
def __init__(self, soc, version,
burst_size, tosbus_fifo, fromsbus_fifo, fromsbus_req_fifo,
wb_read, wb_write, wb_dma,
usesampling=False,
cd_nubus="nubus", cd_nubus90="nubus90"):
platform = soc.platform
self.add_sources(platform)
self.add_sources(platform, version)
#led0 = platform.request("user_led", 0)
#led1 = platform.request("user_led", 1)
@ -714,54 +714,91 @@ class NuBus(Module):
# stuff at this end so we don't use the signals inadvertantly
# real NuBus signals
nub_tm0n = platform.request("tm0_3v3_n")
nub_tm1n = platform.request("tm1_3v3_n")
nub_startn = platform.request("start_3v3_n")
nub_ackn = platform.request("ack_3v3_n")
nub_adn = platform.request("ad_3v3_n")
nub_idn = platform.request("id_3v3_n")
nub_tm0n = platform.request("tm0_3v3_n") # V1.0: from CPLD ; V1.2: from shifters
nub_tm1n = platform.request("tm1_3v3_n") # V1.0: from CPLD ; V1.2: from shifters
nub_startn = platform.request("start_3v3_n") # V1.0: from CPLD ; V1.2: from shifters
nub_ackn = platform.request("ack_3v3_n") # V1.0: from CPLD ; V1.2: from shifters
nub_adn = platform.request("ad_3v3_n") # V1.0: from CPLD ; V1.2: from shifters
nub_idn = platform.request("id_3v3_n") # V1.0: from CPLD (4 bits) ; V1.2: from shifters (3 bits, /ID3 is always 0)
# Tri-state
self.specials += Tristate(nub_tm0n, tm0_o_n, tmo_oe, tm0_i_n)
self.specials += Tristate(nub_tm1n, tm1_o_n, tmo_oe, tm1_i_n)
self.specials += Tristate(nub_ackn, ack_o_n, tmo_oe, ack_i_n)
self.specials += Tristate(nub_adn, ad_o_n, ad_oe, ad_i_n)
self.specials += Tristate(nub_startn, start_o_n, master_oe, start_i_n)
self.comb += [
id_i_n.eq(nub_idn),
]
if (version == "V1.0"):
# tri-state communication with CPLD
self.specials += Tristate(nub_tm0n, tm0_o_n, tmo_oe, tm0_i_n)
self.specials += Tristate(nub_tm1n, tm1_o_n, tmo_oe, tm1_i_n)
self.specials += Tristate(nub_ackn, ack_o_n, tmo_oe, ack_i_n)
self.specials += Tristate(nub_adn, ad_o_n, ad_oe, ad_i_n)
self.specials += Tristate(nub_startn, start_o_n, master_oe, start_i_n)
elif (version == "V1.2"):
# input only
self.comb += [
tm0_i_n.eq(nub_tm0n),
tm1_i_n.eq(nub_tm1n),
ack_i_n.eq(nub_ackn),
ad_i_n.eq(nub_adn),
start_i_n.eq(nub_startn),
]
else:
raise ValueError(f"Unsupported version {version}")
# input only
if (version == "V1.0"):
self.comb += [
id_i_n.eq(nub_idn),
]
elif (version == "V1.2"):
self.comb += [
id_i_n.eq(Cat(nub_idn, Signal(1, reset = 0))),
]
else:
raise ValueError(f"Unsupported version {version}")
# NubusFPGA-only signals
nf_tmoen = platform.request("tmoen")
nf_nubus_ad_dir = platform.request("nubus_ad_dir")
nf_nubus_ad_dir = platform.request("nubus_ad_dir") # to drivers
self.comb += [
nf_tmoen.eq(~tmo_oe),
nf_nubus_ad_dir.eq(~ad_oe),
]
if (version == "V1.0"):
nf_tmoen = platform.request("tmoen") # to cpld
self.comb += [
nf_tmoen.eq(~tmo_oe),
]
# real Nubus signal, for master
nub_rqstn = platform.request("rqst_3v3_n")
nub_rqstn = platform.request("rqst_3v3_n") # V1.0: from CPLD ; V1.2: from shifters
# Tri-state
self.specials += Tristate(nub_rqstn, rqst_o_n, rqst_oe, rqst_i_n)
if (version == "V1.0"):
# tri-state communication with CPLD
self.specials += Tristate(nub_rqstn, rqst_o_n, rqst_oe, rqst_i_n)
elif (version == "V1.2"):
# input only
self.comb += [
rqst_i_n.eq(nub_rqstn),
]
else:
raise ValueError(f"Unsupported version {version}")
# NubusFPGA-only signals, for master
nub_arbcy_n = platform.request("arbcy_n")
nf_grant = platform.request("grant")
nf_nubus_master_dir = platform.request("nubus_master_dir")
nf_fpga_to_cpld_signal = platform.request("fpga_to_cpld_signal")
if (version == "V1.0"):
nub_arbcy_n = platform.request("arbcy_n") # V1.0: from cpld
nf_grant = platform.request("grant") # V1.0: from cpld
nf_nubus_master_dir = platform.request("nubus_master_dir") # V1.0: to cpld
nf_fpga_to_cpld_signal = platform.request("fpga_to_cpld_signal") # V1.0: to cpld, 'rqstoen'
# NuBus90 signals, , for completeness
nub_clk2xn = ClockSignal(cd_nubus90)
nub_tm2n = platform.request("tm2_3v3_n")
nub_tm2n = platform.request("tm2_3v3_n") # V1.0: from CPLD ; V1.2: from shifters
self.comb += [
nf_nubus_master_dir.eq(master_oe),
nub_arbcy_n.eq(~start_arbitration),
grant.eq(nf_grant),
nf_fpga_to_cpld_signal.eq(~rqst_oe),
]
if (version == "V1.0"):
self.comb += [
nf_nubus_master_dir.eq(master_oe),
nub_arbcy_n.eq(~start_arbitration),
grant.eq(nf_grant),
nf_fpga_to_cpld_signal.eq(~rqst_oe),
]
if (usesampling):
self.sync += [
@ -771,6 +808,50 @@ class NuBus(Module):
)
]
def add_sources(self, platform):
if (version == "V1.2"):
self.nubus_oe = nubus_oe = Signal() # improveme
self.specials += Instance("nubus_cpldinfpga",
i_nubus_oe = nubus_oe, # improveme: handled in soc
i_tmoen = ~tmo_oe,
i_nubus_master_dir = master_oe,
i_rqst_oe_n = ~rqst_oe,
i_id_n_3v3 = id_i_n, # input only
i_arbcy_n = ~start_arbitration,
i_arb_n_3v3 = platform.request("arb_3v3_n"), # arb only seen by cpld
o_arb_o_n = platform.request("arb_o_n"),
o_grant = grant,
i_tm0_n_3v3 = tm0_o_n, # tm0 driving controlled by tmoen
o_tm0_o_n = platform.request("tm0_o_n"),
i_tm1_n_3v3 = tm1_o_n, # tm1 driving controlled by tmoen
o_tm1_o_n = platform.request("tm1_o_n"),
o_tmx_oe_n = platform.request("tmx_oe_n"),
i_tm2_n_3v3 = nub_tm2n, # tm2 currently never driven
o_tm2_o_n = platform.request("tm2_o_n"),
o_tm2_oe_n = platform.request("tm2_oe_n"),
i_start_n_3v3 = start_o_n, # start driving enabled by nubus_master_dir
o_start_o_n = platform.request("start_o_n"),
o_start_oe_n = platform.request("start_oe_n"),
i_ack_n_3v3 = ack_o_n, # ack driving controlled by tmoen
o_ack_o_n = platform.request("ack_o_n"),
o_ack_oe_n = platform.request("ack_oe_n"),
i_rqst_n_3v3 = rqst_o_n, # rqst driving controller by rqst_oe_n
o_rqst_o_n = platform.request("rqst_o_n")
)
def add_sources(self, platform, version):
# sampling of data on falling edge of clock, done in verilog
platform.add_source("nubus_sampling.v", "verilog")
if (version == "V1.2"):
platform.add_source("nubus_arbiter.v", "verilog") # for CPLDinfpga
platform.add_source("nubus_cpldinfpga.v", "verilog") # internal now

View File

@ -42,7 +42,7 @@ from nubus_cpu_wb import Wishbone2NuBus
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq,
def __init__(self, platform, version, sys_clk_freq,
goblin=False,
hdmi=False,
pix_clk=0):
@ -74,6 +74,17 @@ class _CRG(Module):
self.specials += Instance("BUFG", i_I=clk48, o_O=self.clk48_bufg)
self.comb += self.cd_native.clk.eq(self.clk48_bufg)
#self.cd_native.clk = clk48
##### V1.2 extra clock for B34
if (version == "V1.2"):
self.clock_domains.cd_bank34 = ClockDomain()
clk54 = platform.request("clk54")
self.clk54_bufg = Signal()
self.specials += Instance("BUFG", i_I=clk54, o_O=self.clk54_bufg)
self.comb += self.cd_native.clk.eq(self.clk54_bufg)
else:
clk54 = None
clk_nubus = platform.request("clk_3v3_n")
if (clk_nubus is None):
@ -108,8 +119,8 @@ class _CRG(Module):
platform.add_platform_command("create_generated_clock -name sys4x90clk [get_pins {{{{MMCME2_ADV/CLKOUT{}}}}}]".format(num_clk))
num_clk = num_clk + 1
self.comb += pll.reset.eq(~rst_nubus_n) # | ~por_done
platform.add_false_path_constraints(self.cd_native.clk, self.cd_nubus.clk) # FIXME?
platform.add_false_path_constraints(self.cd_nubus.clk, self.cd_native.clk) # FIXME?
platform.add_false_path_constraints(clk48, self.cd_nubus.clk) # FIXME?
platform.add_false_path_constraints(self.cd_nubus.clk, clk48) # FIXME?
#platform.add_false_path_constraints(self.cd_sys.clk, self.cd_nubus.clk)
#platform.add_false_path_constraints(self.cd_nubus.clk, self.cd_sys.clk)
##platform.add_false_path_constraints(self.cd_native.clk, self.cd_sys.clk)
@ -130,7 +141,15 @@ class _CRG(Module):
if (goblin):
self.submodules.video_pll = video_pll = S7MMCM(speedgrade=platform.speedgrade)
video_pll.register_clkin(self.clk48_bufg, 48e6)
if (clk54 is None):
# no 54 MHz clock, drive hdmi from the main clock
video_pll.register_clkin(self.clk48_bufg, 48e6)
else:
# drive hdmi from the 54 MHz clock, easier to generate e.g. 148.5 MHz
video_pll.register_clkin(self.clk54_bufg, 54e6)
platform.add_false_path_constraints(self.cd_bank34.clk, self.cd_nubus.clk) # FIXME?
platform.add_false_path_constraints(self.cd_bank34.clk, clk48) # FIXME?
if (not hdmi):
video_pll.create_clkout(self.cd_vga, pix_clk, margin = 0.0005)
platform.add_platform_command("create_generated_clock -name vga_clk [get_pins {{{{MMCME2_ADV_{}/CLKOUT{}}}}}]".format(num_adv, num_clk))
@ -223,7 +242,7 @@ class NuBusFPGA(SoCCore):
#"END OF SLOT SPACE": 0xF0FFFFFF,
}
self.mem_map.update(wb_mem_map)
self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq, goblin=goblin, hdmi=hdmi, pix_clk=litex.soc.cores.video.video_timings[goblin_res]["pix_clk"])
self.submodules.crg = _CRG(platform=platform, version=version, sys_clk_freq=sys_clk_freq, goblin=goblin, hdmi=hdmi, pix_clk=litex.soc.cores.video.video_timings[goblin_res]["pix_clk"])
## add our custom timings after the clocks have been defined
xdc_timings_filename = None;
@ -404,6 +423,7 @@ class NuBusFPGA(SoCCore):
self.comb += dma_irq.eq(self.exchange_with_mem.irq)
self.submodules.nubus = nubus_full_unified.NuBus(soc=self,
version=version,
burst_size=burst_size,
tosbus_fifo=self.tosbus_fifo,
fromsbus_fifo=self.fromsbus_fifo,

View File

@ -101,6 +101,8 @@ _nubus_io_v1_0 = [
]
_nubus_io_v1_2 = [
## extra 54 MHz clock reference for bank 34
("clk54", 0, Pins("R3"), IOStandard("LVCMOS33")),
## leds on the NuBus board
("user_led", 0, Pins("U9"), IOStandard("lvcmos33")), #LED0
("user_led", 1, Pins("V9"), IOStandard("lvcmos33")), #LED1; both are overlapping with serial TX/RX
@ -179,7 +181,7 @@ _nubus_nubus_v1_2 = [
("ack_o_n", 0, Pins("H14"), IOStandard("lvttl")),
("ack_oe_n", 0, Pins("J13"), IOStandard("lvttl")),
("nmrq_3v3_n", 0, Pins("K16"), IOStandard("lvttl")), # 'irq' line, Output only direct to 74LVT125
("reset_3v3_n", 0, Pins("R3"), IOStandard("lvttl")), # Input only
("reset_3v3_n", 0, Pins("U8"), IOStandard("lvttl")), # Input only
("rqst_3v3_n" , 0, Pins("J18"), IOStandard("lvttl")), # Open Collector
("rqst_o_n" , 0, Pins("K13"), IOStandard("lvttl")),
("start_3v3_n", 0, Pins("K15"), IOStandard("lvttl")),
@ -191,7 +193,7 @@ _nubus_nubus_v1_2 = [
"D17 D18 E17 E18 F15 F18 F16 G18 "), IOStandard("lvttl")),
("arb_3v3_n", 0, Pins("T8 V4 V5 U6"), IOStandard("lvttl")), # Open Collector
("arb_o_n", 0, Pins("J14 G16 G14 H17"), IOStandard("lvttl")),
("id_3v3_n", 0, Pins("U7 V6 V7 U8"), IOStandard("lvttl")),
("id_3v3_n", 0, Pins("U7 V6 V7"), IOStandard("lvttl")),
("tm0_3v3_n", 0, Pins("U2"), IOStandard("lvttl")),
("tm0_o_n", 0, Pins("T6"), IOStandard("lvttl")),
("tm1_3v3_n", 0, Pins("V2"), IOStandard("lvttl")),