From 40e818c950d73fd6d3aa03702b8f7c99a50e0d0c Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Mon, 20 Sep 2021 13:50:00 -0400 Subject: [PATCH] version-specific proms --- .../forth_to_migen_rom.sh | 38 +++--- sbus-to-ztex-gateware-migen/prom_V1_0.bth | 13 ++ sbus-to-ztex-gateware-migen/prom_V1_2.bth | 13 ++ sbus-to-ztex-gateware-migen/prom_csr.fth | 15 --- .../sbus_to_fpga_prom.py | 122 ++++++++++++++++++ .../sbus_to_fpga_soc.py | 36 ++++-- 6 files changed, 196 insertions(+), 41 deletions(-) create mode 100644 sbus-to-ztex-gateware-migen/prom_V1_0.bth create mode 100644 sbus-to-ztex-gateware-migen/prom_V1_2.bth delete mode 100644 sbus-to-ztex-gateware-migen/prom_csr.fth create mode 100644 sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py diff --git a/sbus-to-ztex-gateware-migen/forth_to_migen_rom.sh b/sbus-to-ztex-gateware-migen/forth_to_migen_rom.sh index 5bcd747..ab3bdc4 100755 --- a/sbus-to-ztex-gateware-migen/forth_to_migen_rom.sh +++ b/sbus-to-ztex-gateware-migen/forth_to_migen_rom.sh @@ -1,21 +1,29 @@ #!/bin/bash -PFX=prom_migen +for V in "V1_0" "V1_2"; do -rm -f ${PFX}.fc + PFX=prom_${V} -# (export BP=~/SPARC/SBusFPGA/sbus-to-ztex/openfirmware ; toke ${PFX}.forth ) + if test -f ${PFX}.fth; then + echo "GENERATING PROM for $V" -( export BP=`pwd`/openfirmware ; openfirmware/cpu/x86/Linux/forth openfirmware/cpu/x86/build/builder.dic prom_migen.bth ) 2>&1 | tee forth.log + rm -f ${PFX}.fc + + # (export BP=~/SPARC/SBusFPGA/sbus-to-ztex/openfirmware ; toke ${PFX}.forth ) + + ( export BP=`pwd`/openfirmware ; openfirmware/cpu/x86/Linux/forth openfirmware/cpu/x86/build/builder.dic ${PFX}.bth ) 2>&1 | tee forth.log + + rm -f /tmp/${PFX}.hexa + + od --endian=big -w4 -x ${PFX}.fc | awk '{ print $2,$3"," }' >| /tmp/${PFX}.hexa + + rm -f /tmp/${PFX}.txt_hexa + + cat /tmp/${PFX}.hexa | sed -e 's/^\([a-f0-9][a-f0-9][a-f0-9][a-f0-9]\) \([a-f0-9][a-f0-9][a-f0-9][a-f0-9]\),/0x\1\2,/g' -e 's/^\([a-f0-9][a-f0-9]*\) ,/0x\10000,/' -e 's/^ ,/0x00000000,/' -e 's/\(0x[0-9a-fA-F]*\),/if (idx == 0):\n\treturn \1;/' > /tmp/${PFX}.txt_hexa + + #echo "rom = [" + #cat /tmp/${PFX}.txt_hexa + #echo "]" + fi -rm -f /tmp/${PFX}.hexa - -od --endian=big -w4 -x ${PFX}.fc | awk '{ print $2,$3"," }' >| /tmp/${PFX}.hexa - -rm -f /tmp/${PFX}.txt_hexa - -cat /tmp/${PFX}.hexa | sed -e 's/^\([a-f0-9][a-f0-9][a-f0-9][a-f0-9]\) \([a-f0-9][a-f0-9][a-f0-9][a-f0-9]\),/0x\1\2,/g' -e 's/^\([a-f0-9][a-f0-9]*\) ,/0x\10000,/' -e 's/^ ,/0x00000000,/' -e 's/\(0x[0-9a-fA-F]*\),/if (idx == 0):\n\treturn \1;/' > /tmp/${PFX}.txt_hexa - -#echo "rom = [" -#cat /tmp/${PFX}.txt_hexa -#echo "]" +done diff --git a/sbus-to-ztex-gateware-migen/prom_V1_0.bth b/sbus-to-ztex-gateware-migen/prom_V1_0.bth new file mode 100644 index 0000000..72ef944 --- /dev/null +++ b/sbus-to-ztex-gateware-migen/prom_V1_0.bth @@ -0,0 +1,13 @@ +purpose: Load file for SBusFPGA + +command: &builder &this + +build-now + +\ silent on + +begin-tokenizing prom_V1_0.fc + +fload prom_V1_0.fth + +end-tokenizing diff --git a/sbus-to-ztex-gateware-migen/prom_V1_2.bth b/sbus-to-ztex-gateware-migen/prom_V1_2.bth new file mode 100644 index 0000000..06c9fa7 --- /dev/null +++ b/sbus-to-ztex-gateware-migen/prom_V1_2.bth @@ -0,0 +1,13 @@ +purpose: Load file for SBusFPGA + +command: &builder &this + +build-now + +\ silent on + +begin-tokenizing prom_V1_2.fc + +fload prom_V1_2.fth + +end-tokenizing diff --git a/sbus-to-ztex-gateware-migen/prom_csr.fth b/sbus-to-ztex-gateware-migen/prom_csr.fth deleted file mode 100644 index 26f7854..0000000 --- a/sbus-to-ztex-gateware-migen/prom_csr.fth +++ /dev/null @@ -1,15 +0,0 @@ -\ auto-generated base regions for CSRs in the PROM -h# 40000 constant sbusfpga_csraddr_leds -h# 41000 constant sbusfpga_csraddr_curve25519engine -h# 42000 constant sbusfpga_csraddr_ddrphy -h# 43000 constant sbusfpga_csraddr_exchange_with_mem -h# 44000 constant sbusfpga_csraddr_sbus_bus_stat -h# 45000 constant sbusfpga_csraddr_sdram -h# 46000 constant sbusfpga_csraddr_trng -h# 80000 constant sbusfpga_regionaddr_usb_host_ctrl -h# 0 constant sbusfpga_regionaddr_prom -h# 80000000 constant sbusfpga_regionaddr_main_ram -h# fc000000 constant sbusfpga_regionaddr_usb_fake_dma -h# a0000 constant sbusfpga_regionaddr_curve25519engine -h# 40000 constant sbusfpga_regionaddr_csr -h# 1 constant sbusfpga_irq_usb_host diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py new file mode 100644 index 0000000..1e8caf2 --- /dev/null +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_prom.py @@ -0,0 +1,122 @@ +import os +import json +import inspect +from shutil import which +from sysconfig import get_platform + +from migen import * + +def get_header_map_stuff(name, size, type="csr"): + r = f"my-address sbusfpga_{type}addr_{name} + my-space h# {size:x} reg\n" + r += "h# 7f xdrint \" slave-burst-sizes\" attribute\n" # fixme: burst-sizes + r += "h# 7f xdrint \" burst-sizes\" attribute\n" # fixme: burst-sizes + r += f"headers\n-1 instance value {name}-virt\nmy-address constant my-sbus-address\nmy-space constant my-sbus-space\n" + r += ": map-in ( adr space size -- virt ) \" map-in\" $call-parent ;\n: map-out ( virt size -- ) \" map-out\" $call-parent ;\n"; + r += f": map-in-{name} ( -- ) my-sbus-address sbusfpga_{type}addr_{name} + my-sbus-space h# {size:x} map-in is {name}-virt ;\n" + r += f": map-out-{name} ( -- ) {name}-virt h# {size:x} map-out ;\n" + return r + +def get_header_map3_stuff(gname, name1, name2, name3, size1, size2, size3, type1="csr", type2="csr", type3="csr"): + r = f"my-address sbusfpga_{type1}addr_{name1} + my-space xdrphys h# {size1:x} xdrint xdr+\n" + r += f"my-address sbusfpga_{type2}addr_{name2} + my-space xdrphys h# {size2:x} xdrint xdr+\n" + r += f"my-address sbusfpga_{type3}addr_{name3} + my-space xdrphys h# {size3:x} xdrint xdr+\n" + r += "\" reg\" attribute\n" + r += "h# 7f xdrint \" slave-burst-sizes\" attribute\n" # fixme: burst-sizes + r += "h# 7f xdrint \" burst-sizes\" attribute\n" # fixme: burst-sizes + r += f"headers\n-1 instance value {name1}-virt\n" + r += f"headers\n-1 instance value {name2}-virt\n" + r += f"headers\n-1 instance value {name3}-virt\n" + r += "my-address constant my-sbus-address\nmy-space constant my-sbus-space\n" + r += ": map-in ( adr space size -- virt ) \" map-in\" $call-parent ;\n: map-out ( virt size -- ) \" map-out\" $call-parent ;\n"; + r += f": map-in-{gname} ( -- )\n" + r += f"my-sbus-address sbusfpga_{type1}addr_{name1} + my-sbus-space h# {size1:x} map-in is {name1}-virt\n" + r += f"my-sbus-address sbusfpga_{type2}addr_{name2} + my-sbus-space h# {size2:x} map-in is {name2}-virt\n" + r += f"my-sbus-address sbusfpga_{type3}addr_{name3} + my-sbus-space h# {size3:x} map-in is {name3}-virt\n" + r += ";\n" + r += f": map-out-{gname} ( -- )\n" + r += f"{name1}-virt h# {size1:x} map-out\n" + r += f"{name2}-virt h# {size2:x} map-out\n" + r += f"{name3}-virt h# {size3:x} map-out\n" + r += ";\n" + return r + +def get_prom(soc, + version="V1.0", + usb=False, + sdram=True, + engine=False, + i2c=False, + cg3=False): + + r = "fcode-version2\nfload prom_csr_{}.fth\n".format(version.replace(".", "_")) + + if (version == "V1.0"): + r += "\" RDOL,led\" device-name\n" + r += get_header_map_stuff("leds", 4) + r += ": setled! ( pattern -- )\nmap-in-leds\nleds-virt l! ( pattern virt -- )\nmap-out-leds\n;\n" + r += "finish-device\nnew-device\n" + + r += "\" RDOL,sbusstat\" device-name\n" + r += get_header_map_stuff("sbus_bus_stat", 256) + r += "finish-device\nnew-device\n" + + r += "\" RDOL,neorv32trng\" device-name\n" + r += get_header_map_stuff("trng", 8) + r += ": disabletrng! ( -- )\n" + r += " map-in-trng\n" + r += " 1 trng-virt l! ( pattern virt -- )\n" + r += " map-out-trng\n" + r += ";\n" + r += "disabletrng!\n" + if (usb or sdram or engine or i2c or cg3): + r += "finish-device\nnew-device\n" + + if (usb): + r += "\" generic-ohci\" device-name\n" + r += "sbusfpga_irq_usb_host xdrint \" interrupts\" attribute\n" + r += get_header_map_stuff("usb_host_ctrl", 4096, type="region") + r += ": my-reset! ( -- )\n" + r += " map-in-usb_host_ctrl\n" + r += " 00000001 usb_host_ctrl-virt h# 4 + l! ( -- ) ( reset the HC )\n" + r += " 00000000 usb_host_ctrl-virt h# 18 + l! ( -- ) ( reset HCCA & friends )\n" + r += " 00000000 usb_host_ctrl-virt h# 1c + l! ( -- )\n" + r += " 00000000 usb_host_ctrl-virt h# 20 + l! ( -- )\n" + r += " 00000000 usb_host_ctrl-virt h# 24 + l! ( -- )\n" + r += " 00000000 usb_host_ctrl-virt h# 28 + l! ( -- )\n" + r += " 00000000 usb_host_ctrl-virt h# 2c + l! ( -- )\n" + r += " 00000000 usb_host_ctrl-virt h# 30 + l! ( -- )\n" + r += " map-out-usb_host_ctrl\n" + r += ";\n" + r += "my-reset!\n" + if (sdram or engine or i2c or cg3): + r += "finish-device\nnew-device\n" + + if (sdram): + r += "\" RDOL,sdram\" device-name\n" + r += get_header_map3_stuff("mregs", "ddrphy", "sdram", "exchange_with_mem", 4096, 4096, 4096) + if (engine or i2c or cg3): + r += "finish-device\nnew-device\n" + + if (engine): + r += "\" betrustedc25519e\" device-name\n" + r += ": sbusfpga_regionaddr_curve25519engine-microcode sbusfpga_regionaddr_curve25519engine ;\n" + r += ": sbusfpga_regionaddr_curve25519engine-regfile sbusfpga_regionaddr_curve25519engine h# 10000 + ;\n" + r += get_header_map3_stuff("curve25519engine", "curve25519engine-regs", "curve25519engine-microcode", "curve25519engine-regfile", 4096, 4096, 65536, type2="region", type3="region") + if (i2c or cg3): + r += "finish-device\nnew-device\n" + + if (i2c): + r += "\" RDOL,i2c\" device-name\n" + r += get_header_map_stuff("i2c", 64) + if (cg3): + r += "finish-device\nnew-device\n" + + if (cg3): + cg3_file = open("cg3.fth") + cg3_lines = cg3_file.readlines() + for line in cg3_lines: + r += line + + r += "end0\n" + + return r diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py index 679b46b..399bc2e 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py @@ -31,6 +31,7 @@ from migen.genlib.resetsync import AsyncResetSynchronizer; from gateware import i2c; import sbus_to_fpga_export; +import sbus_to_fpga_prom; from litex.soc.cores.video import VideoVGAPHY import cg3_fb; @@ -181,10 +182,11 @@ class _CRG(Module): if (cg3): self.submodules.video_pll = video_pll = S7MMCM(speedgrade=-1) video_pll.register_clkin(self.clk48_bufg, 48e6) - video_pll.create_clkout(self.cd_vga, pix_clk, margin = 0) + 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)) num_clk = num_clk + 1 self.comb += video_pll.reset.eq(~rst_sbus) + platform.add_false_path_constraints(self.cd_sys.clk, self.cd_vga.clk) num_adv = num_adv + 1 num_clk = 0 @@ -279,7 +281,7 @@ class SBusFPGA(SoCCore): #self.comb += pad_SBUS_DATA_OE_LED_2.eq(SBUS_DATA_OE_LED_2_o) #self.comb += SBUS_DATA_OE_LED_o.eq(~SBUS_3V3_INT1s_o) - prom_file = "prom_migen.fc" + prom_file = "prom_{}.fc".format(version.replace(".", "_")) prom_data = soc_core.get_mem_data(prom_file, "big") # prom = Array(prom_data) #print("\n****************************************\n") @@ -391,8 +393,9 @@ class SBusFPGA(SoCCore): if (cg3): litex.soc.cores.video.video_timings.update(cg3_fb.cg3_timings) self.submodules.videophy = VideoVGAPHY(platform.request("vga"), clock_domain="vga") - self.submodules.cg3 = cg3_fb.cg3(soc=self, phy=self.videophy, timings="1152x900@76Hz", clock_domain="vga") + self.submodules.cg3 = cg3_fb.cg3(soc=self, phy=self.videophy, timings="1152x900@76Hz", clock_domain="vga") # clock_domain for the VGA side, cg3 is running in cd_sys self.bus.add_slave("cg3_registers", self.cg3.bus, SoCRegion(origin=self.mem_map.get("cg3_registers", None), size=0x1000, cached=False)) + #self.add_video_framebuffer(phy=self.videophy, timings="1152x900@76Hz", clock_domain="vga") print("IRQ to Device map:\n") print(platform.irq_device_map) @@ -432,18 +435,21 @@ def main(): cg3=args.cg3) #soc.add_uart(name="uart", baudrate=115200, fifo_depth=16) - soc.platform.name += "_" + args.version.replace(".", "_") + version_for_filename = args.version.replace(".", "_") + + soc.platform.name += "_" + version_for_filename builder = Builder(soc, **builder_argdict(args)) builder.build(**vivado_build_argdict(args), run=args.build) # Generate modified CSR registers definitions/access functions to netbsd_csr.h. # should be split per-device (and without base) to still work if we have identical devices in different configurations on multiple boards - csr_contents = sbus_to_fpga_export.get_csr_header( - regions = soc.csr_regions, - constants = soc.constants, - csr_base = soc.mem_regions['csr'].origin) - write_to_file(os.path.join("netbsd_csr.h"), csr_contents) + # now it is split + #csr_contents = sbus_to_fpga_export.get_csr_header( + # regions = soc.csr_regions, + # constants = soc.constants, + # csr_base = soc.mem_regions['csr'].origin) + #write_to_file(os.path.join("netbsd_csr.h"), csr_contents) csr_contents_dict = sbus_to_fpga_export.get_csr_header_split( regions = soc.csr_regions, @@ -452,7 +458,6 @@ def main(): for name in csr_contents_dict.keys(): write_to_file(os.path.join("sbusfpga_csr_{}.h".format(name)), csr_contents_dict[name]) - # tells the prom where to find what # just one, as that is board-specific # BEWARE! then need to run 'forth_to_migen_rom.sh' *and* regenerate the bitstream with the proper PROM built-in! @@ -463,7 +468,16 @@ def main(): device_irq_map = soc.platform.device_irq_map, constants = soc.constants, csr_base = soc.mem_regions['csr'].origin) - write_to_file(os.path.join("prom_csr.fth"), csr_forth_contents) + write_to_file(os.path.join(f"prom_csr_{version_for_filename}.fth"), csr_forth_contents) + + prom_content = sbus_to_fpga_prom.get_prom(soc=soc, version=args.version, + usb=args.usb, + sdram=args.sdram, + engine=args.engine, + i2c=args.i2c, + cg3=args.cg3) + write_to_file(os.path.join(f"prom_{version_for_filename}.fth"), prom_content) + if __name__ == "__main__": main()