mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-09-28 17:55:30 +00:00
Compare commits
No commits in common. "79f6954a7ef9fe003501c52189f7b27c08b53ffc" and "86a6afbd39d5518284c81f1f4c99ec78992f6ce5" have entirely different histories.
79f6954a7e
...
86a6afbd39
@ -1 +1 @@
|
||||
Subproject commit 06c4327335c34b0adaac18f9a3dc9c1badc19953
|
||||
Subproject commit 0de12910a247bd96f3e90db971de137c6e5ffa43
|
@ -1,205 +0,0 @@
|
||||
from migen import *
|
||||
from migen.genlib.fifo import *
|
||||
from migen.fhdl.specials import Tristate
|
||||
|
||||
from litex.soc.interconnect.csr import *
|
||||
|
||||
import litex
|
||||
|
||||
class MDIOCtrl(Module, AutoCSR):
|
||||
def __init__(self, platform):
|
||||
|
||||
div_clk_begin = 39
|
||||
div_clk_half = 20
|
||||
|
||||
sig_mdc = platform.request("sep_mdc");
|
||||
sig_mdio = platform.request("sep_mdio");
|
||||
mdio_o = Signal()
|
||||
mdio_oe = Signal()
|
||||
mdio_i = Signal()
|
||||
|
||||
clk_div = Signal(log2_int(div_clk_begin, False))
|
||||
int_cnt = Signal(log2_int(32))
|
||||
rdata = Signal(32) # DEBUG, should be 16, FIXME
|
||||
cmd_recv = Signal()
|
||||
|
||||
self.specials += Tristate(sig_mdio, mdio_o, mdio_oe, mdio_i)
|
||||
|
||||
self.reg_addr = reg_addr = CSRStorage(fields = [CSRField("reg_addr", 5, description = "Reg Addr"),
|
||||
CSRField("reserved", 27, description = "Reserved"),])
|
||||
self.phy_addr = phy_addr = CSRStorage(fields = [CSRField("phy_addr", 5, description = "Phy Addr"),
|
||||
CSRField("reserved", 27, description = "Reserved"),])
|
||||
self.mdio_command = mdio_command = CSRStorage(fields = [CSRField("read", 1, description = "Read"),
|
||||
CSRField("write", 1, description = "write"),
|
||||
CSRField("reserved", 30, description = "Reserved"),])
|
||||
self.mdio_status = mdio_status = CSRStatus(fields = [CSRField("access_complete", 1, description = "Phy Addr"),
|
||||
CSRField("busy", 1, description = "busy"),
|
||||
CSRField("reserved", 30, description = "Reserved"),])
|
||||
self.mdio_write = mdio_write = CSRStorage(fields = [CSRField("val", 16, description = "writeval"),
|
||||
CSRField("reserved", 16, description = "Reserved"),])
|
||||
#self.mdio_read = mdio_read = CSRStatus(fields = [CSRField("val", 16, description = "readval"),
|
||||
# CSRField("reserved", 16, description = "Reserved"),])
|
||||
self.mdio_read = mdio_read = CSRStatus(fields = [CSRField("val", 32, description = "readval"),]) # DEBUG, should be 16, FIXME
|
||||
|
||||
self.submodules.wishbone_fsm = mdio_fsm = FSM(reset_state = "Reset")
|
||||
|
||||
self.comb += [
|
||||
mdio_status.fields.access_complete.eq(mdio_fsm.ongoing("Idle")),
|
||||
mdio_status.fields.busy.eq(cmd_recv),
|
||||
mdio_read.fields.val.eq(rdata),
|
||||
]
|
||||
|
||||
output_data = Signal(32)
|
||||
in_preamble = Signal()
|
||||
shift_od = Signal()
|
||||
self.sync += [
|
||||
If(shift_od,
|
||||
output_data.eq(Cat(Signal(1, reset = 0), output_data[0:31])),
|
||||
),
|
||||
]
|
||||
self.comb += [
|
||||
#If(in_preamble,
|
||||
# mdio_o.eq(1),
|
||||
#).Else(
|
||||
# mdio_o.eq(output_data[31]),
|
||||
#),
|
||||
mdio_o.eq(in_preamble | output_data[31]),
|
||||
]
|
||||
shift_rd = Signal()
|
||||
shift_rd2 = Signal()
|
||||
self.sync += [
|
||||
shift_rd2.eq(shift_rd), # delay by one cycle
|
||||
If(shift_rd2,
|
||||
output_data.eq(Cat(rdata[1:32], Signal(1, reset = 0))), # DEBUG, should be 16, FIXME
|
||||
),
|
||||
]
|
||||
|
||||
mdc = Signal()
|
||||
self.comb += [ sig_mdc.eq(mdc), ]
|
||||
self.sync += [
|
||||
If(clk_div == 0,
|
||||
clk_div.eq(div_clk_begin),
|
||||
mdc.eq(1),
|
||||
).Else(
|
||||
If(clk_div == div_clk_half,
|
||||
mdc.eq(0),
|
||||
),
|
||||
clk_div.eq(clk_div - 1),
|
||||
),
|
||||
If(mdio_command.re,
|
||||
cmd_recv.eq(1),
|
||||
),
|
||||
]
|
||||
|
||||
write = Signal()
|
||||
|
||||
mdio_fsm.act("Reset",
|
||||
NextState("Idle")
|
||||
)
|
||||
mdio_fsm.act("Idle",
|
||||
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
|
||||
NextValue(cmd_recv, 0),
|
||||
NextValue(write, mdio_command.fields.write),
|
||||
|
||||
NextValue(output_data[0:16], mdio_write.fields.val),
|
||||
NextValue(output_data[16:18], 0x2), # TA
|
||||
NextValue(output_data[18:23], reg_addr.fields.reg_addr),
|
||||
NextValue(output_data[23:28], phy_addr.fields.phy_addr),
|
||||
If(mdio_command.fields.write,
|
||||
NextValue(output_data[28:30], 0x1), # write
|
||||
).Else(
|
||||
NextValue(output_data[28:30], 0x2), # read
|
||||
NextValue(rdata, 0xFFFFFFFF),
|
||||
),
|
||||
NextValue(output_data[30:32], 0x1), # start
|
||||
in_preamble.eq(1),
|
||||
mdio_oe.eq(1),
|
||||
NextValue(int_cnt, 31),
|
||||
NextState("Preamble"),
|
||||
)
|
||||
)
|
||||
|
||||
mdio_fsm.act("Preamble",
|
||||
in_preamble.eq(1),
|
||||
mdio_oe.eq(1),
|
||||
If(clk_div == 2, # CHECKME
|
||||
If(int_cnt == 0,
|
||||
NextValue(int_cnt, 31),
|
||||
in_preamble.eq(0), # switch mdio_o to MSb of output_data
|
||||
If(write,
|
||||
NextState("WData"),
|
||||
).Else(
|
||||
NextState("RData"),
|
||||
),
|
||||
).Else(
|
||||
NextValue(int_cnt, int_cnt - 1),
|
||||
NextState("Preamble"),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
mdio_fsm.act("WData",
|
||||
in_preamble.eq(0),
|
||||
mdio_oe.eq(1),
|
||||
If(clk_div == 2,
|
||||
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
|
||||
NextValue(output_data, 0), # make sure it's zero
|
||||
NextState("Idle"), ## fixme: delay to idle by one MDC clok cycle?
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
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
|
||||
NextValue(int_cnt, int_cnt - 1),
|
||||
If(int_cnt == 18,
|
||||
#mdio_o.eq(1), # help pull-ups
|
||||
#mdio_oe.eq(0), # stop driving during TA
|
||||
NextState("TA"),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
mdio_fsm.act("TA",
|
||||
mdio_oe.eq(0),
|
||||
If(clk_div == 2,
|
||||
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),
|
||||
If(int_cnt == 16,
|
||||
NextValue(output_data, 0), # make sure it's zero
|
||||
NextState("Capture"),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
mdio_fsm.act("Capture",
|
||||
mdio_oe.eq(0),
|
||||
If(clk_div == 2,
|
||||
NextValue(rdata[15], mdio_i),
|
||||
NextValue(int_cnt, int_cnt - 1),
|
||||
If(int_cnt == 0,
|
||||
NextState("Idle"),
|
||||
).Else(
|
||||
shift_rd.eq(1), # shift in 2 cycles to make room
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
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),
|
||||
]
|
@ -19,6 +19,9 @@ import nubus_to_fpga_export
|
||||
import nubus_full_unified
|
||||
import nubus_stat
|
||||
|
||||
from litedram.modules import MT41J128M16
|
||||
from litedram.phy import s7ddrphy
|
||||
|
||||
from litedram.frontend.dma import *
|
||||
|
||||
from liteeth.phy.rmii import LiteEthPHYRMII
|
||||
@ -26,11 +29,15 @@ from liteeth.phy.rmii import LiteEthPHYRMII
|
||||
from migen.genlib.cdc import BusSynchronizer
|
||||
from migen.genlib.resetsync import AsyncResetSynchronizer
|
||||
|
||||
from litex.soc.cores.video import VideoS7HDMIPHY
|
||||
from litex.soc.cores.video import VideoVGAPHY
|
||||
from litex.soc.cores.video import video_timings
|
||||
from VintageBusFPGA_Common.goblin_accel import *
|
||||
|
||||
# Wishbone stuff
|
||||
from VintageBusFPGA_Common.cdc_wb import WishboneDomainCrossingMaster
|
||||
from VintageBusFPGA_Common.fpga_blk_dma import *
|
||||
from VintageBusFPGA_Common.fpga_sd_dma import *
|
||||
from VintageBusFPGA_Common.MacPeriphSoC import *
|
||||
|
||||
from nubus_mem_wb import NuBus2Wishbone
|
||||
from nubus_memfifo_wb import NuBus2WishboneFIFO
|
||||
@ -175,10 +182,35 @@ class _CRG(Module):
|
||||
|
||||
|
||||
|
||||
class NuBusFPGA(MacPeriphSoC):
|
||||
class NuBusFPGA(SoCCore): # Add SDCard -----------------------------------------------------------------------------------
|
||||
# WiP
|
||||
def add_sdcard_custom(self, name="sdcard", mode="read+write"):
|
||||
# Imports.
|
||||
from litesdcard.phy import SDPHY
|
||||
from litesdcard.core import SDCore
|
||||
|
||||
# Checks.
|
||||
assert mode in ["read", "write", "read+write"]
|
||||
|
||||
# Pads.
|
||||
sdcard_pads = self.platform.request(name)
|
||||
|
||||
# Core.
|
||||
self.check_if_exists("sdphy")
|
||||
self.check_if_exists("sdcore")
|
||||
self.sdphy = SDPHY(sdcard_pads, self.platform.device, self.clk_freq, cmd_timeout=10e-1, data_timeout=10e-1)
|
||||
self.sdcore = SDCore(self.sdphy)
|
||||
|
||||
def __init__(self, variant, version, sys_clk_freq, goblin, hdmi, goblin_res, sdcard, flash, config_flash, ethernet, **kwargs):
|
||||
print(f"Building NuBusFPGA for board version {version}")
|
||||
|
||||
kwargs["cpu_type"] = "None"
|
||||
kwargs["integrated_sram_size"] = 0
|
||||
kwargs["with_uart"] = False
|
||||
kwargs["with_timer"] = False
|
||||
|
||||
self.sys_clk_freq = sys_clk_freq
|
||||
|
||||
self.platform = platform = ztex213_nubus.Platform(variant = variant, version = version)
|
||||
|
||||
if (flash and (version == "V1.2")):
|
||||
@ -188,20 +220,69 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
platform.add_extension(ztex213_nubus._rmii_eth_extpmod_io_v1_2)
|
||||
|
||||
use_goblin_alt = True
|
||||
if ((not use_goblin_alt) or (not hdmi)):
|
||||
from VintageBusFPGA_Common.goblin_fb import goblin_rounded_size, Goblin
|
||||
else:
|
||||
from VintageBusFPGA_Common.goblin_alt_fb import goblin_rounded_size, GoblinAlt
|
||||
|
||||
MacPeriphSoC.__init__(self,
|
||||
if (goblin):
|
||||
hres = int(goblin_res.split("@")[0].split("x")[0])
|
||||
vres = int(goblin_res.split("@")[0].split("x")[1])
|
||||
goblin_fb_size = goblin_rounded_size(hres, vres)
|
||||
print(f"Reserving {goblin_fb_size} bytes ({goblin_fb_size//1048576} MiB) for the goblin")
|
||||
else:
|
||||
hres = 0
|
||||
vres = 0
|
||||
goblin_fb_size = 0
|
||||
# litex.soc.cores.video.video_timings.update(goblin_timings)
|
||||
|
||||
SoCCore.__init__(self,
|
||||
platform=platform,
|
||||
sys_clk_freq=sys_clk_freq,
|
||||
clk_freq=sys_clk_freq,
|
||||
csr_paging=0x800, # default is 0x800
|
||||
bus_interconnect = "crossbar",
|
||||
goblin = goblin,
|
||||
hdmi = hdmi,
|
||||
goblin_res = goblin_res,
|
||||
use_goblin_alt = use_goblin_alt,
|
||||
**kwargs)
|
||||
|
||||
self.mem_map.update(self.wb_mem_map)
|
||||
|
||||
# Quoting the doc:
|
||||
# * Separate address spaces are reserved for processor access to cards in NuBus slots. For a
|
||||
# * device in NuBus slot number s, the address space in 32-bit mode begins at address
|
||||
# * $Fs00 0000 and continues through the highest address, $FsFF FFFF (where s is a constant in
|
||||
# * the range $9 through $E for the Macintosh II, the Macintosh IIx, and the Macintosh IIfx;
|
||||
# * $A through $E for the Macintosh Quadra 900; $9 through $B for the Macintosh IIcx;
|
||||
# * $C through $E for the Macintosh IIci; $D and $E for the Macintosh Quadra 700; and
|
||||
# * $9 for the Macintosh IIsi).
|
||||
# the Q650 is $C through $E like the IIci, $E is the one with the PDS.
|
||||
# So at best we get 16 MiB in 32-bits mode, unless using "super slot space"
|
||||
# in 24 bits it's only one megabyte, $s0 0000 through $sF FFFF
|
||||
# they are translated: '$s0 0000-$sF FFFF' to '$Fs00 0000-$Fs0F FFFF' (for s in range $9 through $E)
|
||||
# let's assume we have 32-bits mode, this can be requested in the DeclROM apparently
|
||||
self.wb_mem_map = wb_mem_map = {
|
||||
# master to map the NuBus access to RAM
|
||||
"master": 0x00000000, # to 0x3FFFFFFF
|
||||
"main_ram": 0x80000000, # not directly reachable from NuBus
|
||||
"video_framebuffer": 0x80000000 + 0x10000000 - goblin_fb_size, # Updated later
|
||||
# map everything in slot 0, remapped from the real slot in NuBus2Wishbone
|
||||
"goblin_mem": 0xF0000000, # up to 8 MiB of FB memory
|
||||
#"END OF FIRST MB" : 0xF00FFFFF,
|
||||
#"END OF 8 MB": 0xF07FFFFF,
|
||||
"goblin_bt" : 0xF0900000, # BT for goblin (regs)
|
||||
"goblin_accel" : 0xF0901000, # accel for goblin (regs)
|
||||
"goblin_accel_ram" : 0xF0902000, # accel for goblin (scratch ram)
|
||||
"stat" : 0xF0903000, # stat
|
||||
"goblin_accel_rom" : 0xF0910000, # accel for goblin (rom)
|
||||
"goblin_audio_ram" : 0xF0920000, # audio for goblin (RAM buffers)
|
||||
"csr" : 0xF0A00000, # CSR
|
||||
"pingmaster": 0xF0B00000,
|
||||
"ethmac": 0xF0C00000,
|
||||
#"spiflash": 0xF0D00000, # testing
|
||||
#"config_spiflash": 0xF0D00000, # testing
|
||||
"rom": 0xF0FF8000, # ROM at the end (32 KiB of it ATM)
|
||||
"spiflash": 0xF0FF8000, # FIXME currently the flash is in the ROM spot, limited to 32 KiB
|
||||
"config_spiflash": 0xF0FF8000, # FIXME currently the flash is in the ROM spot, limited to 32 KiB
|
||||
#"END OF SLOT SPACE": 0xF0FFFFFF,
|
||||
}
|
||||
self.mem_map.update(wb_mem_map)
|
||||
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"], ethernet=ethernet)
|
||||
|
||||
## add our custom timings after the clocks have been defined
|
||||
@ -221,12 +302,83 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
#print(fix_line)
|
||||
platform.add_platform_command(fix_line)
|
||||
|
||||
MacPeriphSoC.mac_add_declrom(self, version = version, flash = flash, config_flash = config_flash)
|
||||
if ((not flash) and (not config_flash)): # so ROM is builtin
|
||||
rom_file = "rom_{}.bin".format(version.replace(".", "_"))
|
||||
rom_data = soc_core.get_mem_data(filename_or_regions=rom_file, endianness="little") # "big"
|
||||
# rom = Array(rom_data)
|
||||
#print("\n****************************************\n")
|
||||
#for i in range(len(rom)):
|
||||
# print(hex(rom[i]))
|
||||
#print("\n****************************************\n")
|
||||
self.add_ram("rom", origin=self.mem_map["rom"], size=2**15, contents=rom_data, mode="r") ## 32 KiB, must match mmap
|
||||
print("$$$$$ ROM must be pre-existing for integration in the bitstream, double-check the ROM file is current for this configuration $$$$$\n");
|
||||
|
||||
MacPeriphSoC.mac_add_sdram(self, hwinit = False)
|
||||
if (flash):
|
||||
from litespi.modules.generated_modules import W25Q128JV
|
||||
from litespi.opcodes import SpiNorFlashOpCodes as Codes
|
||||
self.add_spi_flash(mode="4x",
|
||||
clk_freq = sys_clk_freq/4, # Fixme; PHY freq ?
|
||||
module=W25Q128JV(Codes.READ_1_1_4),
|
||||
region_size = 0x00008000, # 32 KiB
|
||||
with_mmap=True, with_master=False)
|
||||
print("$$$$$ ROM must be put in the external Flash NOR $$$$$\n");
|
||||
|
||||
|
||||
if (config_flash):
|
||||
sector = 40
|
||||
from litespi.modules.generated_modules import S25FL128S
|
||||
from litespi.opcodes import SpiNorFlashOpCodes as Codes
|
||||
self.add_spi_flash(name="config_spiflash",
|
||||
mode="1x",
|
||||
clk_freq = sys_clk_freq/4, # Fixme; PHY freq ?
|
||||
module=S25FL128S(Codes.READ_1_1_1),
|
||||
region_size = 0x00008000, # 32 KiB,
|
||||
region_offset = (sector * 65536),
|
||||
with_mmap=True, with_master=False)
|
||||
print(f"$$$$$ ROM must be put in the config Flash at sector {sector} $$$$$\n");
|
||||
|
||||
#from wb_test import WA2D
|
||||
#self.submodules.wa2d = WA2D(self.platform)
|
||||
#self.bus.add_slave("WA2D", self.wa2d.bus, SoCRegion(origin=0x00C00000, size=0x00400000, cached=False))
|
||||
|
||||
# notsimul to signify we're making a real bitstream
|
||||
# notsimul == False only to produce a verilog implementation to simulate the bus side of things
|
||||
notsimul = True
|
||||
if (notsimul):
|
||||
avail_sdram = 0
|
||||
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
|
||||
memtype = "DDR3",
|
||||
nphases = 4,
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
self.add_sdram("sdram",
|
||||
phy = self.ddrphy,
|
||||
module = MT41J128M16(sys_clk_freq, "1:4"),
|
||||
l2_cache_size = 0,
|
||||
)
|
||||
avail_sdram = self.bus.regions["main_ram"].size
|
||||
#from sdram_init import DDR3FBInit
|
||||
#self.submodules.sdram_init = DDR3FBInit(sys_clk_freq=sys_clk_freq, bitslip=1, delay=25)
|
||||
#self.bus.add_master(name="DDR3Init", master=self.sdram_init.bus)
|
||||
else:
|
||||
avail_sdram = 256 * 1024 * 1024
|
||||
self.add_ram("ram", origin=0x8f800000, size=2**16, mode="rw")
|
||||
|
||||
if (not notsimul): # otherwise we have no CSRs and litex doesn't like that
|
||||
self.submodules.leds = ClockDomainsRenamer("nubus")(LedChaser(
|
||||
pads = platform.request_all("user_led"),
|
||||
sys_clk_freq = 10e6))
|
||||
self.add_csr("leds")
|
||||
|
||||
base_fb = self.wb_mem_map["main_ram"] + avail_sdram - 1048576 # placeholder
|
||||
if (goblin):
|
||||
MacPeriphSoC.mac_add_goblin_prelim(self)
|
||||
if (avail_sdram >= goblin_fb_size):
|
||||
avail_sdram = avail_sdram - goblin_fb_size
|
||||
base_fb = self.wb_mem_map["main_ram"] + avail_sdram
|
||||
self.wb_mem_map["video_framebuffer"] = base_fb
|
||||
print(f"FrameBuffer base_fb @ {base_fb:x}")
|
||||
else:
|
||||
print("***** ERROR ***** Can't have a FrameBuffer without main ram\n")
|
||||
assert(False)
|
||||
|
||||
# don't enable anything on the NuBus side for XX seconds after power up
|
||||
# this avoids FPGA initialization messing with the cold boot process
|
||||
@ -339,7 +491,7 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
fromsbus_req_fifo=self.fromsbus_req_fifo,
|
||||
dram_native_r=self.sdram.crossbar.get_port(mode="read", data_width=data_width_bits),
|
||||
dram_native_w=self.sdram.crossbar.get_port(mode="write", data_width=data_width_bits),
|
||||
mem_size=self.avail_sdram//1048576,
|
||||
mem_size=avail_sdram//1048576,
|
||||
burst_size=burst_size,
|
||||
do_checksum = False,
|
||||
clock_domain="nubus")
|
||||
@ -378,13 +530,45 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
self.bus.add_slave("Stat", self.stat.bus_slv, SoCRegion(origin=self.mem_map.get("stat", None), size=0x1000, cached=False))
|
||||
|
||||
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 (not hdmi):
|
||||
self.submodules.videophy = VideoVGAPHY(platform.request("vga"), clock_domain="vga")
|
||||
self.submodules.goblin = Goblin(soc=self, phy=self.videophy, timings=goblin_res, clock_domain="vga", irq_line=fb_irq, endian="little", hwcursor=False, truecolor=True) # clock_domain for the VGA side, goblin is running in cd_sys
|
||||
else:
|
||||
if (not use_goblin_alt):
|
||||
self.submodules.videophy = VideoS7HDMIPHY(platform.request("hdmi"), clock_domain="hdmi")
|
||||
self.submodules.goblin = Goblin(soc=self, phy=self.videophy, timings=goblin_res, clock_domain="hdmi", irq_line=fb_irq, endian="little", hwcursor=False, truecolor=True) # clock_domain for the HDMI side, goblin is running in cd_sys
|
||||
else:
|
||||
# GoblinAlt contains its own PHY
|
||||
self.submodules.goblin = GoblinAlt(soc=self, timings=goblin_res, clock_domain="hdmi", irq_line=fb_irq, endian="little", hwcursor=False, truecolor=True)
|
||||
# it also has a bus master so that the audio bit can fetch data from Wishbone
|
||||
self.bus.add_master(name="GoblinAudio", master=self.goblin.goblin_audio.busmaster)
|
||||
self.add_ram("goblin_audio_ram", origin=self.mem_map["goblin_audio_ram"], size=2**13, mode="rw") # 8 KiB buffer, planned as 2*4KiB
|
||||
self.comb += [ audio_irq.eq(self.goblin.goblin_audio.irq), ]
|
||||
|
||||
self.bus.add_slave("goblin_bt", self.goblin.bus, SoCRegion(origin=self.mem_map.get("goblin_bt", None), size=0x1000, cached=False))
|
||||
#pad_user_led_0 = platform.request("user_led", 0)
|
||||
#pad_user_led_1 = platform.request("user_led", 1)
|
||||
#self.comb += pad_user_led_0.eq(self.goblin.video_framebuffer.underflow)
|
||||
#self.comb += pad_user_led_1.eq(self.goblin.video_framebuffer.fb_dma.enable)
|
||||
if (True):
|
||||
self.submodules.goblin_accel = GoblinAccelNuBus(soc = self)
|
||||
self.bus.add_slave("goblin_accel", self.goblin_accel.bus, SoCRegion(origin=self.mem_map.get("goblin_accel", None), size=0x1000, cached=False))
|
||||
self.bus.add_master(name="goblin_accel_r5_i", master=self.goblin_accel.ibus)
|
||||
self.bus.add_master(name="goblin_accel_r5_d", master=self.goblin_accel.dbus)
|
||||
goblin_rom_file = "VintageBusFPGA_Common/blit_goblin_nubus.raw"
|
||||
goblin_rom_data = soc_core.get_mem_data(filename_or_regions=goblin_rom_file, endianness="little")
|
||||
goblin_rom_len = 4*len(goblin_rom_data);
|
||||
rounded_goblin_rom_len = 2**log2_int(goblin_rom_len, False)
|
||||
print(f"GOBLIN ROM is {goblin_rom_len} bytes, using {rounded_goblin_rom_len}")
|
||||
assert(rounded_goblin_rom_len <= 2**16)
|
||||
self.add_ram("goblin_accel_rom", origin=self.mem_map["goblin_accel_rom"], size=rounded_goblin_rom_len, contents=goblin_rom_data, mode="r")
|
||||
self.add_ram("goblin_accel_ram", origin=self.mem_map["goblin_accel_ram"], size=2**12, mode="rw")
|
||||
|
||||
if (sdcard):
|
||||
self.add_sdcard()
|
||||
# irq?
|
||||
|
||||
if (ethernet): ### WIP WIP WIP WIP
|
||||
if (ethernet):
|
||||
# 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"),
|
||||
@ -392,10 +576,6 @@ class NuBusFPGA(MacPeriphSoC):
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user