mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-12-21 04:29:33 +00:00
'alt' hdmi from framebuffer, ROM config from gateware, settable pixel clock for non-alt hdmi
This commit is contained in:
parent
824806768a
commit
4baf007f31
@ -1 +1 @@
|
||||
Subproject commit 06c4327335c34b0adaac18f9a3dc9c1badc19953
|
||||
Subproject commit 76527c00d957379c1111d6899516f1f90ef2f63b
|
@ -4,8 +4,12 @@
|
||||
source /opt/Xilinx/Vivado/2023.2/settings64.sh
|
||||
export LD_LIBRARY_PATH=/opt/Xilinx/Vivado/2023.2/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 --goblin-alt --hdmi --config-flash # --ethernet # --sdcard # --flash
|
||||
|
||||
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 --config-flash # --ethernet # --sdcard # --flash
|
||||
|
||||
#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 1280x1024@60Hz --hdmi --config-flash # --ethernet # --sdcard # --flash
|
||||
|
||||
#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
|
||||
|
@ -11,6 +11,8 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
|
||||
div_clk_begin = 39
|
||||
div_clk_half = 20
|
||||
|
||||
div_clk_state_change = 2
|
||||
|
||||
sig_mdc = platform.request("sep_mdc");
|
||||
sig_mdio = platform.request("sep_mdio");
|
||||
@ -100,7 +102,7 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
in_preamble.eq(0),
|
||||
mdio_oe.eq(0), # don't drive
|
||||
#mdio_oe.eq(1), # drive 0 at idle ?
|
||||
If(cmd_recv & (clk_div == 2), # CHECKME
|
||||
If(cmd_recv & (clk_div == div_clk_state_change), # CHECKME
|
||||
NextValue(cmd_recv, 0),
|
||||
NextValue(write, mdio_command.fields.write),
|
||||
|
||||
@ -125,7 +127,7 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
mdio_fsm.act("Preamble",
|
||||
in_preamble.eq(1),
|
||||
mdio_oe.eq(1),
|
||||
If(clk_div == 2, # CHECKME
|
||||
If(clk_div == div_clk_state_change, # CHECKME
|
||||
If(int_cnt == 0,
|
||||
NextValue(int_cnt, 31),
|
||||
in_preamble.eq(0), # switch mdio_o to MSb of output_data
|
||||
@ -144,12 +146,12 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
mdio_fsm.act("WData",
|
||||
in_preamble.eq(0),
|
||||
mdio_oe.eq(1),
|
||||
If(clk_div == 2,
|
||||
If(clk_div == div_clk_state_change,
|
||||
shift_od.eq(1), # so during clk_div == 1, output will move to the next bit
|
||||
NextValue(int_cnt, int_cnt - 1),
|
||||
If(int_cnt == 0,
|
||||
mdio_o.eq(1), # help pull-ups
|
||||
mdio_oe.eq(0), # stop driving
|
||||
# mdio_oe.eq(0), # stop driving
|
||||
NextValue(output_data, 0), # make sure it's zero
|
||||
NextState("Idle"), ## fixme: delay to idle by one MDC clok cycle?
|
||||
)
|
||||
@ -159,11 +161,11 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
mdio_fsm.act("RData",
|
||||
in_preamble.eq(0),
|
||||
mdio_oe.eq(1),
|
||||
If(clk_div == 2,
|
||||
shift_od.eq(1), # so during clk_div == 2, output will move to the next bit
|
||||
If(clk_div == div_clk_state_change,
|
||||
shift_od.eq(1), # so during clk_div == div_clk_state_change, output will move to the next bit
|
||||
NextValue(int_cnt, int_cnt - 1),
|
||||
If(int_cnt == 18,
|
||||
#mdio_o.eq(1), # help pull-ups
|
||||
mdio_o.eq(1), # help pull-ups
|
||||
#mdio_oe.eq(0), # stop driving during TA
|
||||
NextState("TA"),
|
||||
)
|
||||
@ -172,7 +174,8 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
|
||||
mdio_fsm.act("TA",
|
||||
mdio_oe.eq(0),
|
||||
If(clk_div == 2,
|
||||
If(clk_div == div_clk_state_change,
|
||||
# mdio_oe.eq(0), # stop driving
|
||||
NextValue(rdata[15], mdio_i), # DEBUG, will capture on 17 and 16, will be flushed by shifting
|
||||
shift_rd.eq(1), # DEBUG, shift in 2 cycles to make room
|
||||
NextValue(int_cnt, int_cnt - 1),
|
||||
@ -185,10 +188,12 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
|
||||
mdio_fsm.act("Capture",
|
||||
mdio_oe.eq(0),
|
||||
If(clk_div == 2,
|
||||
If(clk_div == div_clk_state_change,
|
||||
NextValue(rdata[15], mdio_i),
|
||||
NextValue(int_cnt, int_cnt - 1),
|
||||
If(int_cnt == 0,
|
||||
mdio_oe.eq(0),
|
||||
mdio_o.eq(1), # help pull-ups
|
||||
NextState("Idle"),
|
||||
).Else(
|
||||
shift_rd.eq(1), # shift in 2 cycles to make room
|
||||
@ -196,10 +201,10 @@ class MDIOCtrl(Module, AutoCSR):
|
||||
),
|
||||
)
|
||||
|
||||
led0 = platform.request("user_led", 0)
|
||||
led1 = platform.request("user_led", 1)
|
||||
|
||||
self.comb += [
|
||||
led0.eq(~mdio_fsm.ongoing("Idle")),
|
||||
#led1.eq(clk_div != 0),
|
||||
]
|
||||
#led0 = platform.request("user_led", 0)
|
||||
#led1 = platform.request("user_led", 1)
|
||||
#
|
||||
#self.comb += [
|
||||
# led0.eq(~mdio_fsm.ongoing("Idle")),
|
||||
# #led1.eq(clk_div != 0),
|
||||
#]
|
||||
|
@ -37,7 +37,7 @@ from nubus_memfifo_wb import NuBus2WishboneFIFO
|
||||
from nubus_cpu_wb import Wishbone2NuBus
|
||||
|
||||
# CRG ----------------------------------------------------------------------------------------------
|
||||
class _CRG(Module):
|
||||
class _CRG(Module, AutoCSR): # AutoCSR for DRP
|
||||
def __init__(self, platform, version, sys_clk_freq,
|
||||
goblin=False,
|
||||
hdmi=False,
|
||||
@ -101,7 +101,7 @@ class _CRG(Module):
|
||||
assert(false)
|
||||
self.cd_nubus90.clk = clk2x_nubus
|
||||
self.comb += self.cd_nubus90.rst.eq(~rst_nubus_n)
|
||||
platform.add_platform_command("create_clock -name nubus90_clk -period 50.0 -waveform {{0.0 37.5}} [get_ports clk2x_3v3_n]")
|
||||
platform.add_platform_command("create_clock -name nubus90_clk -period 50.0 -waveform {{0.0 25}} [get_ports clk2x_3v3_n]")
|
||||
|
||||
num_adv = 0
|
||||
num_clk = 0
|
||||
@ -119,7 +119,7 @@ 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
|
||||
if (ethernet):
|
||||
pll.create_clkout(self.cd_eth, 50e6, phase=90) # fixme: what if sys_clk_feq != 100e6?
|
||||
pll.create_clkout(self.cd_eth, 50e6, phase=90) # fixme: what if sys_clk_feq != 100e6? # why phase ???
|
||||
platform.add_platform_command("create_generated_clock -name ethclk [get_pins {{{{MMCME2_ADV/CLKOUT{}}}}}]".format(num_clk))
|
||||
num_clk = num_clk + 1
|
||||
|
||||
@ -166,6 +166,8 @@ class _CRG(Module):
|
||||
num_clk = num_clk + 1
|
||||
platform.add_platform_command("create_generated_clock -name hdmi5x_clk [get_pins {{{{MMCME2_ADV_{}/CLKOUT{}}}}}]".format(num_adv, num_clk))
|
||||
num_clk = num_clk + 1
|
||||
video_pll.expose_drp()
|
||||
|
||||
|
||||
self.comb += video_pll.reset.eq(~rst_nubus_n)
|
||||
#platform.add_false_path_constraints(self.cd_sys.clk, self.cd_vga.clk)
|
||||
@ -176,7 +178,7 @@ class _CRG(Module):
|
||||
|
||||
|
||||
class NuBusFPGA(MacPeriphSoC):
|
||||
def __init__(self, variant, version, sys_clk_freq, goblin, hdmi, goblin_res, sdcard, flash, config_flash, ethernet, **kwargs):
|
||||
def __init__(self, variant, version, sys_clk_freq, goblin, hdmi, goblin_res, use_goblin_alt, sdcard, flash, config_flash, ethernet, **kwargs):
|
||||
print(f"Building NuBusFPGA for board version {version}")
|
||||
|
||||
self.platform = platform = ztex213_nubus.Platform(variant = variant, version = version)
|
||||
@ -186,8 +188,6 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
|
||||
if (ethernet and (version == "V1.2")):
|
||||
platform.add_extension(ztex213_nubus._rmii_eth_extpmod_io_v1_2)
|
||||
|
||||
use_goblin_alt = True
|
||||
|
||||
MacPeriphSoC.__init__(self,
|
||||
platform=platform,
|
||||
@ -380,7 +380,7 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
if (goblin):
|
||||
MacPeriphSoC.mac_add_goblin(self, use_goblin_alt = use_goblin_alt, hdmi = hdmi, goblin_res = goblin_res, goblin_irq = fb_irq, audio_irq = audio_irq)
|
||||
|
||||
if (sdcard):
|
||||
if (sdcard): ### WIP WIP WIP WIP
|
||||
self.add_sdcard()
|
||||
# irq?
|
||||
|
||||
@ -388,14 +388,13 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
# we need the CRG to provide the cd_eth clock: "use refclk_cd as RMII reference clock (provided by user design) (no external clock).
|
||||
self.ethphy = LiteEthPHYRMII(
|
||||
clock_pads = self.platform.request("eth_clocks"),
|
||||
#clock_pads = None,
|
||||
pads = self.platform.request("eth"))
|
||||
self.add_ethernet(phy=self.ethphy, data_width = 32)
|
||||
print(f"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% {self.ethmac.interface.sram.ev.irq}") # FIXME HANDLEME
|
||||
|
||||
from mdio import MDIOCtrl
|
||||
self.submodules.mdio_ctrl = MDIOCtrl(platform=platform)
|
||||
|
||||
|
||||
# for testing
|
||||
if (False):
|
||||
from nubus_master_tst import PingMaster
|
||||
@ -411,7 +410,8 @@ def main():
|
||||
parser.add_argument("--sys-clk-freq", default=100e6, help="NuBusFPGA system clock (default 100e6 = 100 MHz)")
|
||||
parser.add_argument("--goblin", action="store_true", help="add a goblin framebuffer")
|
||||
parser.add_argument("--hdmi", action="store_true", help="The framebuffer uses HDMI (default to VGA, required for V1.2)")
|
||||
parser.add_argument("--goblin-res", default="640x480@60Hz", help="Specify the goblin resolution")
|
||||
parser.add_argument("--goblin-res", default="1920x1080@60Hz", help="Specify the goblin resolution")
|
||||
parser.add_argument("--goblin-alt", action="store_true", help="Use alternate HDMI Phy with Audio support (requires Full HD resolution)")
|
||||
parser.add_argument("--sdcard", action="store_true", help="add a sdcard controller (V1.2 only)")
|
||||
parser.add_argument("--flash", action="store_true", help="add a Flash device [V1.2+FLASHTEMP PMod] and configure the ROM to it")
|
||||
parser.add_argument("--config-flash", action="store_true", help="Configure the ROM to the internal Flash used for FPGA config")
|
||||
@ -439,10 +439,39 @@ def main():
|
||||
if ((not args.hdmi) and (args.version == "V1.2")):
|
||||
print(" ***** ERROR ***** : VGA not supported on V1.2\n");
|
||||
assert(False)
|
||||
|
||||
if ((not args.hdmi) and args.goblin_alt):
|
||||
print(" ***** ERROR ***** : VGA and Goblin Alt PHY don't make sense\n");
|
||||
assert(False)
|
||||
|
||||
if (args.config_flash and args.flash):
|
||||
print(" ***** ERROR ***** : ROM-in-Flash can only use config OR PMod, not both\n");
|
||||
assert(False)
|
||||
|
||||
if (args.goblin_alt and (args.goblin_res != "1920x1080@60Hz")):
|
||||
print(" ***** ERROR ***** : Goblin Alt PHY currently only supports Full HD\n");
|
||||
assert(False)
|
||||
|
||||
if (True):
|
||||
f = open("decl_rom_config.mak","w+")
|
||||
hres = int(args.goblin_res.split("@")[0].split("x")[0])
|
||||
vres = int(args.goblin_res.split("@")[0].split("x")[1])
|
||||
f.write("TARGET=NUBUSFPGA\n")
|
||||
f.write("FEATURES+= -DNUBUSFPGA")
|
||||
f.write(" -DENABLE_RAMDSK") # only NuBusFPGA for now
|
||||
if (args.goblin_alt):
|
||||
f.write(" -DENABLE_HDMIAUDIO") # no audio in litex-style not-hdmi phy
|
||||
else:
|
||||
f.write(" -DENABLE_HDMI_ALT_CHANGE");
|
||||
if (args.version == "V1.0"):
|
||||
f.write(" -DENABLE_HDMI_ALT_CHANGE_48MHZ");
|
||||
elif (args.version == "V1.2"):
|
||||
f.write(" -DENABLE_HDMI_ALT_CHANGE_54MHZ");
|
||||
|
||||
f.write("\n");
|
||||
f.write(f"HRES={hres}\n");
|
||||
f.write(f"VRES={vres}\n");
|
||||
f.close()
|
||||
|
||||
soc = NuBusFPGA(**soc_core_argdict(args),
|
||||
variant=args.variant,
|
||||
@ -451,6 +480,7 @@ def main():
|
||||
goblin=args.goblin,
|
||||
hdmi=args.hdmi,
|
||||
goblin_res=args.goblin_res,
|
||||
use_goblin_alt=args.goblin_alt,
|
||||
sdcard=args.sdcard,
|
||||
flash=args.flash,
|
||||
config_flash=args.config_flash,
|
||||
|
Loading…
Reference in New Issue
Block a user