From 5c9c67e4a872e9d448fc800538241768a86fcd18 Mon Sep 17 00:00:00 2001 From: Carl Karsten Date: Mon, 9 Sep 2019 12:32:28 -0500 Subject: [PATCH 001/153] move #endif - fixes ##479 --- firmware/ci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/ci.c b/firmware/ci.c index 4a48a46ba..bd3f11d7d 100644 --- a/firmware/ci.c +++ b/firmware/ci.c @@ -473,12 +473,12 @@ static void status_print(void) #ifdef CSR_HDMI_IN0_FREQ_BASE wprintf(" (@" REFRESH_RATE_PRINTF " MHz)", REFRESH_RATE_PRINTF_ARGS(hdmi_in0_freq_value_read() / 10000)); +#endif if(hdmi_in0_status()) { wprintf(" (capturing)"); } else { wprintf(" (disabled)"); } -#endif wputchar('\n'); #endif From 10326426471d4171fbfcbf34d382e2da08b93dc4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 29 Nov 2019 19:52:51 +0000 Subject: [PATCH 002/153] build(deps): bump third_party/liteeth from `4d9e74f` to `f2b3f7e` Bumps [third_party/liteeth](https://github.com/enjoy-digital/liteeth) from `4d9e74f` to `f2b3f7e`. - [Release notes](https://github.com/enjoy-digital/liteeth/releases) - [Commits](https://github.com/enjoy-digital/liteeth/compare/4d9e74f10a3fe7bf71ba9bde50f49689c6458dc5...f2b3f7eeb1a68a4db0d9a3315994374c15e46019) Signed-off-by: dependabot-preview[bot] --- third_party/liteeth | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/liteeth b/third_party/liteeth index 4d9e74f10..f2b3f7eeb 160000 --- a/third_party/liteeth +++ b/third_party/liteeth @@ -1 +1 @@ -Subproject commit 4d9e74f10a3fe7bf71ba9bde50f49689c6458dc5 +Subproject commit f2b3f7eeb1a68a4db0d9a3315994374c15e46019 From 8dc3a40a330c32ea638bff1c49d2aa4195491023 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2019 19:52:00 +0000 Subject: [PATCH 003/153] build(deps): bump third_party/litesata from `db5d2f7` to `b400655` Bumps [third_party/litesata](https://github.com/enjoy-digital/litesata) from `db5d2f7` to `b400655`. - [Release notes](https://github.com/enjoy-digital/litesata/releases) - [Commits](https://github.com/enjoy-digital/litesata/compare/db5d2f7881161ce5b9a10a0ab42555f884b9d7c1...b40065591fa4c41b22da1830ae253a1efd8d3d0b) Signed-off-by: dependabot-preview[bot] --- third_party/litesata | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litesata b/third_party/litesata index db5d2f788..b40065591 160000 --- a/third_party/litesata +++ b/third_party/litesata @@ -1 +1 @@ -Subproject commit db5d2f7881161ce5b9a10a0ab42555f884b9d7c1 +Subproject commit b40065591fa4c41b22da1830ae253a1efd8d3d0b From c0886bf9b465d0be1af83ec37b3de351bd91dee0 Mon Sep 17 00:00:00 2001 From: Niklas Nisbeth Date: Sat, 28 Dec 2019 20:43:05 +0100 Subject: [PATCH 004/153] Use quotes instead of backticks in enter-env.sh --- scripts/enter-env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/enter-env.sh b/scripts/enter-env.sh index 9cddcc503..6a30edad7 100755 --- a/scripts/enter-env.sh +++ b/scripts/enter-env.sh @@ -63,7 +63,7 @@ fi if [ -f /etc/udev/rules.d/99-hdmi2usb-permissions.rules -o -f /lib/udev/rules.d/99-hdmi2usb-permissions.rules -o -f /lib/udev/rules.d/60-hdmi2usb-udev.rules -o ! -z "$HDMI2USB_UDEV_IGNORE" ]; then true else - echo "Please install the HDMI2USB udev rules, or `export HDMI2USB_UDEV_IGNORE=somevalue` to ignore this." + echo "Please install the HDMI2USB udev rules, or 'export HDMI2USB_UDEV_IGNORE=somevalue' to ignore this." echo "On Debian/Ubuntu, these can be installed by running scripts/debian-setup.sh" echo return 1 From bd8bf7803089edf241cc920ec2dd2e6528f03d5b Mon Sep 17 00:00:00 2001 From: Niklas Nisbeth Date: Sat, 28 Dec 2019 20:09:28 +0100 Subject: [PATCH 005/153] Make ice40_hx8k_b_evn target use heap placer --- targets/ice40_hx8k_b_evn/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/ice40_hx8k_b_evn/base.py b/targets/ice40_hx8k_b_evn/base.py index f03aa38a6..a1fc14702 100644 --- a/targets/ice40_hx8k_b_evn/base.py +++ b/targets/ice40_hx8k_b_evn/base.py @@ -103,6 +103,7 @@ def __init__(self, platform, **kwargs): # Disable final deep-sleep power down so firmware words are loaded # onto softcore's address bus. platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin" + platform.toolchain.nextpnr_build_template[1] += " --placer heap" platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" From 7b077f50b9e413fbffd0604902568f7f0a5ae9fb Mon Sep 17 00:00:00 2001 From: Niklas Nisbeth Date: Sat, 28 Dec 2019 20:12:49 +0100 Subject: [PATCH 006/153] Remove "Xilinx" from mkimage output mkimage.py was referring to all FPGA bitstreams as "Xilinx FPGA bitstreams" --- mkimage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkimage.py b/mkimage.py index 636fb03cf..009ef3ad8 100755 --- a/mkimage.py +++ b/mkimage.py @@ -85,7 +85,7 @@ def main(): gateware = "Skipped" print(("Gateware @ 0x{:08x} ({:10} bytes) {:60}" - " - Xilinx FPGA Bitstream" + " - FPGA Bitstream" ).format(gateware_pos, len(gateware_data), gateware)) print(" ".join("{:02x}".format(i) for i in gateware_data[:64])) assert len(gateware_data) < platform.gateware_size From e86fcbf5453f4686aa08aa93bfcd9913ce652b63 Mon Sep 17 00:00:00 2001 From: Ewen McNeill Date: Fri, 10 Jan 2020 14:10:24 +1000 Subject: [PATCH 007/153] EDID: v_sync offset/width are 6-bit values Fix assumption that both h_sync and v_sync offset/width are 10-bit values, which resulted in the v_sync offset being sent as if it were 0; h_sync offset/width are 10-bit values, but v_sync offset/width are 6-bit values. For a summary of the timing section of EDID bit packing see: https://en.wikipedia.org/wiki/Extended_Display_Identification_Data#Detailed_Timing_Descriptor --- firmware/edid.c | 19 ++++++++++++++++--- firmware/processor.c | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/firmware/edid.c b/firmware/edid.c index 6db7a5966..de0aacda0 100644 --- a/firmware/edid.c +++ b/firmware/edid.c @@ -149,6 +149,12 @@ static void generate_edid_timing(uint8_t *data_block, const struct video_timing t->pixel_clock[0] = timing->pixel_clock & 0xff; t->pixel_clock[1] = timing->pixel_clock >> 8; + /* EDID wire format summary: + * https://en.wikipedia.org/wiki/Extended_Display_Identification_Data#Detailed_Timing_Descriptor + * Note h_sync offset/width are 10-bit values, and v_sync offset/width + * are 6-bit values. All of them are split over bytes in structure. + */ + t->h_active_l = timing->h_active & 0xff; t->h_blanking_l = timing->h_blanking & 0xff; t->h_active_blanking_h = ((timing->h_active >> 8) << 4) | (timing->h_blanking >> 8); @@ -159,9 +165,16 @@ static void generate_edid_timing(uint8_t *data_block, const struct video_timing t->h_sync_offset_l = timing->h_sync_offset & 0xff; t->h_sync_width_l = timing->h_sync_width & 0xff; - t->v_sync_offset_width_l = timing->v_sync_offset & 0xff; - t->hv_sync_offset_width_h = ((timing->h_sync_offset >> 8) << 6) | ((timing->h_sync_width >> 8) << 4) - | ((timing->v_sync_offset >> 8) << 2) | (timing->v_sync_width >> 8); + + /* Byte 10: 4-bits of v_sync offset, 4 bits of v_sync_width */ + t->v_sync_offset_width_l = ((timing->v_sync_offset & 0x0f) << 4) | (timing->v_sync_width & 0x0f); + + /* Byte 11: top 2-bits each: h_sync offset/width, v_sync offset/width */ + t->hv_sync_offset_width_h = + (((timing->h_sync_offset >> 8) & 0x03) << 6) | + (((timing->h_sync_width >> 8) & 0x03) << 4) | + (((timing->v_sync_offset >> 4) & 0x03) << 2) | + (((timing->v_sync_width >> 4) & 0x03)); h_image_size = 10*timing->h_active/64; v_image_size = 10*timing->v_active/64; diff --git a/firmware/processor.c b/firmware/processor.c index 782f9d712..65073f9a0 100644 --- a/firmware/processor.c +++ b/firmware/processor.c @@ -267,7 +267,7 @@ static const struct video_timing video_modes[PROCESSOR_MODE_COUNT] = { .v_active = 720, .v_blanking = 30, - .v_sync_offset = 20, + .v_sync_offset = 5, .v_sync_width = 5, .flags = EDID_DIGITAL | EDID_HSYNC_POS | EDID_VSYNC_POS From fc4089380b9c4df915a277a4057f9cd2fc163f0a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2020 19:55:37 +0000 Subject: [PATCH 008/153] build(deps): bump third_party/litepcie from `c455779` to `06ee416` Bumps [third_party/litepcie](https://github.com/enjoy-digital/litepcie) from `c455779` to `06ee416`. - [Release notes](https://github.com/enjoy-digital/litepcie/releases) - [Commits](https://github.com/enjoy-digital/litepcie/compare/c4557792267f83a6e5ee1cccce3e1e2cd1d5b46e...06ee416e9eedf6e44ac13b89d06c1c96d9c3dd39) Signed-off-by: dependabot-preview[bot] --- third_party/litepcie | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litepcie b/third_party/litepcie index c45577922..06ee416e9 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit c4557792267f83a6e5ee1cccce3e1e2cd1d5b46e +Subproject commit 06ee416e9eedf6e44ac13b89d06c1c96d9c3dd39 From 2b69ba7fc4448494fc0b870f97f9af0be19908e8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2020 19:56:07 +0000 Subject: [PATCH 009/153] build(deps): bump third_party/migen from `94db729` to `0d0e17a` Bumps [third_party/migen](https://github.com/m-labs/migen) from `94db729` to `0d0e17a`. - [Release notes](https://github.com/m-labs/migen/releases) - [Commits](https://github.com/m-labs/migen/compare/94db7295fd4942d0ee27de1148a6cc7be356329d...0d0e17a5e65fc21a2f08a16b55594739c98cf89e) Signed-off-by: dependabot-preview[bot] --- third_party/migen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/migen b/third_party/migen index 94db7295f..0d0e17a5e 160000 --- a/third_party/migen +++ b/third_party/migen @@ -1 +1 @@ -Subproject commit 94db7295fd4942d0ee27de1148a6cc7be356329d +Subproject commit 0d0e17a5e65fc21a2f08a16b55594739c98cf89e From f39b41c16dea3d6483413d7ace4567486f883c76 Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Wed, 20 Nov 2019 10:17:36 +0100 Subject: [PATCH 010/153] platforms: add netv2 platform --- platforms/netv2.py | 234 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 platforms/netv2.py diff --git a/platforms/netv2.py b/platforms/netv2.py new file mode 100644 index 000000000..eed6395e3 --- /dev/null +++ b/platforms/netv2.py @@ -0,0 +1,234 @@ +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, VivadoProgrammer + +_io = [ + # clock + ("clk50", 0, Pins("J19"), IOStandard("LVCMOS33")), + + # leds + ("user_led", 0, Pins("M21"), IOStandard("LVCMOS33")), + ("user_led", 1, Pins("N20"), IOStandard("LVCMOS33")), + ("user_led", 2, Pins("L21"), IOStandard("LVCMOS33")), + ("user_led", 3, Pins("AA21"), IOStandard("LVCMOS33")), + ("user_led", 4, Pins("R19"), IOStandard("LVCMOS33")), + ("user_led", 5, Pins("M16"), IOStandard("LVCMOS33")), + + # flash + ("flash", 0, + Subsignal("cs_n", Pins("T19")), + Subsignal("mosi", Pins("P22")), + Subsignal("miso", Pins("R22")), + Subsignal("vpp", Pins("P21")), + Subsignal("hold", Pins("R21")), + IOStandard("LVCMOS33") + ), + + # serial + ("serial", 0, + Subsignal("tx", Pins("E14")), + Subsignal("rx", Pins("E13")), + IOStandard("LVCMOS33"), + ), + + # dram + ("ddram", 0, + Subsignal("a", Pins( + "U6 V4 W5 V5 AA1 Y2 AB1 AB3", + "AB2 Y3 W6 Y1 V2 AA3" + ), + IOStandard("SSTL15")), + Subsignal("ba", Pins("U5 W4 V7"), IOStandard("SSTL15")), + Subsignal("ras_n", Pins("Y9"), IOStandard("SSTL15")), + Subsignal("cas_n", Pins("Y7"), IOStandard("SSTL15")), + Subsignal("we_n", Pins("V8"), IOStandard("SSTL15")), + Subsignal("dm", Pins("M5 L3"), IOStandard("SSTL15")), + Subsignal("dq", Pins( + "N2 M6 P1 N5 P2 N4 R1 P6 " + "K3 M2 K4 M3 J6 L5 J4 K6 " + ), + IOStandard("SSTL15"), + Misc("IN_TERM=UNTUNED_SPLIT_50")), + Subsignal("dqs_p", Pins("P5 M1"), IOStandard("DIFF_SSTL15")), + Subsignal("dqs_n", Pins("P4 L1"), IOStandard("DIFF_SSTL15")), + Subsignal("clk_p", Pins("R3"), IOStandard("DIFF_SSTL15")), + Subsignal("clk_n", Pins("R2"), IOStandard("DIFF_SSTL15")), + Subsignal("cke", Pins("Y8"), IOStandard("SSTL15")), + Subsignal("odt", Pins("W9"), IOStandard("SSTL15")), + Subsignal("reset_n", Pins("AB5"), IOStandard("LVCMOS15")), + Subsignal("cs_n", Pins("V9"), IOStandard("SSTL15")), + Misc("SLEW=FAST"), + ), + + # pcie + ("pcie_x1", 0, + Subsignal("rst_n", Pins("E18"), IOStandard("LVCMOS33")), + Subsignal("clk_p", Pins("F10")), + Subsignal("clk_n", Pins("E10")), + Subsignal("rx_p", Pins("D11")), + Subsignal("rx_n", Pins("C11")), + Subsignal("tx_p", Pins("D5")), + Subsignal("tx_n", Pins("C5")) + ), + + ("pcie_x2", 0, + Subsignal("rst_n", Pins("E18"), IOStandard("LVCMOS33")), + Subsignal("clk_p", Pins("F10")), + Subsignal("clk_n", Pins("E10")), + Subsignal("rx_p", Pins("D11 B10")), + Subsignal("rx_n", Pins("C11 A10")), + Subsignal("tx_p", Pins("D5 B6")), + Subsignal("tx_n", Pins("C5 A6")) + ), + + ("pcie_x4", 0, + Subsignal("rst_n", Pins("E18"), IOStandard("LVCMOS33")), + Subsignal("clk_p", Pins("F10")), + Subsignal("clk_n", Pins("E10")), + Subsignal("rx_p", Pins("D11 B10 D9 B8")), + Subsignal("rx_n", Pins("C11 A10 C9 A8")), + Subsignal("tx_p", Pins("D5 B6 D7 B4")), + Subsignal("tx_n", Pins("C5 A6 C7 A4")) + ), + + # ethernet + ("eth_clocks", 0, + Subsignal("ref_clk", Pins("D17")), + IOStandard("LVCMOS33"), + ), + + ("eth", 0, + Subsignal("rst_n", Pins("F16")), + Subsignal("rx_data", Pins("A20 B18")), + Subsignal("crs_dv", Pins("C20")), + Subsignal("tx_en", Pins("A19")), + Subsignal("tx_data", Pins("C18 C19")), + Subsignal("mdc", Pins("F14")), + Subsignal("mdio", Pins("F13")), + Subsignal("rx_er", Pins("B20")), + Subsignal("int_n", Pins("D21")), + IOStandard("LVCMOS33") + ), + + # sdcard + ("sdcard", 0, + Subsignal("data", Pins("L15 L16 K14 M13"), Misc("PULLUP True")), + Subsignal("cmd", Pins("L13"), Misc("PULLUP True")), + Subsignal("clk", Pins("K18")), + IOStandard("LVCMOS33"), Misc("SLEW=FAST") + ), + + # hdmi in + ("hdmi_in", 0, + Subsignal("clk_p", Pins("L19"), IOStandard("TMDS_33"), Inverted()), + Subsignal("clk_n", Pins("L20"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data0_p", Pins("K21"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data0_n", Pins("K22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data1_p", Pins("J20"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data1_n", Pins("J21"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data2_p", Pins("J22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data2_n", Pins("H22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("scl", Pins("T18"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("V18"), IOStandard("LVCMOS33")), + ), + + ("hdmi_in", 1, + Subsignal("clk_p", Pins("Y18"), IOStandard("TMDS_33"), Inverted()), + Subsignal("clk_n", Pins("Y19"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data0_p", Pins("AA18"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("AB18"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("AA19"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data1_n", Pins("AB20"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data2_p", Pins("AB21"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data2_n", Pins("AB22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("scl", Pins("W17"), IOStandard("LVCMOS33"), Inverted()), + Subsignal("sda", Pins("R17"), IOStandard("LVCMOS33")), + ), + + # hdmi out + ("hdmi_out", 0, + Subsignal("clk_p", Pins("W19"), Inverted(), IOStandard("TMDS_33")), + Subsignal("clk_n", Pins("W20"), Inverted(), IOStandard("TMDS_33")), + Subsignal("data0_p", Pins("W21"), IOStandard("TMDS_33")), + Subsignal("data0_n", Pins("W22"), IOStandard("TMDS_33")), + Subsignal("data1_p", Pins("U20"), IOStandard("TMDS_33")), + Subsignal("data1_n", Pins("V20"), IOStandard("TMDS_33")), + Subsignal("data2_p", Pins("T21"), IOStandard("TMDS_33")), + Subsignal("data2_n", Pins("U21"), IOStandard("TMDS_33")) + ), + + ("hdmi_out", 1, + Subsignal("clk_p", Pins("G21"), IOStandard("TMDS_33"), Inverted()), + Subsignal("clk_n", Pins("G22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data0_p", Pins("E22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data0_n", Pins("D22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data1_p", Pins("C22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data1_n", Pins("B22"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data2_p", Pins("B21"), IOStandard("TMDS_33"), Inverted()), + Subsignal("data2_n", Pins("A21"), IOStandard("TMDS_33"), Inverted()), + Subsignal("scl", Pins("P16"), IOStandard("LVCMOS33")), + Subsignal("sda", Pins("R16"), IOStandard("LVCMOS33")), + ), +] + +_hdmi_infos = { + "HDMI_OUT0_MNEMONIC": "TX1", + "HDMI_OUT0_DESCRIPTION" : ( + "HDMI-A connector (marked TX0/J10H on PCB) located in the mounting bracket area, connector is the one closer to the DC Jack\\r\\n" + ), + + "HDMI_OUT1_MNEMONIC": "TX2", + "HDMI_OUT1_DESCRIPTION" : ( + "HDMI-D connector (marked TX1/P10H on PCB) located on the top edge of the board, connector is the one closer to the DC Jack\\r\\n" + ), + + "HDMI_IN0_MNEMONIC": "RX1", + "HDMI_IN0_DESCRIPTION" : ( + "HDMI-A connector (marked RX0/J11H on PCB) located in the mounting bracket area, connector is the one farther from the DC Jack\\r\\n" + ), + + "HDMI_IN1_MNEMONIC": "RX2", + "HDMI_IN1_DESCRIPTION" : ( + "HDMI-A connector (marked OVERLAY/J12H on PCB) located on the top edge of the board, connector is the one farther from the DC Jack\\r\\n" + ), +} + +class Platform(XilinxPlatform): + name = "netv2" + default_clk_name = "clk50" + default_clk_period = 20.0 + hdmi_infos = _hdmi_infos + + # From https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf + gateware_size = 0x400000 + + # FIXME: Create a "spi flash module" object in the same way we have SDRAM + # module objects. + spiflash_model = "mx25l6433f" + spiflash_read_dummy_bits = 10 + spiflash_clock_div = 2 + spiflash_total_size = int((64/8)*1024*1024) # 64Mbit + spiflash_page_size = 256 + spiflash_sector_size = 0x1000 + + def __init__(self, toolchain="vivado", programmer="vivado", part="xc7a35t"): + XilinxPlatform.__init__(self, part + "-fgg484-2", _io, + toolchain=toolchain) + + self.toolchain.bitstream_commands = [ + "set_property CONFIG_VOLTAGE 3.3 [current_design]", + "set_property CFGBVS VCCO [current_design]", + "set_property BITSTREAM.CONFIG.CONFIGRATE 40 [current_design]", + "set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]", + ] + self.toolchain.additional_commands = \ + ["write_cfgmem -verbose -force -format bin -interface spix4 -size 16 " + "-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"] + + self.programmer = programmer + + def create_programmer(self): + if self.programmer == "vivado": + return VivadoProgrammer(flash_part="mx25l6433f-spi-x1_x2_x4") + else: + raise ValueError("{} programmer is not supported" + .format(self.programmer)) From b5f73ac761da2d99118636c5b89cdfef885f359f Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Wed, 20 Nov 2019 14:12:00 +0100 Subject: [PATCH 011/153] targets: add netv2 targets --- platforms/netv2.py | 40 +++++----- targets/netv2/Makefile.mk | 48 ++++++++++++ targets/netv2/base.py | 154 +++++++++++++++++++++++++++++++++++++ targets/netv2/hdmi2pcie.py | 133 ++++++++++++++++++++++++++++++++ targets/netv2/net.py | 47 +++++++++++ 5 files changed, 402 insertions(+), 20 deletions(-) create mode 100644 targets/netv2/Makefile.mk create mode 100755 targets/netv2/base.py create mode 100644 targets/netv2/hdmi2pcie.py create mode 100755 targets/netv2/net.py diff --git a/platforms/netv2.py b/platforms/netv2.py index eed6395e3..a4d1432fc 100644 --- a/platforms/netv2.py +++ b/platforms/netv2.py @@ -34,28 +34,28 @@ ("ddram", 0, Subsignal("a", Pins( "U6 V4 W5 V5 AA1 Y2 AB1 AB3", - "AB2 Y3 W6 Y1 V2 AA3" - ), - IOStandard("SSTL15")), - Subsignal("ba", Pins("U5 W4 V7"), IOStandard("SSTL15")), - Subsignal("ras_n", Pins("Y9"), IOStandard("SSTL15")), - Subsignal("cas_n", Pins("Y7"), IOStandard("SSTL15")), - Subsignal("we_n", Pins("V8"), IOStandard("SSTL15")), - Subsignal("dm", Pins("M5 L3"), IOStandard("SSTL15")), + "AB2 Y3 W6 Y1 V2 AA3"), + IOStandard("SSTL15_R")), + Subsignal("ba", Pins("U5 W4 V7"), IOStandard("SSTL15_R")), + Subsignal("ras_n", Pins("Y9"), IOStandard("SSTL15_R")), + Subsignal("cas_n", Pins("Y7"), IOStandard("SSTL15_R")), + Subsignal("we_n", Pins("V8"), IOStandard("SSTL15_R")), + Subsignal("dm", Pins("G1 H4 M5 L3"), IOStandard("SSTL15_R")), Subsignal("dq", Pins( - "N2 M6 P1 N5 P2 N4 R1 P6 " - "K3 M2 K4 M3 J6 L5 J4 K6 " - ), - IOStandard("SSTL15"), - Misc("IN_TERM=UNTUNED_SPLIT_50")), - Subsignal("dqs_p", Pins("P5 M1"), IOStandard("DIFF_SSTL15")), - Subsignal("dqs_n", Pins("P4 L1"), IOStandard("DIFF_SSTL15")), - Subsignal("clk_p", Pins("R3"), IOStandard("DIFF_SSTL15")), - Subsignal("clk_n", Pins("R2"), IOStandard("DIFF_SSTL15")), - Subsignal("cke", Pins("Y8"), IOStandard("SSTL15")), - Subsignal("odt", Pins("W9"), IOStandard("SSTL15")), + "C2 F1 B1 F3 A1 D2 B2 E2", + "J5 H3 K1 H2 J1 G2 H5 G3", + "N2 M6 P1 N5 P2 N4 R1 P6", + "K3 M2 K4 M3 J6 L5 J4 K6"), + IOStandard("SSTL15_R"), + Misc("IN_TERM=UNTUNED_SPLIT_40")), + Subsignal("dqs_p", Pins("E1 K2 P5 M1"), IOStandard("DIFF_SSTL15_R")), + Subsignal("dqs_n", Pins("D1 J2 P4 L1"), IOStandard("DIFF_SSTL15_R")), + Subsignal("clk_p", Pins("R3"), IOStandard("DIFF_SSTL15_R")), + Subsignal("clk_n", Pins("R2"), IOStandard("DIFF_SSTL15_R")), + Subsignal("cke", Pins("Y8"), IOStandard("SSTL15_R")), + Subsignal("odt", Pins("W9"), IOStandard("SSTL15_R")), Subsignal("reset_n", Pins("AB5"), IOStandard("LVCMOS15")), - Subsignal("cs_n", Pins("V9"), IOStandard("SSTL15")), + Subsignal("cs_n", Pins("V9"), IOStandard("SSTL15_R")), Misc("SLEW=FAST"), ), diff --git a/targets/netv2/Makefile.mk b/targets/netv2/Makefile.mk new file mode 100644 index 000000000..28cb76386 --- /dev/null +++ b/targets/netv2/Makefile.mk @@ -0,0 +1,48 @@ +# netv2 targets + +ifneq ($(PLATFORM),netv2) + $(error "Platform should be netv2 when using this file!?") +endif + +# Settings +DEFAULT_TARGET = net +TARGET ?= $(DEFAULT_TARGET) + +COMM_PORT ?= /dev/ttyUSB0 +BAUD ?= 115200 + +# Image +image-flash-$(PLATFORM): image-flash-py + @true + +# Gateware +gateware-load-$(PLATFORM): + @echo "Unsupported" + @false + +gateware-flash-$(PLATFORM): gateware-flash-py + @true + +# Firmware +firmware-load-$(PLATFORM): + flterm --port=$(COMM_PORT) --kernel=$(FIRMWARE_FILEBASE).bin --speed=$(BAUD) + + +firmware-flash-$(PLATFORM): firmware-flash-py + @true + +firmware-connect-$(PLATFORM): + flterm --port=$(COMM_PORT) --speed=$(BAUD) + +# Bios +bios-flash-$(PLATFORM): + @echo "Unsupported." + @false + +# Extra commands +help-$(PLATFORM): + @true + +reset-$(PLATFORM): + @echo "Unsupported." + @false diff --git a/targets/netv2/base.py b/targets/netv2/base.py new file mode 100755 index 000000000..eb5c563b0 --- /dev/null +++ b/targets/netv2/base.py @@ -0,0 +1,154 @@ +# Support for the NeTV2 board +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.soc.integration.soc_core import mem_decoder +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * +from litex.soc.interconnect import wishbone + +from litedram.modules import K4B2G1646F +from litedram.phy import a7ddrphy +from litedram.core import ControllerSettings + +from gateware import cas +from gateware import info + +from targets.utils import csr_map_update, period_ns + + +class _CRG(Module): + def __init__(self, platform): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) + self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_clk100 = ClockDomain() + self.clock_domains.cd_eth = ClockDomain() + + clk50 = platform.request("clk50") + + pll_locked = Signal() + pll_fb = Signal() + self.pll_sys = Signal() + pll_sys4x = Signal() + pll_sys4x_dqs = Signal() + pll_clk200 = Signal() + pll_clk100 = Signal() + pll_clk_eth = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1600 MHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=20.0, + p_CLKFBOUT_MULT=32, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk50, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 100 MHz + p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, + o_CLKOUT0=self.pll_sys, + + # 400 MHz + p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0, + o_CLKOUT1=pll_sys4x, + + # 400 MHz dqs + p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0, + o_CLKOUT2=pll_sys4x_dqs, + + # 200 MHz + p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0, + o_CLKOUT3=pll_clk200, + + # 50MHz + p_CLKOUT4_DIVIDE=32, p_CLKOUT4_PHASE=0.0, + o_CLKOUT4=pll_clk_eth, + + # 100MHz + p_CLKOUT5_DIVIDE=16, p_CLKOUT5_PHASE=0.0, + o_CLKOUT5=pll_clk100 + ), + Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), + Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk), + Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk), + Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), + Instance("BUFG", i_I=pll_clk100, o_O=self.cd_clk100.clk), + Instance("BUFG", i_I=pll_clk_eth, o_O=self.cd_eth.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked), + AsyncResetSynchronizer(self.cd_clk200, ~pll_locked), + AsyncResetSynchronizer(self.cd_clk100, ~pll_locked), + AsyncResetSynchronizer(self.cd_eth, ~pll_locked), + ] + + reset_counter = Signal(4, reset=15) + ic_reset = Signal(reset=1) + self.sync.clk200 += \ + If(reset_counter != 0, + reset_counter.eq(reset_counter - 1) + ).Else( + ic_reset.eq(0) + ) + self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) + + +class BaseSoC(SoCSDRAM): + csr_peripherals = ( + "ddrphy", + "info", + "cas", + ) + csr_map_update(SoCSDRAM.csr_map, csr_peripherals) + + SoCSDRAM.mem_map = { + "rom": 0x00000000, + "sram": 0x10000000, + "main_ram": 0x40000000, + "csr": 0xe0000000, + } + + mem_map = { + "spiflash": 0x20000000, + "emulator_ram": 0x50000000, + } + mem_map.update(SoCSDRAM.mem_map) + + def __init__(self, platform, csr_data_width=8, **kwargs): + if 'integrated_rom_size' not in kwargs: + kwargs['integrated_rom_size']=0x8000 + if 'integrated_sram_size' not in kwargs: + kwargs['integrated_sram_size']=0x8000 + + clk_freq = int(100e6) + SoCSDRAM.__init__(self, platform, clk_freq, csr_data_width=csr_data_width, **kwargs) + + self.submodules.crg = _CRG(platform) + self.crg.cd_sys.clk.attr.add("keep") + self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) + + # Basic peripherals + self.submodules.info = info.Info(platform, self.__class__.__name__) + self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) + + bios_size = 0x8000 + + # sdram + sdram_module = K4B2G1646F(self.clk_freq, "1:4") + self.submodules.ddrphy = a7ddrphy.A7DDRPHY( + platform.request("ddram")) + controller_settings = ControllerSettings( + with_bandwidth=True, + cmd_buffer_depth=8, + with_refresh=True) + self.register_sdram(self.ddrphy, + sdram_module.geom_settings, + sdram_module.timing_settings, + controller_settings=controller_settings) + + +SoC = BaseSoC diff --git a/targets/netv2/hdmi2pcie.py b/targets/netv2/hdmi2pcie.py new file mode 100644 index 000000000..b77c05970 --- /dev/null +++ b/targets/netv2/hdmi2pcie.py @@ -0,0 +1,133 @@ +from migen import * + +from targets.netv2.base import SoC as BaseSoC + +from litex.soc.interconnect import wishbone +from litex.soc.cores.freqmeter import FreqMeter + +from litepcie.phy.s7pciephy import S7PCIEPHY +from litepcie.core import LitePCIeEndpoint, LitePCIeMSI +from litepcie.frontend.dma import LitePCIeDMA +from litepcie.frontend.wishbone import LitePCIeWishboneBridge + +from litevideo.input import HDMIIn +from litevideo.output import VideoOut + +from targets.utils import period_ns, csr_map_update + +class WishboneEndianSwap(Module): + def __init__(self, wb_if): + self.wishbone = wishbone.Interface() + self.sync += [ + self.wishbone.adr.eq(wb_if.adr), + + self.wishbone.dat_w[0:8].eq(wb_if.dat_w[24:32]), + self.wishbone.dat_w[8:16].eq(wb_if.dat_w[16:24]), + self.wishbone.dat_w[16:24].eq(wb_if.dat_w[8:16]), + self.wishbone.dat_w[24:32].eq(wb_if.dat_w[0:8]), + #self.wishbone.dat_w.eq(wb_if.dat_w), + + wb_if.dat_r[0:8].eq(self.wishbone.dat_r[24:32]), + wb_if.dat_r[8:16].eq(self.wishbone.dat_r[16:24]), + wb_if.dat_r[16:24].eq(self.wishbone.dat_r[8:16]), + wb_if.dat_r[24:32].eq(self.wishbone.dat_r[0:8]), + #wb_if.dat_r.eq(self.wishbone.dat_r), + + self.wishbone.sel[3].eq(wb_if.sel[0]), + self.wishbone.sel[2].eq(wb_if.sel[1]), + self.wishbone.sel[1].eq(wb_if.sel[2]), + self.wishbone.sel[0].eq(wb_if.sel[3]), + #self.wishbone.sel.eq(wb_if.sel), + + self.wishbone.cyc.eq(wb_if.cyc), + self.wishbone.stb.eq(wb_if.stb), + wb_if.ack.eq(self.wishbone.ack), + self.wishbone.we.eq(wb_if.we), + self.wishbone.cti.eq(wb_if.cti), + self.wishbone.bte.eq(wb_if.bte), + wb_if.err.eq(self.wishbone.err), + ] + + +class HDMI2PCIeSoC(BaseSoC): + csr_peripherals = [ + "pcie_phy", + "pcie_dma0", + "pcie_dma1", + "pcie_msi", + + "hdmi_out0", + "hdmi_in0", + "hdmi_in0_freq", + "hdmi_in0_edid_mem", + ] + csr_map_update(BaseSoC.csr_map, csr_peripherals) + + def __init__(self, platform, *args, **kwargs): + BaseSoC.__init__(self, platform, csr_data_width=32, *args, **kwargs) + + sys_clk_freq = int(100e6) + + # pcie phy + self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x1"), bar0_size=32*1024*1024) + platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.pcie_phy.cd_pcie.clk) + + # pcie endpoint + self.submodules.pcie_endpoint = LitePCIeEndpoint(self.pcie_phy) + + # pcie wishbone bridge + self.submodules.pcie_bridge = LitePCIeWishboneBridge(self.pcie_endpoint, lambda a: 1, shadow_base=0x40000000) + self.submodules.wb_swap = WishboneEndianSwap(self.pcie_bridge.wishbone) + self.add_wb_master(self.wb_swap.wishbone) + + # pcie dma + self.submodules.pcie_dma0 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint, with_loopback=True) + + # pcie msi + self.submodules.pcie_msi = LitePCIeMSI() + self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi) + self.interrupts = { + "PCIE_DMA0_WRITER": self.pcie_dma0.writer.irq, + "PCIE_DMA0_READER": self.pcie_dma0.reader.irq + } + for i, (k, v) in enumerate(sorted(self.interrupts.items())): + self.comb += self.pcie_msi.irqs[i].eq(v) + self.add_constant(k + "_INTERRUPT", i) + + # hdmi in 0 + hdmi_in0_pads = platform.request("hdmi_in", 0) + self.submodules.hdmi_in0_freq = FreqMeter(period=sys_clk_freq) + self.submodules.hdmi_in0 = HDMIIn( + hdmi_in0_pads, + self.sdram.crossbar.get_port(mode="write"), + fifo_depth=1024, + device="xc7", + split_mmcm=True) + self.comb += self.hdmi_in0_freq.clk.eq(self.hdmi_in0.clocking.cd_pix.clk), + for clk in [self.hdmi_in0.clocking.cd_pix.clk, + self.hdmi_in0.clocking.cd_pix1p25x.clk, + self.hdmi_in0.clocking.cd_pix5x.clk]: + self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk) + self.platform.add_period_constraint(platform.lookup_request("hdmi_in", 0).clk_p, period_ns(148.5e6)) + + # hdmi out 0 + hdmi_out0_dram_port = self.sdram.crossbar.get_port(mode="read", dw=16, cd="hdmi_out0_pix", reverse=True) + self.submodules.hdmi_out0 = VideoOut( + platform.device, + platform.request("hdmi_out", 0), + hdmi_out0_dram_port, + "ycbcr422", + fifo_depth=4096) + for clk in [self.hdmi_out0.driver.clocking.cd_pix.clk, + self.hdmi_out0.driver.clocking.cd_pix5x.clk]: + self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk) + + for name, value in sorted(self.platform.hdmi_infos.items()): + self.add_constant(name, value) + + self.add_interrupt("hdmi_in0") + + +SoC = HDMI2PCIeSoC diff --git a/targets/netv2/net.py b/targets/netv2/net.py new file mode 100755 index 000000000..4b76acd53 --- /dev/null +++ b/targets/netv2/net.py @@ -0,0 +1,47 @@ +from litex.soc.integration.soc_core import mem_decoder +from litex.soc.integration.soc_sdram import * + +from liteeth.core.mac import LiteEthMAC +from liteeth.phy.rmii import LiteEthPHYRMII + +from targets.utils import csr_map_update +from targets.netv2.base import SoC as BaseSoC + + +class NetSoC(BaseSoC): + csr_peripherals = ( + "ethphy", + "ethmac", + ) + csr_map_update(BaseSoC.csr_map, csr_peripherals) + + mem_map = { + "ethmac": 0x30000000, # (shadow @0xb0000000) + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, platform, *args, **kwargs): + BaseSoC.__init__(self, platform, integrated_rom_size=0x10000, *args, **kwargs) + + self.submodules.ethphy = LiteEthPHYRMII( + platform.request("eth_clocks"), + platform.request("eth")) + self.submodules.ethmac = LiteEthMAC( + phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) + self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_memory_region("ethmac", + self.mem_map["ethmac"] | self.shadow_base, 0x2000) + + self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") + self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 40.0) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 40.0) + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.ethphy.crg.cd_eth_rx.clk, + self.ethphy.crg.cd_eth_tx.clk) + + self.add_interrupt("ethmac") + + +SoC = NetSoC From f026f84a3e3b0e13418748e3f72237326d61449b Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Thu, 21 Nov 2019 13:28:28 +0100 Subject: [PATCH 012/153] make: update pcie header generation --- make.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/make.py b/make.py index 19f16a68e..da002856d 100755 --- a/make.py +++ b/make.py @@ -153,11 +153,13 @@ def main(): vns = platform.build(soc, build_dir=os.path.join(builddir, "gateware")) if hasattr(soc, 'pcie_phy'): - from targets.common import cpu_interface - csr_header = cpu_interface.get_csr_header(soc.get_csr_regions(), soc.get_constants()) + from litex.soc.integration.export import get_csr_header, get_soc_header + csr_header = get_csr_header(soc.csr_regions, soc.constants, with_access_functions=False) + soc_header = get_soc_header(soc.constants, with_access_functions=False) kerneldir = os.path.join(builddir, "software", "pcie", "kernel") os.makedirs(kerneldir, exist_ok=True) write_to_file(os.path.join(kerneldir, "csr.h"), csr_header) + write_to_file(os.path.join(kerneldir, "soc.h"), soc_header) if hasattr(soc, 'do_exit'): soc.do_exit(vns, filename="{}/analyzer.csv".format(testdir)) From 971d1cb48212cfce16e2db7fb86eff82e1c94e4a Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Thu, 21 Nov 2019 15:23:29 +0100 Subject: [PATCH 013/153] firmware: add hdmi2pcie firmware --- firmware/Makefile | 1 + firmware/ci.c | 18 +++++++++++++++++- firmware/framebuffer.h | 18 +++++++++++------- firmware/pcie.c | 10 ++++++++++ firmware/pcie.h | 8 ++++++++ firmware/processor.c | 22 ++++++++++++++++++++++ firmware/processor.h | 9 ++++++--- 7 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 firmware/pcie.c create mode 100644 firmware/pcie.h diff --git a/firmware/Makefile b/firmware/Makefile index 9df315338..3dd09fc77 100755 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -45,6 +45,7 @@ OBJECTS=\ tofe_eeprom.o \ uptime.o \ version.o \ + pcie.o \ $(FIRMBUILD_DIRECTORY)/version_data.o \ $(FIRMBUILD_DIRECTORY)/hdmi_in1.o \ boot-helper-$(CPU).o diff --git a/firmware/ci.c b/firmware/ci.c index 4a48a46ba..c5825822d 100644 --- a/firmware/ci.c +++ b/firmware/ci.c @@ -647,6 +647,10 @@ static void video_matrix_list(void) #ifdef CSR_HDMI_IN1_BASE wprintf("input1 (1): %s\n", HDMI_IN1_MNEMONIC); wputs(HDMI_IN1_DESCRIPTION); +#endif +#ifdef CSR_PCIE_PHY_BASE + wprintf("pcie (x):\n"); + wprintf(" PCIe buffer\n"); #endif wprintf("pattern (p):\n"); wprintf(" Video pattern\n"); @@ -669,7 +673,7 @@ static void video_matrix_list(void) static void video_matrix_connect(int source, int sink) { - if(source >= 0 && source <= VIDEO_IN_PATTERN) + if(source >= 0 && source < VIDEO_IN_MAX) { if(sink >= 0 && sink <= VIDEO_OUT_HDMI_OUT1) { wprintf("Connecting %s to output%d\n", processor_get_source_name(source), sink); @@ -693,6 +697,12 @@ static void video_matrix_connect(int source, int sink) processor_set_encoder_source(source); processor_update(); } +#endif +#ifdef CSR_PCIE_PHY_BASE + else if(sink == VIDEO_OUT_PCIE) { + wprintf("Connecting %s to PCIe\n", processor_get_source_name(source)); + processor_update(); + } #endif } } @@ -1097,6 +1107,9 @@ void ci_service(void) else if((strcmp(token, "pattern") == 0) || (strcmp(token, "p") == 0)) { source = VIDEO_IN_PATTERN; } + else if((strcmp(token, "pcie") == 0) || (strcmp(token, "x") == 0)){ + source = VIDEO_IN_PCIE; + } else { wprintf("Unknown video source: '%s'\n", token); } @@ -1113,6 +1126,9 @@ void ci_service(void) else if((strcmp(token, "encoder") == 0) || (strcmp(token, "e") == 0)) { sink = VIDEO_OUT_ENCODER; } + else if((strcmp(token, "pcie") == 0) || (strcmp(token, "x") == 0)) { + sink = VIDEO_OUT_PCIE; + } else wprintf("Unknown video sink: '%s'\n", token); diff --git a/firmware/framebuffer.h b/firmware/framebuffer.h index 9fae20187..560d1efad 100644 --- a/firmware/framebuffer.h +++ b/firmware/framebuffer.h @@ -22,16 +22,17 @@ * Frame buffers must be aligned to XXX boundary. * * 0x01000000 - Pattern Buffer - Frame Buffer n + * 0x02000000 - PCIe Buffer - Frame Buffer n * * Each input then has 3 frame buffers spaced like this; * // HDMI Input 0 - * 0x02000000 - HDMI Input 0 - Frame Buffer n - * 0x02040000 - HDMI Input 0 - Frame Buffer n+1 - * 0x02080000 - HDMI Input 0 - Frame Buffer n+2 + * 0x03000000 - HDMI Input 0 - Frame Buffer n + * 0x03040000 - HDMI Input 0 - Frame Buffer n+1 + * 0x03080000 - HDMI Input 0 - Frame Buffer n+2 * // HDMI Input 1 - * 0x03000000 - HDMI Input 1 - Frame Buffer n - * 0x03040000 - HDMI Input 1 - Frame Buffer n+1 - * 0x03080000 - HDMI Input 1 - Frame Buffer n+2 + * 0x04000000 - HDMI Input 1 - Frame Buffer n + * 0x04040000 - HDMI Input 1 - Frame Buffer n+1 + * 0x04080000 - HDMI Input 1 - Frame Buffer n+2 * ... * // HDMI Input x * 0x0.000000 - HDMI Input x - Frame Buffer n @@ -41,6 +42,7 @@ */ #define FRAMEBUFFER_OFFSET 0x01000000 #define FRAMEBUFFER_PATTERNS 1 +#define FRAMEBUFFER_PCIE_BUFFERS 1 #define FRAMEBUFFER_PIXELS_X 1920 // pixels #define FRAMEBUFFER_PIXELS_Y 1080 // pixels @@ -48,7 +50,9 @@ #define FRAMEBUFFER_BASE(x) ((x+1)*FRAMEBUFFER_OFFSET) #define FRAMEBUFFER_BASE_PATTERN FRAMEBUFFER_BASE(0) -#define FRAMEBUFFER_BASE_HDMI_INPUT(x) FRAMEBUFFER_BASE(x+FRAMEBUFFER_PATTERNS) +#define FRAMEBUFFER_BASE_PCIE FRAMEBUFFER_BASE(FRAMEBUFFER_PATTERNS) +#define FRAMEBUFFER_BASE_HDMI_INPUT(x) FRAMEBUFFER_BASE(x+FRAMEBUFFER_PATTERNS+FRAMEBUFFER_PCIE_BUFFERS) + // Largest frame size at 16bpp (ish) #define FRAMEBUFFER_SIZE 0x400000 // bytes diff --git a/firmware/pcie.c b/firmware/pcie.c new file mode 100644 index 000000000..8e912277c --- /dev/null +++ b/firmware/pcie.c @@ -0,0 +1,10 @@ +#include "pcie.h" +#include "framebuffer.h" + +// Last 4 bytes of the buffer area +volatile unsigned int * pcie_in_fb_index = (unsigned int*)(MAIN_RAM_BASE + FRAMEBUFFER_BASE_PCIE + 4 * FRAMEBUFFER_SIZE - sizeof(unsigned int)); +volatile unsigned int * pcie_out_fb_index = (unsigned int*)(MAIN_RAM_BASE + FRAMEBUFFER_BASE_PCIE + 8 * FRAMEBUFFER_SIZE - sizeof(unsigned int)); + +unsigned int pcie_in_framebuffer_base(char n) { + return FRAMEBUFFER_BASE_PCIE + n * FRAMEBUFFER_SIZE; +} diff --git a/firmware/pcie.h b/firmware/pcie.h new file mode 100644 index 000000000..2f3e80e2e --- /dev/null +++ b/firmware/pcie.h @@ -0,0 +1,8 @@ +#ifndef __PCIE_H +#define __PCIE_H + +extern volatile unsigned int * pcie_out_fb_index; +extern volatile unsigned int * pcie_in_fb_index; +unsigned int pcie_in_framebuffer_base(char); + +#endif diff --git a/firmware/processor.c b/firmware/processor.c index 782f9d712..d71d2b6a4 100644 --- a/firmware/processor.c +++ b/firmware/processor.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "hdmi_in0.h" #include "hdmi_in1.h" @@ -33,6 +35,7 @@ #include "mmcm.h" #include "processor.h" #include "heartbeat.h" +#include "pcie.h" /* ----------------->>> Time ----------->>> @@ -705,6 +708,8 @@ char * processor_get_source_name(int source) { memset(processor_buffer, 0, 16); if(source == VIDEO_IN_PATTERN) sprintf(processor_buffer, "pattern"); + else if(source == VIDEO_IN_PCIE) + sprintf(processor_buffer, "pcie"); else sprintf(processor_buffer, "input%d", source); return processor_buffer; @@ -712,6 +717,9 @@ char * processor_get_source_name(int source) { void processor_update(void) { +#ifdef CSR_PCIE_PHY_BASE + unsigned int pcie_in_fb_idx = (*pcie_in_fb_index) >> 24; +#endif #ifdef CSR_HDMI_OUT0_BASE /* hdmi_out0 */ #ifdef CSR_HDMI_IN0_BASE @@ -721,9 +729,14 @@ void processor_update(void) #ifdef CSR_HDMI_IN1_BASE if(processor_hdmi_out0_source == VIDEO_IN_HDMI_IN1) hdmi_out0_core_initiator_base_write(hdmi_in1_framebuffer_base(hdmi_in1_fb_index)); +#endif +#ifdef CSR_PCIE_PHY_BASE + if(processor_hdmi_out0_source == VIDEO_IN_PCIE) + hdmi_out0_core_initiator_base_write(pcie_in_framebuffer_base(pcie_in_fb_idx)); #endif if(processor_hdmi_out0_source == VIDEO_IN_PATTERN) hdmi_out0_core_initiator_base_write(pattern_framebuffer_base()); + #endif #ifdef CSR_HDMI_OUT1_BASE @@ -735,6 +748,10 @@ void processor_update(void) #ifdef CSR_HDMI_IN1_BASE if(processor_hdmi_out1_source == VIDEO_IN_HDMI_IN1) hdmi_out1_core_initiator_base_write(hdmi_in1_framebuffer_base(hdmi_in1_fb_index)); +#endif +#ifdef CSR_PCIE_PHY_BASE + if(processor_hdmi_out0_source == VIDEO_IN_PCIE) + hdmi_out1_core_initiator_base_write(pcie_in_framebuffer_base(pcie_in_fb_idx)); #endif if(processor_hdmi_out1_source == VIDEO_IN_PATTERN) hdmi_out1_core_initiator_base_write(pattern_framebuffer_base()); @@ -757,6 +774,11 @@ void processor_update(void) encoder_reader_base_write(pattern_framebuffer_base()); #endif +#ifdef CSR_PCIE_PHY_BASE + /* PCIe capture*/ + /* FIXME: add code here when PCIe output starts to use DMA */ +#endif + #ifdef CSR_HDMI_IN0_BASE hb_service(hdmi_in0_framebuffer_base(hdmi_in0_fb_index)); #endif diff --git a/firmware/processor.h b/firmware/processor.h index 6c24b5c64..a24c02234 100644 --- a/firmware/processor.h +++ b/firmware/processor.h @@ -45,15 +45,18 @@ enum { }; enum { - VIDEO_IN_HDMI_IN0=0, + VIDEO_IN_PATTERN=0, + VIDEO_IN_HDMI_IN0, VIDEO_IN_HDMI_IN1, - VIDEO_IN_PATTERN + VIDEO_IN_PCIE, + VIDEO_IN_MAX }; enum { VIDEO_OUT_HDMI_OUT0=0, VIDEO_OUT_HDMI_OUT1, - VIDEO_OUT_ENCODER + VIDEO_OUT_ENCODER, + VIDEO_OUT_PCIE }; extern int processor_mode; From e34dc9b0fb024e3c0f469ea6318472d0afe12b93 Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Mon, 2 Dec 2019 14:30:11 +0100 Subject: [PATCH 014/153] software: add hdmi2pcie V4L2 driver --- software/hdmi2pcie/kernel/Makefile | 16 + software/hdmi2pcie/kernel/README | 9 + software/hdmi2pcie/kernel/main.c | 746 +++++++++++++++++++++++++++++ 3 files changed, 771 insertions(+) create mode 100644 software/hdmi2pcie/kernel/Makefile create mode 100644 software/hdmi2pcie/kernel/README create mode 100644 software/hdmi2pcie/kernel/main.c diff --git a/software/hdmi2pcie/kernel/Makefile b/software/hdmi2pcie/kernel/Makefile new file mode 100644 index 000000000..cd7567a47 --- /dev/null +++ b/software/hdmi2pcie/kernel/Makefile @@ -0,0 +1,16 @@ +# Makefile for kernel module + +KERNEL_VERSION:=$(shell uname -r) +KERNEL_PATH:=/lib/modules/$(KERNEL_VERSION)/build + +obj-m = hdmi2pcie.o +hdmi2pcie-objs = main.o + +all: hdmi2pcie.ko + +hdmi2pcie.ko: main.c + make -C $(KERNEL_PATH) M=$(shell pwd) modules + +clean: + make -C $(KERNEL_PATH) M=$(shell pwd) clean + rm -f *~ diff --git a/software/hdmi2pcie/kernel/README b/software/hdmi2pcie/kernel/README new file mode 100644 index 000000000..d7ceb114e --- /dev/null +++ b/software/hdmi2pcie/kernel/README @@ -0,0 +1,9 @@ +- Use 'make' to build the driver + +- Insert driver with + + insmod hdmi2pcie.ko + +- Remove driver with + + rmmod hdmi2pcie diff --git a/software/hdmi2pcie/kernel/main.c b/software/hdmi2pcie/kernel/main.c new file mode 100644 index 000000000..383b02439 --- /dev/null +++ b/software/hdmi2pcie/kernel/main.c @@ -0,0 +1,746 @@ +/* + * HDMI2PCIe driver + * + * Copyright (C) 2018 / LambdaConcept / ramtin@lambdaconcept.com + * Copyright (C) 2018 / LambdaConcept / po@lambdaconcept.com + * Copyright (C) 2018 / EnjoyDigital / florent@enjoy-digital.fr + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HDMI2PCIE_NAME "HDMI2PCIe" + +#define PCIE_FPGA_VENDOR_ID 0x10ee +#define PCIE_FPGA_DEVICE_ID 0x7022 + +#define HDMI2PCIE_DIR_IN 0 +#define HDMI2PCIE_DIR_OUT 1 + +#define PCIE_BUF_SIZE 0x400000 +#define READ_BUF_OFF (7*PCIE_BUF_SIZE) + +struct hdmi2pcie_priv_data; + +struct vid_channel { + uint8_t dir; + uint32_t sequence; + struct hdmi2pcie_priv_data *common; + + struct v4l2_device v4l2_dev; + struct video_device vdev; + struct mutex lock; + + struct v4l2_dv_timings timings; + struct v4l2_pix_format format; + + unsigned int *fb_idx; + + spinlock_t qlock; + struct vb2_queue queue; + struct list_head buf_list; +}; + +struct hdmi2pcie_priv_data { + struct pci_dev *pdev; + struct vid_channel *channels; + uint8_t chan_cnt; + /* PCIe BAR0 */ + resource_size_t bar0_size; + phys_addr_t bar0_phys_addr; + uint8_t *bar0_addr; /* virtual address of BAR0 */ +}; + +static const struct v4l2_dv_timings_cap hdmi2pcie_timings_cap = { + .type = V4L2_DV_BT_656_1120, + .reserved = { 0 }, + V4L2_INIT_BT_TIMINGS( + 640, 1920, + 480, 1080, + 25000000, 148500000, + V4L2_DV_BT_STD_CEA861, + V4L2_DV_BT_CAP_PROGRESSIVE + ) +}; + +struct hdmi2pcie_buffer { + struct vb2_v4l2_buffer vb; + struct list_head list; +}; + +static inline struct hdmi2pcie_buffer *to_hdmi2pcie_buffer(struct vb2_buffer *vb2) +{ + return container_of(vb2, struct hdmi2pcie_buffer, vb); +} + +static int queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_devs[]) +{ + struct vid_channel *chan = vb2_get_drv_priv(vq); + + if (vq->num_buffers + *nbuffers < 3) + *nbuffers = 3 - vq->num_buffers; + + if (*nplanes) + return sizes[0] < chan->format.sizeimage ? -EINVAL : 0; + + *nplanes = 1; + sizes[0] = chan->format.sizeimage; + return 0; +} + +static int buffer_prepare(struct vb2_buffer *vb) +{ + struct vid_channel *chan = vb2_get_drv_priv(vb->vb2_queue); + unsigned long size = chan->format.sizeimage; + + if (vb2_plane_size(vb, 0) < size) { + dev_err(&chan->common->pdev->dev, "buffer too small (%lu < %lu)\n", + vb2_plane_size(vb, 0), size); + return -EINVAL; + } + + vb2_set_plane_payload(vb, 0, size); + return 0; +} + +static void buffer_queue(struct vb2_buffer *vb) +{ + struct vid_channel *chan = vb2_get_drv_priv(vb->vb2_queue); + //struct hdmi2pcie_buffer *hbuf = to_hdmi2pcie_buffer(vb); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + unsigned long size = vb2_get_plane_payload(vb, 0); + void *buf = vb2_plane_vaddr(vb, 0); + unsigned long flags; + unsigned long fb_idx = (readl(chan->fb_idx) + 1) % 4; + + spin_lock_irqsave(&chan->qlock, flags); + //list_add_tail(&hbuf->list, &priv->buf_list); + if (chan->dir == HDMI2PCIE_DIR_IN) + memcpy_fromio(buf, chan->common->bar0_addr + READ_BUF_OFF, size); + else + memcpy_toio(chan->common->bar0_addr + fb_idx * PCIE_BUF_SIZE, buf, size); + + writel(fb_idx, chan->fb_idx); + + vb->timestamp = ktime_get_ns(); + vbuf->sequence = chan->sequence++; + vbuf->field = V4L2_FIELD_NONE; + + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); + + spin_unlock_irqrestore(&chan->qlock, flags); +} + +static void return_all_buffers(struct vid_channel *chan, + enum vb2_buffer_state state) +{ + struct hdmi2pcie_buffer *buf, *node; + unsigned long flags; + + spin_lock_irqsave(&chan->qlock, flags); + list_for_each_entry_safe(buf, node, &chan->buf_list, list) { + vb2_buffer_done(&buf->vb.vb2_buf, state); + list_del(&buf->list); + } + spin_unlock_irqrestore(&chan->qlock, flags); +} + +static int start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct vid_channel *chan = vb2_get_drv_priv(vq); + int ret = 0; + + chan->sequence = 0; + + //TODO: Start DMA + + if (ret) { + return_all_buffers(chan, VB2_BUF_STATE_QUEUED); + } + return ret; +} + +static void stop_streaming(struct vb2_queue *vq) +{ + struct vid_channel *chan = vb2_get_drv_priv(vq); + + return_all_buffers(chan, VB2_BUF_STATE_ERROR); +} + +static struct vb2_ops hdmi2pcie_qops = { + .queue_setup = queue_setup, + .buf_prepare = buffer_prepare, + .buf_queue = buffer_queue, + .start_streaming = start_streaming, + .stop_streaming = stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +static int hdmi2pcie_querycap(struct file *file, void *private, + struct v4l2_capability *cap) +{ + struct vid_channel *chan = video_drvdata(file); + + strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); + strlcpy(cap->card, "HDMI2PCIe", sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", + pci_name(chan->common->pdev)); + return 0; +} + +static void hdmi2pcie_fill_pix_format(struct vid_channel *chan, + struct v4l2_pix_format *pix) +{ + pix->pixelformat = V4L2_PIX_FMT_UYVY; + pix->width = chan->timings.bt.width; + pix->height = chan->timings.bt.height; + if (chan->timings.bt.interlaced) { + pix->field = V4L2_FIELD_ALTERNATE; + pix->height /= 2; + } else { + pix->field = V4L2_FIELD_NONE; + } + pix->colorspace = V4L2_COLORSPACE_REC709; + + pix->bytesperline = pix->width * 2; + pix->sizeimage = pix->bytesperline * pix->height; + pix->priv = 0; +} + +static int hdmi2pcie_try_fmt_vid(struct file *file, void *private, + struct v4l2_format *f) +{ + struct vid_channel *chan = video_drvdata(file); + struct v4l2_pix_format *pix = &f->fmt.pix; + + if (pix->pixelformat != V4L2_PIX_FMT_UYVY) { + dev_info(&chan->common->pdev->dev, "%s: wrong format\n", __PRETTY_FUNCTION__); + } + hdmi2pcie_fill_pix_format(chan, pix); + return 0; +} + +static int hdmi2pcie_s_fmt_vid(struct file *file, void *private, + struct v4l2_format *f) +{ + struct vid_channel *chan = video_drvdata(file); + int ret; + + ret = hdmi2pcie_try_fmt_vid(file, private, f); + if (ret) + return ret; + + if (vb2_is_busy(&chan->queue)) + return -EBUSY; + + // TODO: set format on the device + chan->format = f->fmt.pix; + return 0; +} + +static int hdmi2pcie_g_fmt_vid(struct file *file, void *private, + struct v4l2_format *f) +{ + struct vid_channel *chan = video_drvdata(file); + + f->fmt.pix = chan->format; + return 0; +} + +static int hdmi2pcie_enum_fmt_vid(struct file *file, void *private, + struct v4l2_fmtdesc *f) +{ + if (f->index > 0) + return -EINVAL; + + f->pixelformat = V4L2_PIX_FMT_UYVY; + return 0; +} + +static int hdmi2pcie_s_dv_timings(struct file *file, void *_fh, + struct v4l2_dv_timings *timings) +{ + struct vid_channel *chan = video_drvdata(file); + + if (!v4l2_valid_dv_timings(timings, &hdmi2pcie_timings_cap, NULL, NULL)) + return -EINVAL; + + if (!v4l2_find_dv_timings_cap(timings, &hdmi2pcie_timings_cap, + 0, NULL, NULL)) + return -EINVAL; + + if (v4l2_match_dv_timings(timings, &chan->timings, 0, false)) + return 0; + + if (vb2_is_busy(&chan->queue)) + return -EBUSY; + + chan->timings = *timings; + + hdmi2pcie_fill_pix_format(chan, &chan->format); + return 0; +} + +static int hdmi2pcie_g_dv_timings(struct file *file, void *_fh, + struct v4l2_dv_timings *timings) +{ + struct vid_channel *chan = video_drvdata(file); + + *timings = chan->timings; + return 0; +} + +static int hdmi2pcie_enum_dv_timings(struct file *file, void *_fh, + struct v4l2_enum_dv_timings *timings) +{ + return v4l2_enum_dv_timings_cap(timings, &hdmi2pcie_timings_cap, + NULL, NULL); +} + +static int hdmi2pcie_query_dv_timings(struct file *file, void *_fh, + struct v4l2_dv_timings *timings) +{ + // TODO: detect current timings/signal state (out of range, disconnected, ...) + + return 0; +} + +static int hdmi2pcie_dv_timings_cap(struct file *file, void *fh, + struct v4l2_dv_timings_cap *cap) +{ + *cap = hdmi2pcie_timings_cap; + return 0; +} + +static int hdmi2pcie_enum_input(struct file *file, void *private, + struct v4l2_input *i) +{ + if (i->index > 0) + return -EINVAL; + + i->type = V4L2_INPUT_TYPE_CAMERA; + strlcpy(i->name, "HDMI In", sizeof(i->name)); + i->capabilities = V4L2_IN_CAP_DV_TIMINGS; + return 0; +} + +static int hdmi2pcie_s_input(struct file *file, void *private, unsigned int i) +{ + struct vid_channel *chan = video_drvdata(file); + + if (i > 0) + return -EINVAL; + + if (vb2_is_busy(&chan->queue)) + return -EBUSY; + + chan->vdev.tvnorms = 0; + + hdmi2pcie_fill_pix_format(chan, &chan->format); + return 0; +} + +static int hdmi2pcie_g_input(struct file *file, void *private, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int hdmi2pcie_enum_output(struct file *file, void *private, + struct v4l2_output *i) +{ + if (i->index > 0) + return -EINVAL; + + i->type = V4L2_OUTPUT_TYPE_ANALOG; + strlcpy(i->name, "HDMI Out", sizeof(i->name)); + i->capabilities = V4L2_OUT_CAP_DV_TIMINGS; + return 0; +} + +static int hdmi2pcie_s_output(struct file *file, void *private, unsigned int i) +{ + struct vid_channel *chan = video_drvdata(file); + + if (i > 0) + return -EINVAL; + + if (vb2_is_busy(&chan->queue)) + return -EBUSY; + + chan->vdev.tvnorms = 0; + + hdmi2pcie_fill_pix_format(chan, &chan->format); + return 0; +} + +static int hdmi2pcie_g_output(struct file *file, void *private, unsigned int *i) +{ + *i = 0; + return 0; +} + +static const struct v4l2_ioctl_ops hdmi2pcie_ioctl_in_ops = { + .vidioc_querycap = hdmi2pcie_querycap, + + .vidioc_try_fmt_vid_cap = hdmi2pcie_try_fmt_vid, + .vidioc_s_fmt_vid_cap = hdmi2pcie_s_fmt_vid, + .vidioc_g_fmt_vid_cap = hdmi2pcie_g_fmt_vid, + .vidioc_enum_fmt_vid_cap = hdmi2pcie_enum_fmt_vid, + + .vidioc_s_dv_timings = hdmi2pcie_s_dv_timings, + .vidioc_g_dv_timings = hdmi2pcie_g_dv_timings, + .vidioc_enum_dv_timings = hdmi2pcie_enum_dv_timings, + .vidioc_query_dv_timings = hdmi2pcie_query_dv_timings, + .vidioc_dv_timings_cap = hdmi2pcie_dv_timings_cap, + + .vidioc_enum_input = hdmi2pcie_enum_input, + .vidioc_g_input = hdmi2pcie_g_input, + .vidioc_s_input = hdmi2pcie_s_input, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +static const struct v4l2_ioctl_ops hdmi2pcie_ioctl_out_ops = { + .vidioc_querycap = hdmi2pcie_querycap, + + .vidioc_try_fmt_vid_out = hdmi2pcie_try_fmt_vid, + .vidioc_s_fmt_vid_out = hdmi2pcie_s_fmt_vid, + .vidioc_g_fmt_vid_out = hdmi2pcie_g_fmt_vid, + .vidioc_enum_fmt_vid_out = hdmi2pcie_enum_fmt_vid, + + .vidioc_s_dv_timings = hdmi2pcie_s_dv_timings, + .vidioc_g_dv_timings = hdmi2pcie_g_dv_timings, + .vidioc_enum_dv_timings = hdmi2pcie_enum_dv_timings, + .vidioc_query_dv_timings = hdmi2pcie_query_dv_timings, + .vidioc_dv_timings_cap = hdmi2pcie_dv_timings_cap, + + .vidioc_enum_output = hdmi2pcie_enum_output, + .vidioc_g_output = hdmi2pcie_g_output, + .vidioc_s_output = hdmi2pcie_s_output, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_log_status = v4l2_ctrl_log_status, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +static const struct v4l2_file_operations hdmi2pcie_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .unlocked_ioctl = video_ioctl2, + .read = vb2_fop_read, + .mmap = vb2_fop_mmap, + .poll = vb2_fop_poll, +}; + +static int hdmi2pcie_register_video_dev(struct pci_dev *pdev, struct vid_channel *chan, uint8_t dir) +{ + static const struct v4l2_dv_timings timings_def = V4L2_DV_BT_CEA_1920X1080P60; + struct video_device *vdev = &chan->vdev; + struct vb2_queue *q = &chan->queue; + int ret; + + chan->dir = dir; + + ret = v4l2_device_register(&pdev->dev, &chan->v4l2_dev); + if (ret) { + dev_err(&pdev->dev, "v4l2_device_register failed, ret=%d\n", ret); + return ret; + } + + // Last 4 bytes of buffer area contain the buffer index used for synchronization with FPGA firmware + if (dir == HDMI2PCIE_DIR_IN) + chan->fb_idx = (unsigned int*)(chan->common->bar0_addr + 8*PCIE_BUF_SIZE - sizeof(unsigned int)); + else + chan->fb_idx = (unsigned int*)(chan->common->bar0_addr + 4*PCIE_BUF_SIZE - sizeof(unsigned int)); + + writel(0, chan->fb_idx); + + mutex_init(&chan->lock); + + q->io_modes = VB2_MMAP | VB2_DMABUF; + q->dev = &pdev->dev; + q->drv_priv = chan; + q->buf_struct_size = sizeof(struct hdmi2pcie_buffer); + q->ops = &hdmi2pcie_qops; + q->mem_ops = &vb2_dma_contig_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->min_buffers_needed = 2; + q->lock = &chan->lock; + q->gfp_flags = GFP_DMA32; + + if (dir == HDMI2PCIE_DIR_IN) { + q->io_modes |= VB2_READ; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + } else { + q->io_modes |= VB2_WRITE; + q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + } + + ret = vb2_queue_init(q); + if (ret) { + dev_err(&pdev->dev, "vb2_queue_init failed, ret=%d\n", ret); + goto v4l2_unregister; + } + + INIT_LIST_HEAD(&chan->buf_list); + spin_lock_init(&chan->qlock); + + strlcpy(vdev->name, HDMI2PCIE_NAME, sizeof(vdev->name)); + vdev->release = video_device_release_empty; + + vdev->fops = &hdmi2pcie_fops; + vdev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; + + if (dir == HDMI2PCIE_DIR_IN) { + vdev->ioctl_ops = &hdmi2pcie_ioctl_in_ops; + vdev->device_caps |= V4L2_CAP_VIDEO_CAPTURE; + } else { + vdev->ioctl_ops = &hdmi2pcie_ioctl_out_ops; + vdev->device_caps |= V4L2_CAP_VIDEO_OUTPUT; + } + + + vdev->lock = &chan->lock; + vdev->queue = q; + vdev->vfl_dir = dir ? VFL_DIR_TX : VFL_DIR_RX; + vdev->v4l2_dev = &chan->v4l2_dev; + video_set_drvdata(vdev, chan); + + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + if (ret) { + dev_err(&pdev->dev, "video_register_device failed, ret=%d\n", ret); + goto v4l2_unregister; + } + + chan->timings = timings_def; + + dev_info(&pdev->dev, "V4L2 HDMI2PCIe driver loaded"); + return 0; + +v4l2_unregister: + v4l2_device_unregister(&chan->v4l2_dev); + return ret; +} + +static int hdmi2pcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int i; + int ret; + uint8_t rev_id; + + struct device *dev = &pdev->dev; + struct hdmi2pcie_priv_data *priv; + + dev_info(dev, "\e[1m[Probing device]\e[0m\n"); + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv->chan_cnt = 2; + if(!priv) { + dev_err(dev, "Cannot allocate memory\n"); + ret = -ENOMEM; + goto fail_before_pci_device_enable; + } + priv->channels = kzalloc(sizeof(*priv->channels) * priv->chan_cnt, GFP_KERNEL); + if(!priv->channels) { + dev_err(dev, "Cannot allocate memory\n"); + ret = -ENOMEM; + goto fail_before_pci_device_enable; + } + + for (i = 0; i < priv->chan_cnt; i++) + priv->channels[i].common = priv; + + pci_set_drvdata(pdev, priv); + priv->pdev = pdev; + + ret = pci_enable_device(pdev); + if (ret != 0) { + dev_err(dev, "Cannot enable device\n"); + goto fail_before_pci_device_enable; + } + + /* check device version */ + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); + if (rev_id != 1) { + dev_err(dev, "Unsupported device version %d\n", rev_id); + goto fail_before_pci_request_regions; + } + + if (pci_request_regions(pdev, HDMI2PCIE_NAME) < 0) { + dev_err(dev, "Could not request regions\n"); + goto fail_before_pci_request_regions; + } + + /* check bar0 config */ + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { + dev_err(dev, "Invalid BAR0 configuration\n"); + goto fail_before_bar_remap; + } + + priv->bar0_addr = pci_ioremap_bar(pdev, 0); + priv->bar0_size = pci_resource_len(pdev, 0); + priv->bar0_phys_addr = pci_resource_start(pdev, 0); + if (!priv->bar0_addr) { + dev_err(dev, "Could not map BAR0\n"); + goto fail_before_bar_remap; + } + + pci_set_master(pdev); + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(dev, "Failed to set DMA mask\n"); + goto fail_before_pci_msi_enable; + }; + + ret = pci_enable_msi(pdev); + if (ret) { + dev_err(dev, "Failed to enable MSI\n"); + goto fail_before_pci_msi_enable; + } + + // TODO: in total we should register 2 input and 2 output channels, one for each HDMI port + + ret = hdmi2pcie_register_video_dev(pdev, &priv->channels[0], HDMI2PCIE_DIR_IN); + ret += hdmi2pcie_register_video_dev(pdev, &priv->channels[1], HDMI2PCIE_DIR_OUT); + if (ret) { + dev_err(dev, "Failed to register V4L2 device"); + goto fail_before_register_video_dev; + } + + return 0; + +fail_before_register_video_dev: + pci_disable_msi(pdev); +fail_before_pci_msi_enable: + pci_iounmap(pdev, priv->bar0_addr); +fail_before_bar_remap: + pci_release_regions(pdev); +fail_before_pci_request_regions: + pci_disable_device(pdev); +fail_before_pci_device_enable: + if(priv){ + if(priv->channels) + kfree(priv->channels); + kfree(priv); + } + return ret; +} + +static void hdmi2pcie_pci_remove(struct pci_dev *pdev) +{ + struct hdmi2pcie_priv_data *priv; + int i; + + priv = pci_get_drvdata(pdev); + + dev_info(&pdev->dev, "\e[1m[Removing device]\e[0m\n"); + + pci_disable_msi(pdev); + + if(priv) + pci_iounmap(pdev, priv->bar0_addr); + + for (i = 0; i < priv->chan_cnt; i++) { + video_unregister_device(&priv->channels[i].vdev); + v4l2_device_unregister(&priv->channels[i].v4l2_dev); + } + + if(priv){ + if(priv->channels) + kfree(priv->channels); + kfree(priv); + } + + pci_disable_device(pdev); + pci_release_regions(pdev); +} + +static const struct pci_device_id hdmi2pcie_pci_ids[] = { + { PCI_DEVICE(PCIE_FPGA_VENDOR_ID, PCIE_FPGA_DEVICE_ID ), }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, hdmi2pcie_pci_ids); + +static struct pci_driver hdmi2pcie_pci_driver = { + .name = HDMI2PCIE_NAME, + .id_table = hdmi2pcie_pci_ids, + .probe = hdmi2pcie_pci_probe, + .remove = hdmi2pcie_pci_remove, +}; + +static int __init hdmi2pcie_module_init(void) +{ + int ret; + + ret = pci_register_driver(&hdmi2pcie_pci_driver); + if (ret < 0) { + printk(KERN_ERR HDMI2PCIE_NAME " Error while registering PCI driver\n"); + return ret; + } + + return 0; +} + +static void __exit hdmi2pcie_module_exit(void) +{ + pci_unregister_driver(&hdmi2pcie_pci_driver); +} + + +module_init(hdmi2pcie_module_init); +module_exit(hdmi2pcie_module_exit); + +MODULE_LICENSE("GPL"); From 14a5150fbe57982309d26cbd95b0dc17e7643de4 Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Fri, 22 Nov 2019 14:01:42 +0100 Subject: [PATCH 015/153] firmware: reboot device using CSR if possible --- firmware/reboot.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/firmware/reboot.c b/firmware/reboot.c index 098622cdc..85b6f81e3 100644 --- a/firmware/reboot.c +++ b/firmware/reboot.c @@ -14,10 +14,17 @@ extern void boot_helper(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr); +#ifdef CSR_CTRL_BASE +void reboot(void) +{ + ctrl_reset_write(1); +} +#else void reboot(void) { boot(0, 0, 0, CONFIG_CPU_RESET_ADDR); } +#endif void __attribute__((noreturn)) boot(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr) { From 6797fc1b2fe84696b19a7208ec5235f8518e988a Mon Sep 17 00:00:00 2001 From: Piotr Binkowski Date: Fri, 22 Nov 2019 14:56:22 +0100 Subject: [PATCH 016/153] ci: add netv2 test runs --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index fda079eac..30614cc2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,6 +82,7 @@ env: - C=mor1kx TC="ise" P=opsis T="base net" - C=mor1kx TC="ise" P=pipistrello T="base" # VexRISCV + - C=vexriscv TC="vivado" P=netv2 T="base net" - C=vexriscv TC="vivado" P=arty T="base net" - C=vexriscv TC="vivado" P=mimas_a7 T="base net" - C=vexriscv TC="ise" P=mimasv2 T="base" @@ -117,6 +118,10 @@ env: - C=lm32 TC="ise" P=atlys T="hdmi2usb" - C=lm32 TC="ise" P=opsis T="hdmi2usb" #-------------------------------------------- + # HDMI2USB Targets + #-------------------------------------------- + - C=vexriscv TC="vivado" P=netv2 T="hdmi2pcie" + #-------------------------------------------- # MicroPython Targets #-------------------------------------------- # FIXME: Add some here From 8a7b8b53b4b8423fc159e250e143d11fa85b0f76 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Wed, 29 Jan 2020 16:04:52 +0100 Subject: [PATCH 017/153] travis: Cleanup the allow_failures. --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 30614cc2b..5a82f38cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -145,9 +145,12 @@ env: jobs: allow_failures: - - env: C=lm32 TC="vivado" P=nexys_video T="video" - env: C=mor1kx.linux TC="vivado" P=nexys_video T="net" F=linux + # Need to rebuilt Xilinx toolchain to add pano_logic_g2 part (Spartan 6 150T part) - env: C=vexriscv.lite TC="ise" P=pano_logic_g2 T="base" + # Need to rebuilt Xilinx toolchain to add NeTV2 FPGA Part (Artix 7 35T+50T parts) + - env: C=vexriscv TC="vivado" P=netv2 T="base net" + - env: C=vexriscv TC="vivado" P=netv2 T="hdmi2pcie" notifications: email: From 78bf57988994fb0cadc4a66cd8989d26286b1347 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Wed, 29 Jan 2020 17:19:28 +0100 Subject: [PATCH 018/153] travis: Also let the HDMI2USB targets fail. They non-deterministically take >50minutes to fail. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5a82f38cf..79b725b24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -151,6 +151,9 @@ jobs: # Need to rebuilt Xilinx toolchain to add NeTV2 FPGA Part (Artix 7 35T+50T parts) - env: C=vexriscv TC="vivado" P=netv2 T="base net" - env: C=vexriscv TC="vivado" P=netv2 T="hdmi2pcie" + # Occasionally these builds take longer than 50minute limit on Travis. + - env: C=lm32 TC="ise" P=atlys T="hdmi2usb" + - env: C=lm32 TC="ise" P=opsis T="hdmi2usb" notifications: email: From a18eea7694aa5a422f639d9232b163b37e0f8f1b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2020 17:04:36 +0000 Subject: [PATCH 019/153] build(deps): bump third_party/litedram from `ac4b339` to `a35a1f7` Bumps [third_party/litedram](https://github.com/enjoy-digital/litedram) from `ac4b339` to `a35a1f7`. - [Release notes](https://github.com/enjoy-digital/litedram/releases) - [Commits](https://github.com/enjoy-digital/litedram/compare/ac4b339a6fd90bb012e7fea72f1d5fd1c367af44...a35a1f7790cba537d52ccc8ae73c4e230a6cba8d) Signed-off-by: dependabot-preview[bot] --- third_party/litedram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litedram b/third_party/litedram index ac4b339a6..a35a1f779 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit ac4b339a6fd90bb012e7fea72f1d5fd1c367af44 +Subproject commit a35a1f7790cba537d52ccc8ae73c4e230a6cba8d From 382c066af061f8c9202f72488f77aa586b79a677 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2020 17:04:55 +0000 Subject: [PATCH 020/153] build(deps): bump third_party/liteeth from `f2b3f7e` to `f532a12` Bumps [third_party/liteeth](https://github.com/enjoy-digital/liteeth) from `f2b3f7e` to `f532a12`. - [Release notes](https://github.com/enjoy-digital/liteeth/releases) - [Commits](https://github.com/enjoy-digital/liteeth/compare/f2b3f7eeb1a68a4db0d9a3315994374c15e46019...f532a12b40648e84cef626e9343f428e5e366fb4) Signed-off-by: dependabot-preview[bot] --- third_party/liteeth | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/liteeth b/third_party/liteeth index f2b3f7eeb..f532a12b4 160000 --- a/third_party/liteeth +++ b/third_party/liteeth @@ -1 +1 @@ -Subproject commit f2b3f7eeb1a68a4db0d9a3315994374c15e46019 +Subproject commit f532a12b40648e84cef626e9343f428e5e366fb4 From f0e898c517fa1611ce0462f7222f92282ca6ef9a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2020 17:05:18 +0000 Subject: [PATCH 021/153] build(deps): bump third_party/litepcie from `06ee416` to `9357036` Bumps [third_party/litepcie](https://github.com/enjoy-digital/litepcie) from `06ee416` to `9357036`. - [Release notes](https://github.com/enjoy-digital/litepcie/releases) - [Commits](https://github.com/enjoy-digital/litepcie/compare/06ee416e9eedf6e44ac13b89d06c1c96d9c3dd39...935703636b20306a66d3253f34a4473f0e8d2844) Signed-off-by: dependabot-preview[bot] --- third_party/litepcie | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litepcie b/third_party/litepcie index 06ee416e9..935703636 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit 06ee416e9eedf6e44ac13b89d06c1c96d9c3dd39 +Subproject commit 935703636b20306a66d3253f34a4473f0e8d2844 From ee422731927cc1a61b6156ae91a726308675bba8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2020 17:06:48 +0000 Subject: [PATCH 022/153] build(deps): bump third_party/litesata from `b400655` to `1e3573b` Bumps [third_party/litesata](https://github.com/enjoy-digital/litesata) from `b400655` to `1e3573b`. - [Release notes](https://github.com/enjoy-digital/litesata/releases) - [Commits](https://github.com/enjoy-digital/litesata/compare/b40065591fa4c41b22da1830ae253a1efd8d3d0b...1e3573b07d382eac50ef764fd839009bf90cb8ce) Signed-off-by: dependabot-preview[bot] --- third_party/litesata | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litesata b/third_party/litesata index b40065591..1e3573b07 160000 --- a/third_party/litesata +++ b/third_party/litesata @@ -1 +1 @@ -Subproject commit b40065591fa4c41b22da1830ae253a1efd8d3d0b +Subproject commit 1e3573b07d382eac50ef764fd839009bf90cb8ce From dc15055c885eadeec659a63892299c3776c2071b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2020 17:06:49 +0000 Subject: [PATCH 023/153] build(deps): bump third_party/litex-renode from `f082da2` to `70e884e` Bumps [third_party/litex-renode](https://github.com/litex-hub/litex-renode) from `f082da2` to `70e884e`. - [Release notes](https://github.com/litex-hub/litex-renode/releases) - [Commits](https://github.com/litex-hub/litex-renode/compare/f082da2e1093bf7033b8842a502f21f295591f3f...70e884e88c25d997ea5e3dd1e2a8bb08f0d02f90) Signed-off-by: dependabot-preview[bot] --- third_party/litex-renode | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litex-renode b/third_party/litex-renode index f082da2e1..70e884e88 160000 --- a/third_party/litex-renode +++ b/third_party/litex-renode @@ -1 +1 @@ -Subproject commit f082da2e1093bf7033b8842a502f21f295591f3f +Subproject commit 70e884e88c25d997ea5e3dd1e2a8bb08f0d02f90 From e448e631a8fefad3ee10f909eef21c8c1b09143d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2020 17:07:05 +0000 Subject: [PATCH 024/153] build(deps): bump third_party/flash_proxies from `01d8f81` to `3a06aa8` Bumps [third_party/flash_proxies](https://github.com/jordens/bscan_spi_bitstreams) from `01d8f81` to `3a06aa8`. - [Release notes](https://github.com/jordens/bscan_spi_bitstreams/releases) - [Commits](https://github.com/jordens/bscan_spi_bitstreams/compare/01d8f819f15baf9a8cc5d96945a51e4d267ff564...3a06aa84b62ad24467fb0d2c6ceddf565e9ea447) Signed-off-by: dependabot-preview[bot] --- third_party/flash_proxies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/flash_proxies b/third_party/flash_proxies index 01d8f819f..3a06aa84b 160000 --- a/third_party/flash_proxies +++ b/third_party/flash_proxies @@ -1 +1 @@ -Subproject commit 01d8f819f15baf9a8cc5d96945a51e4d267ff564 +Subproject commit 3a06aa84b62ad24467fb0d2c6ceddf565e9ea447 From 23dca80fc2096bbac095115f7d293c9f846060bf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 29 Jan 2020 17:07:24 +0000 Subject: [PATCH 025/153] build(deps): bump third_party/litescope from `1448b55` to `daf10e9` Bumps [third_party/litescope](https://github.com/enjoy-digital/litescope) from `1448b55` to `daf10e9`. - [Release notes](https://github.com/enjoy-digital/litescope/releases) - [Commits](https://github.com/enjoy-digital/litescope/compare/1448b5581901ba54b764f7a78268892ae8f5efff...daf10e9473fb70b3034e0331ef89005661ac04e0) Signed-off-by: dependabot-preview[bot] --- third_party/litescope | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litescope b/third_party/litescope index 1448b5581..daf10e947 160000 --- a/third_party/litescope +++ b/third_party/litescope @@ -1 +1 @@ -Subproject commit 1448b5581901ba54b764f7a78268892ae8f5efff +Subproject commit daf10e9473fb70b3034e0331ef89005661ac04e0 From 13bbeb6c471b538bc16a7c711c28645529bbecd3 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 18 Oct 2019 15:39:34 +0200 Subject: [PATCH 026/153] Use custom config & DTS overlay for Zephyr --- scripts/build-zephyr.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/build-zephyr.sh b/scripts/build-zephyr.sh index 8283eee1a..293d81344 100755 --- a/scripts/build-zephyr.sh +++ b/scripts/build-zephyr.sh @@ -77,16 +77,32 @@ if [ "$FIRMWARE" != "zephyr" ]; then fi ZEPHYR_SRC_DIR=$THIRD_DIR/zephyr -ZEPHYR_APP=${ZEPHYR_APP:-subsys/shell/shell_module} OUTPUT_DIR=$TOP_DIR/$TARGET_BUILD_DIR/software/zephyr export ZEPHYR_BASE=$ZEPHYR_SRC_DIR/zephyr +ZEPHYR_APP=$ZEPHYR_BASE/samples/${ZEPHYR_APP:-subsys/shell/shell_module} if [ ! -d "$ZEPHYR_SRC_DIR" ]; then mkdir -p $ZEPHYR_SRC_DIR cd $ZEPHYR_SRC_DIR - west init --manifest-url $ZEPHYR_REPO --manifest-rev $ZEPHYR_REPO_BRANCH + west init \ + --manifest-url $ZEPHYR_REPO \ + --manifest-rev $ZEPHYR_REPO_BRANCH fi -west build -b $TARGET_BOARD $ZEPHYR_SRC_DIR/zephyr/samples/$ZEPHYR_APP --build-dir $OUTPUT_DIR -- -DZEPHYR_SDK_INSTALL_DIR=$ZEPHYR_SDK_INSTALL_DIR + +# generate DTS from LiteX configuration +mkdir -p $OUTPUT_DIR +$THIRD_DIR/litex-renode/generate-zephyr-dts.py \ + --dts $OUTPUT_DIR/litex.overlay \ + --config $OUTPUT_DIR/config.overlay \ + $TOP_DIR/$TARGET_BUILD_DIR/test/csr.csv + +cat $OUTPUT_DIR/config.overlay | xargs west build \ + -b $TARGET_BOARD \ + --build-dir $OUTPUT_DIR \ + $ZEPHYR_APP \ + -- \ + -DZEPHYR_SDK_INSTALL_DIR=$ZEPHYR_SDK_INSTALL_DIR \ + -DDTC_OVERLAY_FILE=$OUTPUT_DIR/litex.overlay cd $OUTPUT_DIR if [ ! -f "firmware.bin" ]; then From 3806d3e371350c481bfa9831301df49864cb6495 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 21 Jan 2020 15:22:59 +0100 Subject: [PATCH 027/153] Update waxwing pin mappings according to official UCF --- platforms/waxwing.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/platforms/waxwing.py b/platforms/waxwing.py index 1d524431c..2f7b5ae7d 100644 --- a/platforms/waxwing.py +++ b/platforms/waxwing.py @@ -1,6 +1,11 @@ # Support for the Numato Waxwing Spartan 6 Development Module # https://numato.com/product/waxwing-spartan-6-fpga-development-board - +# +# Updated to: +# https://productdata.numato.com/assets/downloads/fpga/waxwing/developmentboard/WaxwingSpartan6DevelopmentBoardV3.ucf +# +# Note: To use serial over FTDI change channel B to UART mode and +# set driver to Virtual COM port using FTProg tool or similar from litex.build.generic_platform import * from litex.build.xilinx import XilinxPlatform @@ -9,21 +14,19 @@ ("clk100", 0, Pins("V10"), IOStandard("LVTTL")), ("serial", 0, - Subsignal("tx", Pins("L18")), - Subsignal("rx", Pins("L17"), Misc("PULLUP")), - Subsignal("cts", Pins("M16"), Misc("PULLUP")), - Subsignal("rts", Pins("M18"), Misc("PULLUP")), + Subsignal("tx", Pins("M11")), + Subsignal("rx", Pins("N11")), IOStandard("LVTTL") ), #the board has a FTDI FT2232H ("usb_fifo", 0, - Subsignal("data", Pins("L17 L18 M16 M18 N17 N18 P17 P18")), - Subsignal("rxf_n", Pins("K18")), - Subsignal("txe_n", Pins("K17")), - Subsignal("rd_n", Pins("J18")), - Subsignal("wr_n", Pins("J16")), - Subsignal("siwua", Pins("H18")), + Subsignal("data", Pins("N11 M11 T14 V14 N18 N17 V11 U11")), + Subsignal("rxf_n", Pins("V13")), + Subsignal("txe_n", Pins("U13")), + Subsignal("rd_n", Pins("V15")), + Subsignal("wr_n", Pins("U15")), + Subsignal("siwua", Pins("T17")), IOStandard("LVTTL"), ), From 67d6798abd32f0b595dac557de9c8785649e6c27 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 21 Jan 2020 15:23:18 +0100 Subject: [PATCH 028/153] Added net configuration for waxwing --- targets/waxwing/net.py | 263 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100755 targets/waxwing/net.py diff --git a/targets/waxwing/net.py b/targets/waxwing/net.py new file mode 100755 index 000000000..b4338f1a1 --- /dev/null +++ b/targets/waxwing/net.py @@ -0,0 +1,263 @@ +# Support for the Numato Saturn (http://numato.com/product/saturn-spartan-6-fpga-development-board-with-ddr-sdram) +# Original code from : https://github.com/timvideos/litex-buildenv/blob/master/targets/waxwing/base.py +# By Rohit Singh + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.build.generic_platform import * + +from litex.soc.cores.clock import * +from litex.soc.integration.soc_core import * +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * + +from litedram.modules import MT46H32M16 +from litedram.phy import s6ddrphy +from litedram.core import ControllerSettings + +from targets.utils import csr_map_update +from liteeth.phy.mii import LiteEthPHYMII +from liteeth.mac import LiteEthMAC + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + self.clock_domains.cd_eth = ClockDomain() + + # Input 100MHz clock + f0 = Fraction(100, 1)*1000000 + clk100 = platform.request("clk100") + clk100a = Signal() + # Input 100MHz clock (buffered) + self.specials += Instance( + "IBUFG", + i_I=clk100, + o_O=clk100a + ) + + clk100b = Signal() + + self.specials += Instance( + "BUFIO2", + p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk100a, + o_DIVCLK=clk100b + ) + + #PLL parameters + f = Fraction(10, 1) + n, d = f.numerator, f.denominator + p = 8 + + assert f0*n/d/p/4 == clk_freq + assert 19e6 <= f0/d <= 500e6 # pfd + assert 400e6 <= f0*n/d <= 1000e6 # vco + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_unused_a = Signal() + unbuf_eth = Signal() + unbuf_sys = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=d, + # Input Clocks (100MHz) + i_CLKIN1=clk100b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., + # Outputs + # (125 MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p, + # (125 MHz) unused + o_CLKOUT1=unbuf_unused_a, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p, + # (62.5 MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=(p*2), + # (62.5 MHz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=(p*2), + # (25.00 MHz) eth + o_CLKOUT4=unbuf_eth, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=(p*5), + # (31.25 MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=(p*4), + ) + + #power on reset? + reset = ~platform.request("user_btn", 0) + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + #System clock + self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance( + "BUFPLL", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, + i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb + ) + + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + + # ethernet + self.specials += Instance( + "BUFG", + i_I=unbuf_eth, + o_O=self.cd_eth.clk + ) + + # sdram_half + self.specials += Instance( + "BUFG", + i_I=unbuf_sdram_half_a, + o_O=self.cd_sdram_half.clk + ) + + clk_sdram_half_shifted = Signal() + self.specials += Instance( + "BUFG", + i_I=unbuf_sdram_half_b, + o_O=clk_sdram_half_shifted + ) + + clk = platform.request("ddram_clock") + self.specials += Instance( + "ODDR2", + p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.p + ) + + self.specials += Instance( + "ODDR2", + p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.n + ) + +# BaseSoC ------------------------------------------------------------------------------------------ + +class BaseSoC(SoCSDRAM): + + def __init__(self, platform, **kwargs): + if 'integrated_rom_size' not in kwargs: + kwargs['integrated_rom_size']=0x8000 + if 'integrated_sram_size' not in kwargs: + kwargs['integrated_sram_size']=0x8000 + + clk_freq = (31 + Fraction(1, 4))*1000*1000 + SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) + + self.submodules.crg = _CRG(platform, clk_freq) + + # sdram + if not self.integrated_main_ram_size: + sdram_module = MT46H32M16(clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram"), + sdram_module.memtype, + rd_bitslip=2, + wr_bitslip=3, + dqs_ddr_alignment="C1" + ) + self.add_csr("ddrphy") + + self.register_sdram(self.ddrphy, + sdram_module.geom_settings, + sdram_module.timing_settings, + controller_settings=ControllerSettings( + with_bandwidth=True) + ) + + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + +# EthernetSoC -------------------------------------------------------------------------------------- + +class EthernetSoC(BaseSoC): + mem_map = { + "ethmac": 0xb0000000, + } + mem_map.update(BaseSoC.mem_map) + + def __init__(self, platform, *args, **kwargs): + # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. + if 'integrated_rom_size' not in kwargs: + kwargs['integrated_rom_size'] = 0x10000 + BaseSoC.__init__(self, platform, *args, **kwargs) + + self.submodules.ethphy = LiteEthPHYMII(self.platform.request("eth_clocks"), + self.platform.request("eth")) + self.add_csr("ethphy") + self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, + interface="wishbone", endianness=self.cpu.endianness) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") + self.add_csr("ethmac") + self.add_interrupt("ethmac") + self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") + self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") + #self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 1e9/12.5e6) + #self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 1e9/12.5e6) + #self.platform.add_false_path_constraints( + # self.crg.cd_sys.clk, + # self.ethphy.crg.cd_eth_rx.clk, + # self.ethphy.crg.cd_eth_tx.clk) + +SoC = EthernetSoC From 1e8165efee6fa6e89aeb4af0b86854fa9b8b1115 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 21 Jan 2020 19:17:21 +0100 Subject: [PATCH 029/153] Add emulator_ram section --- targets/waxwing/net.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/targets/waxwing/net.py b/targets/waxwing/net.py index b4338f1a1..ec8c6cb02 100755 --- a/targets/waxwing/net.py +++ b/targets/waxwing/net.py @@ -22,6 +22,8 @@ from liteeth.phy.mii import LiteEthPHYMII from liteeth.mac import LiteEthMAC +from litex.soc.interconnect import wishbone + # CRG ---------------------------------------------------------------------------------------------- class _CRG(Module): @@ -192,6 +194,10 @@ def __init__(self, platform, clk_freq): # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCSDRAM): + mem_map = { + "emulator_ram": 0x50000000, # (default shadow @0xd0000000) + } + mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): if 'integrated_rom_size' not in kwargs: @@ -204,6 +210,11 @@ def __init__(self, platform, **kwargs): self.submodules.crg = _CRG(platform, clk_freq) + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) + # sdram if not self.integrated_main_ram_size: sdram_module = MT46H32M16(clk_freq, "1:2") From 813a42d1070baa675dbe12d4618a8803d3bd3452 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Tue, 21 Jan 2020 19:21:11 +0100 Subject: [PATCH 030/153] Set notes for different configurations of FTDI chip --- platforms/waxwing.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platforms/waxwing.py b/platforms/waxwing.py index 2f7b5ae7d..0a464b54e 100644 --- a/platforms/waxwing.py +++ b/platforms/waxwing.py @@ -4,8 +4,6 @@ # Updated to: # https://productdata.numato.com/assets/downloads/fpga/waxwing/developmentboard/WaxwingSpartan6DevelopmentBoardV3.ucf # -# Note: To use serial over FTDI change channel B to UART mode and -# set driver to Virtual COM port using FTProg tool or similar from litex.build.generic_platform import * from litex.build.xilinx import XilinxPlatform @@ -13,13 +11,18 @@ _io = [ ("clk100", 0, Pins("V10"), IOStandard("LVTTL")), + # The board has a FTDI FT2232H so different configurtaion is possible + # Note: To use serial over FTDI change channel B to UART mode and + # set driver to Virtual COM port using FTProg tool or similar ("serial", 0, Subsignal("tx", Pins("M11")), Subsignal("rx", Pins("N11")), IOStandard("LVTTL") ), - #the board has a FTDI FT2232H + # The board has a FTDI FT2232H so different configurtaion is possible + # Note: To use usb_fifo change channel B to 245FIFO mode and + # set driver to D2XX Direct using FTProg tool or similar ("usb_fifo", 0, Subsignal("data", Pins("N11 M11 T14 V14 N18 N17 V11 U11")), Subsignal("rxf_n", Pins("V13")), From 97fb82e16a7705c580f369e03fadb14a52344835 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Wed, 15 Jan 2020 13:27:19 +1000 Subject: [PATCH 031/153] make.py: Fix image name. --- make.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make.py b/make.py index da002856d..5b4892492 100755 --- a/make.py +++ b/make.py @@ -69,7 +69,7 @@ def get_prog(args, platform): def get_image(builddir, filetype): assert filetype == "flash" - return os.path.join(builddir, "image.bin") + return os.path.join(builddir, "image-gateware+bios+firmware.bin") def get_gateware(builddir, filetype): From aaa46baa7760f5df608e82ae2d1982a9fd7c2706 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2020 19:35:43 +0000 Subject: [PATCH 032/153] build(deps): bump third_party/litepcie from `9357036` to `061418c` Bumps [third_party/litepcie](https://github.com/enjoy-digital/litepcie) from `9357036` to `061418c`. - [Release notes](https://github.com/enjoy-digital/litepcie/releases) - [Commits](https://github.com/enjoy-digital/litepcie/compare/935703636b20306a66d3253f34a4473f0e8d2844...061418c620cb09e32aafc202ed1379a29c49cc17) Signed-off-by: dependabot-preview[bot] --- third_party/litepcie | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litepcie b/third_party/litepcie index 935703636..061418c62 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit 935703636b20306a66d3253f34a4473f0e8d2844 +Subproject commit 061418c620cb09e32aafc202ed1379a29c49cc17 From a335d0a76c400c7a9fa12751d43c73514d33815f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2020 19:36:05 +0000 Subject: [PATCH 033/153] build(deps): bump third_party/litedram from `a35a1f7` to `5a90a8b` Bumps [third_party/litedram](https://github.com/enjoy-digital/litedram) from `a35a1f7` to `5a90a8b`. - [Release notes](https://github.com/enjoy-digital/litedram/releases) - [Commits](https://github.com/enjoy-digital/litedram/compare/a35a1f7790cba537d52ccc8ae73c4e230a6cba8d...5a90a8b0dde504d383ffcc3c1ad6e0724caf5713) Signed-off-by: dependabot-preview[bot] --- third_party/litedram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litedram b/third_party/litedram index a35a1f779..5a90a8b0d 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit a35a1f7790cba537d52ccc8ae73c4e230a6cba8d +Subproject commit 5a90a8b0dde504d383ffcc3c1ad6e0724caf5713 From 4a022e1bf41efdecd7e60a7b6e48f2462dd72d7f Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 31 Jan 2020 19:36:23 +0000 Subject: [PATCH 034/153] build(deps): bump third_party/migen from `0d0e17a` to `d11565a` Bumps [third_party/migen](https://github.com/m-labs/migen) from `0d0e17a` to `d11565a`. - [Release notes](https://github.com/m-labs/migen/releases) - [Commits](https://github.com/m-labs/migen/compare/0d0e17a5e65fc21a2f08a16b55594739c98cf89e...d11565a8ead28eb5a18d7d4f57abe2a7562cdc8c) Signed-off-by: dependabot-preview[bot] --- third_party/migen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/migen b/third_party/migen index 0d0e17a5e..d11565a8e 160000 --- a/third_party/migen +++ b/third_party/migen @@ -1 +1 @@ -Subproject commit 0d0e17a5e65fc21a2f08a16b55594739c98cf89e +Subproject commit d11565a8ead28eb5a18d7d4f57abe2a7562cdc8c From 070cef4b8078c041ac8a416e8a259648c8c73a65 Mon Sep 17 00:00:00 2001 From: Piotr Zierhoffer Date: Tue, 4 Feb 2020 22:51:30 +0100 Subject: [PATCH 035/153] Bump Zephyr SDK version --- scripts/settings.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/settings.sh b/scripts/settings.sh index 51328d9c7..3fd1276ee 100644 --- a/scripts/settings.sh +++ b/scripts/settings.sh @@ -20,7 +20,7 @@ SDCC_VERSION=3.5.0 OPENOCD_VERSION=0.10.0 # Other tools versions -ZEPHYR_SDK_VERSION=0.10.3 +ZEPHYR_SDK_VERSION=0.11.1 # lite modules LITE_REPOS=" From 91fe41bae6bb41f4400109b96282cb1c1a649f03 Mon Sep 17 00:00:00 2001 From: Andres Calderon Date: Fri, 7 Feb 2020 17:02:13 -0500 Subject: [PATCH 036/153] MATRIX Voice supported --- platforms/matrix_voice.py | 96 +++++++++++++ targets/matrix_voice/Makefile.mk | 49 +++++++ targets/matrix_voice/base.py | 228 +++++++++++++++++++++++++++++++ 3 files changed, 373 insertions(+) create mode 100644 platforms/matrix_voice.py create mode 100644 targets/matrix_voice/Makefile.mk create mode 100644 targets/matrix_voice/base.py diff --git a/platforms/matrix_voice.py b/platforms/matrix_voice.py new file mode 100644 index 000000000..d29ce96dd --- /dev/null +++ b/platforms/matrix_voice.py @@ -0,0 +1,96 @@ +# Support for the MATRIX Voice +# https://www.matrix.one/products/voice +# Author: Andres Calderon +# FPGA: Spartan 6 xc6slx9-2-ftg256 +# Copyright 2020 MATRIX Labs +# License: BSD + +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform + +_io = [ + ("clk50", 0, Pins("T7"), IOStandard("LVCMOS33")), +# RPI_GPIO26 + ("cpu_reset", 0, Pins("N6"), IOStandard("LVCMOS33"), Misc("PULLUP")), + + ("serial", 0, + Subsignal("tx", Pins("B12"), IOStandard("LVCMOS33"), + Misc("SLEW=FAST")), + Subsignal("rx", Pins("A12"), IOStandard("LVCMOS33"), + Misc("SLEW=FAST"))), + + ("spiflash", 0, + Subsignal("cs_n", Pins("T3")), + Subsignal("clk", Pins("R11")), + Subsignal("mosi", Pins("T10")), + Subsignal("miso", Pins("P10"), Misc("PULLUP")), + IOStandard("LVCMOS33"), Misc("SLEW=FAST")), + + ("ddram_clock", 0, + Subsignal("p", Pins("G12")), + Subsignal("n", Pins("H11")), + IOStandard("DIFF_SSTL18_II"), Misc("IN_TERM=NONE")), + + ("ddram", 0, + Subsignal( + "a", +# 0 1 2 3 4 5 6 7 8 9 10 11 12 + Pins("H15 H16 F16 H13 C16 J11 J12 F15 F13 F14 C15 G11 D16"), + IOStandard("SSTL18_II") + ), + Subsignal("ba", Pins("G14 G16"), IOStandard("SSTL18_II")), + Subsignal("cke", Pins("D14"), IOStandard("SSTL18_II")), + Subsignal("ras_n", Pins("J13"), IOStandard("SSTL18_II")), + Subsignal("cas_n", Pins("K14"), IOStandard("SSTL18_II")), + Subsignal("we_n", Pins("E15"), IOStandard("SSTL18_II")), + Subsignal( + "dq", +# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + Pins("L14 L16 M15 M16 J14 J16 K15 K16 P15 P16 R15 R16 T14 T13 R12 T12"), + IOStandard("SSTL18_II") + ), + Subsignal("dqs", Pins("R14 N14"), IOStandard("DIFF_SSTL18_II")), + Subsignal("dqs_n", Pins("T15 N16"), IOStandard("DIFF_SSTL18_II")), + Subsignal("dm", Pins("K12 K11"), IOStandard("SSTL18_II")), + Subsignal("odt", Pins("H14"), IOStandard("SSTL18_II")) + ), + + # LED + ("user_led", 0, Pins("T5"), IOStandard("LVCMOS33"), Drive(8)), +] + +_connectors = [ + ("P2", "G1 G3 H1 H2 J1 J3 K1 K2 L1 M1 M2 N1 P1 P2 R1 R2"), +] + +class Platform(XilinxPlatform): + name = "matrix_voice" + default_clk_name = "clk50" + default_clk_period = 20 + + gateware_size = 0x180000 + + spiflash_model = "25l6405" + spiflash_read_dummy_bits = 4 + spiflash_clock_div = 4 + spiflash_total_size = int((64/8)*1024*1024) # 64Mbit + spiflash_page_size = 256 + spiflash_sector_size = 0x10000 + + def __init__(self, device="xc6slx9", programmer="xc3sprog"): + XilinxPlatform.__init__(self, device+"-2-ftg256", _io, _connectors) + self.programmer = programmer + + def create_programmer(self): + proxy="bscan_spi_{}.bit".format(self.device.split('-')[0]) + if self.programmer == "xc3sprog": + return XC3SProg("matrix_voice", proxy) + else: + raise ValueError("{} programmer is not supported".format(self.programmer)) + + def do_finalize(self, fragment): + XilinxPlatform.do_finalize(self, fragment) + try: + self.add_period_constraint(self.lookup_request("clk50", 0), 20) + except ConstraintError: + pass diff --git a/targets/matrix_voice/Makefile.mk b/targets/matrix_voice/Makefile.mk new file mode 100644 index 000000000..abc55a144 --- /dev/null +++ b/targets/matrix_voice/Makefile.mk @@ -0,0 +1,49 @@ +# matrix_voice targets + +ifneq ($(PLATFORM),matrix_voice) + $(error "Platform should be matrix_voice when using this file!?") +endif + +# Settings +DEFAULT_TARGET = base +TARGET ?= $(DEFAULT_TARGET) + +# Image +image-flash-$(PLATFORM): + @echo "MATRIX Voice doesn't support just flashing firmware from PC, try xc3sprog running in the Raspberry instead." + +# Gateware +gateware-load-$(PLATFORM): + @echo "MATRIX Voice doesn't support just flashing firmware from PC, try xc3sprog running in the Raspberry instead." + @false + +gateware-flash-$(PLATFORM): $(GATEWARE_BIOS_FILE) + @echo "MATRIX Voice doesn't support just flashing firmware from PC, try xc3sprog running in the Raspberry instead." + @false + +firmware-load-$(PLATFORM): + @echo "MATRIX Voice doesn't support firmware load from PC, try flterm running in the Raspberry instead." + @false + +firmware-flash-$(PLATFORM): + @echo "MATRIX Voice doesn't support flashing firmware from PC, try flterm running in the Raspberry instead." + @false + +firmware-connect-$(PLATFORM): + @echo "MATRIX Voice doesn't support connect from PC, try flterm running in the Raspberry instead." + +firmware-clear-$(PLATFORM): + @echo "Unsupported." + @false + +bios-flash-$(PLATFORM): + @echo "Unsupported." + @false + +help-$(PLATFORM): + @true + +reset-$(PLATFORM): + @echo "Unsupported." + @false + diff --git a/targets/matrix_voice/base.py b/targets/matrix_voice/base.py new file mode 100644 index 000000000..f770654f2 --- /dev/null +++ b/targets/matrix_voice/base.py @@ -0,0 +1,228 @@ +# Support for the MATRIX Voice +# https://www.matrix.one/products/voice +# Author: Andres Calderon +# FPGA: Spartan 6 xc6slx9-2-ftg256 +# Copyright 2020 MATRIX Labs +# License: BSD + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer +from migen.genlib.misc import WaitTimer + +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * + +from litedram.modules import MT47H32M16 +from litedram.phy import s6ddrphy +from litedram.core import ControllerSettings + +from gateware import cas +from gateware import info +from gateware import spi_flash + +from targets.utils import csr_map_update + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + # Clock domain for peripherals (such as HDMI output). + self.clock_domains.cd_base50 = ClockDomain() + self.clock_domains.cd_encoder = ClockDomain() + + self.reset = Signal() + + # Input 50MHz clock + f0 = 50*1000*1000 + clk50 = platform.request("clk50") + clk50a = Signal() + # Input 50MHz clock (buffered) + self.specials += Instance( + "IBUFG", + i_I=clk50, + o_O=clk50a + ) + clk50b = Signal() + self.specials += Instance( + "BUFIO2", + p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", + p_I_INVERT="FALSE", + i_I=clk50a, + o_DIVCLK=clk50b + ) + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_unused = Signal() + unbuf_sys = Signal() + unbuf_periph = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=1, + # Input Clocks (50MHz) + i_CLKIN1=clk50b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=18, p_CLKFBOUT_PHASE=0., + # (300MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=3, + # unused (available) + o_CLKOUT1=unbuf_unused, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=6, + # (150MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=6, + # (150Hz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=6, + # ( 75MHz) periph + o_CLKOUT4=unbuf_periph, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=12, + # ( 75MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=12, + ) + + + # power on reset + reset = ~platform.request("cpu_reset",0) | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - 75MHz + self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", + name="sdram_half_a_bufpll", + i_I=unbuf_sdram_half_a, + o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", + name="sdram_half_b_bufpll", + i_I=unbuf_sdram_half_b, + o_O=clk_sdram_half_shifted) + + output_clk = Signal() + clk = platform.request("ddram_clock") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=output_clk) + self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) + + +class BaseSoC(SoCSDRAM): + csr_peripherals = ( + "spiflash", + "ddrphy", + "info", + "cas", + ) + csr_map_update(SoCSDRAM.csr_map, csr_peripherals) + + mem_map = { + "spiflash": 0x20000000, # (default shadow @0xa0000000) + } + mem_map.update(SoCSDRAM.mem_map) + + def __init__(self, platform, **kwargs): + if 'integrated_rom_size' not in kwargs: + kwargs['integrated_rom_size']=0x8000 + if 'integrated_sram_size' not in kwargs: + kwargs['integrated_sram_size']=0x4000 + + kwargs['uart_baudrate']=230400 + + clk_freq = 75*1000*1000 + + SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) + + self.submodules.crg = _CRG(platform, clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) + + # Basic peripherals + self.submodules.info = info.Info(platform, self.__class__.__name__) + self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + + # spi flash + self.submodules.spiflash = spi_flash.SpiFlashSingle( + platform.request("spiflash"), + dummy=platform.spiflash_read_dummy_bits, + div=platform.spiflash_clock_div) + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.register_mem("spiflash", self.mem_map["spiflash"], + self.spiflash.bus, size=platform.spiflash_total_size) + + bios_size = 0x8000 + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size + self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + + # sdram + sdram_module = MT47H32M16(self.clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram"), + sdram_module.memtype, + rd_bitslip=0, + wr_bitslip=4, + dqs_ddr_alignment="C0") + controller_settings = ControllerSettings(with_bandwidth=True) + self.register_sdram(self.ddrphy, + sdram_module.geom_settings, + sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + +SoC = BaseSoC From 72670eec614a989a83c13c95b3f78733066ad18c Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 12 Feb 2020 12:58:29 +0100 Subject: [PATCH 037/153] build-zephyr: Generate csr.csv before DTS overlay --- scripts/build-zephyr.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/build-zephyr.sh b/scripts/build-zephyr.sh index 293d81344..f05903425 100755 --- a/scripts/build-zephyr.sh +++ b/scripts/build-zephyr.sh @@ -81,6 +81,11 @@ OUTPUT_DIR=$TOP_DIR/$TARGET_BUILD_DIR/software/zephyr export ZEPHYR_BASE=$ZEPHYR_SRC_DIR/zephyr ZEPHYR_APP=$ZEPHYR_BASE/samples/${ZEPHYR_APP:-subsys/shell/shell_module} +LITEX_CONFIG_FILE="$TOP_DIR/$TARGET_BUILD_DIR/test/csr.csv" +if [ ! -f "$LITEX_CONFIG_FILE" ]; then + make firmware +fi + if [ ! -d "$ZEPHYR_SRC_DIR" ]; then mkdir -p $ZEPHYR_SRC_DIR cd $ZEPHYR_SRC_DIR @@ -94,7 +99,7 @@ mkdir -p $OUTPUT_DIR $THIRD_DIR/litex-renode/generate-zephyr-dts.py \ --dts $OUTPUT_DIR/litex.overlay \ --config $OUTPUT_DIR/config.overlay \ - $TOP_DIR/$TARGET_BUILD_DIR/test/csr.csv + $LITEX_CONFIG_FILE cat $OUTPUT_DIR/config.overlay | xargs west build \ -b $TARGET_BOARD \ From 0ad2201c71a64d84315fda002c11e5e040fa64bb Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2020 19:55:19 +0000 Subject: [PATCH 038/153] build(deps): bump third_party/litedram from `5a90a8b` to `8a46b71` Bumps [third_party/litedram](https://github.com/enjoy-digital/litedram) from `5a90a8b` to `8a46b71`. - [Release notes](https://github.com/enjoy-digital/litedram/releases) - [Commits](https://github.com/enjoy-digital/litedram/compare/5a90a8b0dde504d383ffcc3c1ad6e0724caf5713...8a46b71411656b676611d9bdf441c04ccec3ec21) Signed-off-by: dependabot-preview[bot] --- third_party/litedram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litedram b/third_party/litedram index 5a90a8b0d..8a46b7141 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit 5a90a8b0dde504d383ffcc3c1ad6e0724caf5713 +Subproject commit 8a46b71411656b676611d9bdf441c04ccec3ec21 From b9264c2d4d978d7a8c7c2b5f29155c08e8abe3c1 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 4 Feb 2020 16:24:49 +0100 Subject: [PATCH 039/153] build-linux: Do not clone linux sources when building with buildroot It takes a lot of time and requires space on a disk, but buildroot use it's own copy anyway. --- scripts/build-linux.sh | 69 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 3a764301e..210a2b037 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -74,44 +74,49 @@ else exit 1 fi -# Get linux-litex is needed -LINUX_SRC="$TOP_DIR/third_party/linux" -LINUX_LOCAL="$LINUX_GITLOCAL" # Local place to clone from -LINUX_REMOTE_BIT=$(echo $LINUX_REMOTE | sed -e's-^.*://--' -e's/.git$//') -LINUX_CLONE_FROM="${LINUX_LOCAL:-$LINUX_REMOTE}" -( - # Download the Linux source for the first time - if [ ! -d "$LINUX_SRC" ]; then +if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT} = 1 ]; then + # do not download linux sources, buildroot comes with its own copy + : +else + # Get linux-litex is needed + LINUX_SRC="$TOP_DIR/third_party/linux" + LINUX_LOCAL="$LINUX_GITLOCAL" # Local place to clone from + LINUX_REMOTE_BIT=$(echo $LINUX_REMOTE | sed -e's-^.*://--' -e's/.git$//') + LINUX_CLONE_FROM="${LINUX_LOCAL:-$LINUX_REMOTE}" ( - cd $(dirname $LINUX_SRC) - echo "Downloading Linux source tree." - echo "If you already have a local git checkout you can set 'LINUX_GITLOCAL' to speed up this step." - git clone $LINUX_CLONE_FROM $LINUX_SRC --branch $LINUX_BRANCH - ) - fi + # Download the Linux source for the first time + if [ ! -d "$LINUX_SRC" ]; then + ( + cd $(dirname $LINUX_SRC) + echo "Downloading Linux source tree." + echo "If you already have a local git checkout you can set 'LINUX_GITLOCAL' to speed up this step." + git clone $LINUX_CLONE_FROM $LINUX_SRC --branch $LINUX_BRANCH + ) + fi - # Change into the dir - cd $LINUX_SRC + # Change into the dir + cd $LINUX_SRC - # Add the remote if it doesn't exist - CURRENT_LINUX_REMOTE_NAME=$(git remote -v | grep fetch | grep "$LINUX_REMOTE_BIT" | sed -e's/\t.*$//') - if [ x"$CURRENT_LINUX_REMOTE_NAME" = x ]; then - git remote add $LINUX_REMOTE_NAME $LINUX_REMOTE - CURRENT_LINUX_REMOTE_NAME=$LINUX_REMOTE_NAME - fi + # Add the remote if it doesn't exist + CURRENT_LINUX_REMOTE_NAME=$(git remote -v | grep fetch | grep "$LINUX_REMOTE_BIT" | sed -e's/\t.*$//') + if [ x"$CURRENT_LINUX_REMOTE_NAME" = x ]; then + git remote add $LINUX_REMOTE_NAME $LINUX_REMOTE + CURRENT_LINUX_REMOTE_NAME=$LINUX_REMOTE_NAME + fi - # Get any new data - git fetch $CURRENT_LINUX_REMOTE_NAME + # Get any new data + git fetch $CURRENT_LINUX_REMOTE_NAME - # Checkout or1k-linux branch it not already on it - if [ "$(git rev-parse --abbrev-ref HEAD)" != "$LINUX_BRANCH" ]; then - if git rev-parse --abbrev-ref $LINUX_BRANCH > /dev/null 2>&1; then - git checkout $LINUX_BRANCH - else - git checkout "$CURRENT_LINUX_REMOTE_NAME/$LINUX_BRANCH" -b $LINUX_BRANCH + # Checkout or1k-linux branch it not already on it + if [ "$(git rev-parse --abbrev-ref HEAD)" != "$LINUX_BRANCH" ]; then + if git rev-parse --abbrev-ref $LINUX_BRANCH > /dev/null 2>&1; then + git checkout $LINUX_BRANCH + else + git checkout "$CURRENT_LINUX_REMOTE_NAME/$LINUX_BRANCH" -b $LINUX_BRANCH + fi fi - fi -) + ) +fi # Get litex-devicetree LITEX_DT_SRC="$TOP_DIR/third_party/litex-devicetree" From 1c28e3bdb1df18ab6d66b13c46ebd9e89e0032a2 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 5 Feb 2020 10:38:24 +0100 Subject: [PATCH 040/153] settings: Set Renode version to 1.8.2 --- scripts/build-renode.sh | 2 +- scripts/settings.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/build-renode.sh b/scripts/build-renode.sh index 046751aaa..0220cf3f7 100755 --- a/scripts/build-renode.sh +++ b/scripts/build-renode.sh @@ -26,7 +26,7 @@ fi if ! $RENODE_FOUND; then # Download prebuilt renode Release if none is currently installed - conda install -c antmicro -c conda-forge renode + conda install -c antmicro -c conda-forge renode=$RENODE_VERSION RENODE_BIN=$CONDA_PREFIX/bin/renode fi diff --git a/scripts/settings.sh b/scripts/settings.sh index 3fd1276ee..5ecbcf6d9 100644 --- a/scripts/settings.sh +++ b/scripts/settings.sh @@ -18,6 +18,7 @@ BINUTILS_VERSION=2.32 GCC_VERSION=9.1.0 SDCC_VERSION=3.5.0 OPENOCD_VERSION=0.10.0 +RENODE_VERSION=v1.8.2 # Other tools versions ZEPHYR_SDK_VERSION=0.11.1 From e5f831d4f503f6b2b158ee16ea09231860dc1bbb Mon Sep 17 00:00:00 2001 From: Andres Calderon Date: Fri, 21 Feb 2020 09:19:43 -0500 Subject: [PATCH 041/153] matrix_voice added to .travis.yml --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 79b725b24..345264658 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,6 +52,7 @@ env: - C=lm32 TC="vivado" P=nexys_video T="base net" - C=lm32 TC="ise" P=atlys T="base net" - C=lm32 TC="ise" P=galatea T="base" + - C=lm32 TC="ise" P=matrix_voice T="base" - C=lm32 TC="ise" P=mimasv2 T="base" - C=lm32 TC="ise" P=minispartan6 T="base" - C=lm32 TC="ise" P=opsis T="base net" @@ -94,6 +95,7 @@ env: - C=vexriscv.lite TC="icestorm" P=upduino_v1 T="base" F=stub - C=vexriscv.lite TC="icestorm" P=icefun T="base" F=stub - C=vexriscv.lite TC="vivado" P=arty T="base net" + - C=vexriscv.lite TC="ise" P=matrix_voice T="base" - C=vexriscv.lite TC="ise" P=opsis T="base net" - C=vexriscv.lite TC="ise" P=pano_logic_g2 T="base" # PicoRV32 @@ -102,6 +104,7 @@ env: - C=picorv32 TC="ise" P=opsis T="base net" - C=picorv32.minimal TC="icestorm" P=icebreaker T="base" F=stub - C=picorv32.minimal TC="vivado" P=arty T="base net" + - C=picorv32.minimal TC="ise" P=matrix_voice T="base" - C=picorv32.minimal TC="ise" P=opsis T="base net" # minerva target - C=minerva TC="vivado" P=arty T="base net" From d10e18776b4ef7aef222c4dc2db8ed359b8638e8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2020 19:58:18 +0000 Subject: [PATCH 042/153] build(deps): bump third_party/litepcie from `061418c` to `be68cba` Bumps [third_party/litepcie](https://github.com/enjoy-digital/litepcie) from `061418c` to `be68cba`. - [Release notes](https://github.com/enjoy-digital/litepcie/releases) - [Commits](https://github.com/enjoy-digital/litepcie/compare/061418c620cb09e32aafc202ed1379a29c49cc17...be68cbac60e9ff2f9c50f70bde8e4b2b2fd51683) Signed-off-by: dependabot-preview[bot] --- third_party/litepcie | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litepcie b/third_party/litepcie index 061418c62..be68cbac6 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit 061418c620cb09e32aafc202ed1379a29c49cc17 +Subproject commit be68cbac60e9ff2f9c50f70bde8e4b2b2fd51683 From 5c12b9627429c1c8e9dd9c752b7788f129cc4fe3 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2020 19:58:39 +0000 Subject: [PATCH 043/153] build(deps): bump third_party/litedram from `8a46b71` to `87578dd` Bumps [third_party/litedram](https://github.com/enjoy-digital/litedram) from `8a46b71` to `87578dd`. - [Release notes](https://github.com/enjoy-digital/litedram/releases) - [Commits](https://github.com/enjoy-digital/litedram/compare/8a46b71411656b676611d9bdf441c04ccec3ec21...87578dd2e3793a25d8828a057cd888272fa4d716) Signed-off-by: dependabot-preview[bot] --- third_party/litedram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litedram b/third_party/litedram index 8a46b7141..87578dd2e 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit 8a46b71411656b676611d9bdf441c04ccec3ec21 +Subproject commit 87578dd2e3793a25d8828a057cd888272fa4d716 From 4a96ce8d798e68be7dd67d0222dd79e7639ae96e Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 20 Feb 2020 11:17:49 +0100 Subject: [PATCH 044/153] build-linux: protect against empty BUILD_BUILDROOT env --- scripts/build-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 3a764301e..fe0705ba8 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -190,7 +190,7 @@ BD_REMOTE="${BD_REMOTE:-https://github.com/buildroot/buildroot.git}" BD_SRC="$TOP_DIR/third_party/buildroot" LLV_REMOTE="${LLV_REMOTE:-https://github.com/litex-hub/linux-on-litex-vexriscv.git}" LLV_SRC="$TOP_DIR/third_party/linux-on-litex-vexriscv" -if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT} = 1 ]; then +if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT:-0} = 1 ]; then ( if [ ! -d "$BD_SRC" ]; then ( From a14097530035042af76138e1641fb9391a53760f Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 20 Feb 2020 11:46:43 +0100 Subject: [PATCH 045/153] build-linux: Enable -x to ease debugging --- scripts/build-linux.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index fe0705ba8..794b862e2 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -30,7 +30,7 @@ fi eval $(make env) make info -#set -x +set -x set -e if [ "$CPU_VARIANT" != "linux" ]; then From cdeb2c6b03afe0317ba4d3080e2e94ad870324df Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 20 Feb 2020 11:45:39 +0100 Subject: [PATCH 046/153] build-linux: Verify MD5 sums of downloaded files --- scripts/build-linux.sh | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 794b862e2..33b9797bc 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -61,6 +61,7 @@ if [ ${CPU} = mor1kx ]; then # To rebuild, use https://ozlabs.org/~joel/litex_or1k_defconfig ROOTFS_LOCATION="https://ozlabs.org/~joel/" ROOTFS=${ARCH}-rootfs.cpio.gz + ROOTFS_MD5="3a254683a7b6f441a4acc0d4c555230a" elif [ ${CPU} = vexriscv ]; then LINUX_REMOTE="${LINUX_REMOTE:-https://github.com/torvalds/linux.git}" LINUX_REMOTE_NAME=upstream-linux @@ -69,6 +70,9 @@ elif [ ${CPU} = vexriscv ]; then export ARCH=riscv ROOTFS_LOCATION="https://antmicro.com/projects/renode/litex-buildenv/" ROOTFS=${ARCH}32-rootfs.cpio + ROOTFS_MD5="c3a88ff90fbd05dd6dc5773a8202d47f" + DTB_MD5="390c3ac4468810d4daa78379eb38dc1b" + CONFIG_MD5="fed2b661016e1b4aad16f17103839dba" else echo "Linux is only supported on mor1kx or vexriscv at the moment." exit 1 @@ -181,6 +185,29 @@ if [ ${CPU} = vexriscv ]; then ) fi +function calcualte_md5() { + # will be '0' if the file does not exist + (md5sum "$1" 2>/dev/null || echo "0") | cut -d' ' -f1 +} + +function fetch_file() { + URL=$1 + EXPECTED_MD5=$2 + TRGT=$3 + + ACTUAL_MD5=`calcualte_md5 $TRGT` + + if [ $ACTUAL_MD5 != $EXPECTED_MD5 ]; then + wget $URL -O $TRGT + + ACTUAL_MD5=`calcualte_md5 $TRGT` + if [ $ACTUAL_MD5 != $EXPECTED_MD5 ]; then + echo "Could not fetch file from $URL" + exit 1 + fi + fi +} + # Build linux-litex export CROSS_COMPILE=${CPU_ARCH}-linux-musl- @@ -232,21 +259,17 @@ else echo "Building Linux in $TARGET_LINUX_BUILD_DIR" mkdir -p $TARGET_LINUX_BUILD_DIR - if [ ! -e $TARGET_LINUX_BUILD_DIR/$ROOTFS ]; then - wget $ROOTFS_LOCATION/$ROOTFS -O $TARGET_LINUX_BUILD_DIR/$ROOTFS - fi + + fetch_file $ROOTFS_LOCATION/$ROOTFS $ROOTFS_MD5 $TARGET_LINUX_BUILD_DIR/$ROOTFS if [ ${CPU} = mor1kx ]; then KERNEL_BINARY=vmlinux.bin make O="$TARGET_LINUX_BUILD_DIR" litex_defconfig elif [ ${CPU} = vexriscv ]; then - if [ ! -f $TARGET_LINUX_BUILD_DIR/.config ]; then - wget ${ROOTFS_LOCATION}/litex_vexriscv_linux.config -O $TARGET_LINUX_BUILD_DIR/.config - fi - if [ ! -f $TARGET_LINUX_BUILD_DIR/rv32.dtb ]; then - wget ${ROOTFS_LOCATION}/rv32.dtb -O $TARGET_LINUX_BUILD_DIR/rv32.dtb - fi + fetch_file $ROOTFS_LOCATION/litex_vexriscv_linux.config $CONFIG_MD5 $TARGET_LINUX_BUILD_DIR/.config + + fetch_file $ROOTFS_LOCATION/rv32.dtb $DTB_MD5 $TARGET_LINUX_BUILD_DIR/rv32.dtb KERNEL_BINARY=Image make O="$TARGET_LINUX_BUILD_DIR" olddefconfig From 9b8bad2f3dd22ffca19a6fedf7986c99cde2733d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2020 19:27:03 +0000 Subject: [PATCH 047/153] build(deps): bump third_party/litescope from `daf10e9` to `b3d1e69` Bumps [third_party/litescope](https://github.com/enjoy-digital/litescope) from `daf10e9` to `b3d1e69`. - [Release notes](https://github.com/enjoy-digital/litescope/releases) - [Commits](https://github.com/enjoy-digital/litescope/compare/daf10e9473fb70b3034e0331ef89005661ac04e0...b3d1e6938f42045ade1fcb10aa2498722a4ea041) Signed-off-by: dependabot-preview[bot] --- third_party/litescope | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litescope b/third_party/litescope index daf10e947..b3d1e6938 160000 --- a/third_party/litescope +++ b/third_party/litescope @@ -1 +1 @@ -Subproject commit daf10e9473fb70b3034e0331ef89005661ac04e0 +Subproject commit b3d1e6938f42045ade1fcb10aa2498722a4ea041 From 1be857e52fa1bac5406b8e34045ffb5723f1adc6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2020 19:27:23 +0000 Subject: [PATCH 048/153] build(deps): bump third_party/litepcie from `be68cba` to `c28ec23` Bumps [third_party/litepcie](https://github.com/enjoy-digital/litepcie) from `be68cba` to `c28ec23`. - [Release notes](https://github.com/enjoy-digital/litepcie/releases) - [Commits](https://github.com/enjoy-digital/litepcie/compare/be68cbac60e9ff2f9c50f70bde8e4b2b2fd51683...c28ec23bd05c0ee6b3f1d5609df7ad123128452d) Signed-off-by: dependabot-preview[bot] --- third_party/litepcie | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litepcie b/third_party/litepcie index be68cbac6..c28ec23bd 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit be68cbac60e9ff2f9c50f70bde8e4b2b2fd51683 +Subproject commit c28ec23bd05c0ee6b3f1d5609df7ad123128452d From 0f0fbc617244f3f3e327e359be7fcd0397cc9c7a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 28 Feb 2020 19:27:45 +0000 Subject: [PATCH 049/153] build(deps): bump third_party/litedram from `87578dd` to `8122209` Bumps [third_party/litedram](https://github.com/enjoy-digital/litedram) from `87578dd` to `8122209`. - [Release notes](https://github.com/enjoy-digital/litedram/releases) - [Commits](https://github.com/enjoy-digital/litedram/compare/87578dd2e3793a25d8828a057cd888272fa4d716...8122209d9bd74211220367e11a19c07c0e020505) Signed-off-by: dependabot-preview[bot] --- third_party/litedram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litedram b/third_party/litedram index 87578dd2e..8122209d9 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit 87578dd2e3793a25d8828a057cd888272fa4d716 +Subproject commit 8122209d9bd74211220367e11a19c07c0e020505 From 8da140b604a5468da1fd3a4d92f190890dd00acf Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Sun, 1 Mar 2020 19:28:43 -0800 Subject: [PATCH 050/153] Try and setup correct hostid. --- .travis/download-xilinx.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis/download-xilinx.sh b/.travis/download-xilinx.sh index 54f47b675..1ede84ca0 100755 --- a/.travis/download-xilinx.sh +++ b/.travis/download-xilinx.sh @@ -45,6 +45,9 @@ if [ ! -z "$XILINX_PASSPHRASE" ]; then wget --no-verbose http://xilinx.timvideos.us/Xilinx.lic.gpg cat $XILINX_PASSPHRASE_FILE | gpg --batch --passphrase-fd 0 Xilinx.lic.gpg + sudo modprobe dummy + sudo ip link set name eth0 dev dummy0 + sudo ifconfig eth0 hw ether 08:00:27:68:c9:35 #git clone https://github.com/mithro/impersonate_macaddress #cd impersonate_macaddress #make @@ -66,7 +69,8 @@ if [ -z "$XILINX_DIR" ]; then # Reserved MAC address from documentation block, see # http://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml export LIKELY_XILINX_LICENSE_DIR=$LOCAL_XILINX_DIR - export MACADDR=90:10:00:00:00:01 + #export MACADDR=90:10:00:00:00:01 + export MACADDR=08:00:27:68:c9:35 #export LD_PRELOAD=$XILINX_DIR/impersonate_macaddress/impersonate_macaddress.so #ls -l $LD_PRELOAD export XILINX_DIR=$LOCAL_XILINX_DIR From 65785dccae809d6db04fecbd986a570dd25e8b0e Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Sun, 1 Mar 2020 22:51:51 -0800 Subject: [PATCH 051/153] Remove pano_logic_g2 from allowed failures. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 345264658..7ded96ae5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -149,8 +149,6 @@ env: jobs: allow_failures: - env: C=mor1kx.linux TC="vivado" P=nexys_video T="net" F=linux - # Need to rebuilt Xilinx toolchain to add pano_logic_g2 part (Spartan 6 150T part) - - env: C=vexriscv.lite TC="ise" P=pano_logic_g2 T="base" # Need to rebuilt Xilinx toolchain to add NeTV2 FPGA Part (Artix 7 35T+50T parts) - env: C=vexriscv TC="vivado" P=netv2 T="base net" - env: C=vexriscv TC="vivado" P=netv2 T="hdmi2pcie" From e6d49e7144e665a2ac75a7f13bcfa59cdb404870 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2020 19:44:45 +0000 Subject: [PATCH 052/153] build(deps): bump third_party/litedram from `8122209` to `26564ba` Bumps [third_party/litedram](https://github.com/enjoy-digital/litedram) from `8122209` to `26564ba`. - [Release notes](https://github.com/enjoy-digital/litedram/releases) - [Commits](https://github.com/enjoy-digital/litedram/compare/8122209d9bd74211220367e11a19c07c0e020505...26564ba93cf342a191dc68d31194caf81c7c0c6a) Signed-off-by: dependabot-preview[bot] --- third_party/litedram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litedram b/third_party/litedram index 8122209d9..26564ba93 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit 8122209d9bd74211220367e11a19c07c0e020505 +Subproject commit 26564ba93cf342a191dc68d31194caf81c7c0c6a From f676bf5dd19e9d6c6878a5dec249bc48ab1ecade Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2020 19:45:05 +0000 Subject: [PATCH 053/153] build(deps): bump third_party/litevideo from `49bafa4` to `49d8126` Bumps [third_party/litevideo](https://github.com/enjoy-digital/litevideo) from `49bafa4` to `49d8126`. - [Release notes](https://github.com/enjoy-digital/litevideo/releases) - [Commits](https://github.com/enjoy-digital/litevideo/compare/49bafa481075e0bfbaf067b63c351ec29e993894...49d812694951a924617d8e429d72c0d4da96372a) Signed-off-by: dependabot-preview[bot] --- third_party/litevideo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litevideo b/third_party/litevideo index 49bafa481..49d812694 160000 --- a/third_party/litevideo +++ b/third_party/litevideo @@ -1 +1 @@ -Subproject commit 49bafa481075e0bfbaf067b63c351ec29e993894 +Subproject commit 49d812694951a924617d8e429d72c0d4da96372a From 9b7f0a9c0f8c8ae0408d114217d965cd52282673 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2020 19:45:45 +0000 Subject: [PATCH 054/153] build(deps): bump third_party/litepcie from `c28ec23` to `17beae4` Bumps [third_party/litepcie](https://github.com/enjoy-digital/litepcie) from `c28ec23` to `17beae4`. - [Release notes](https://github.com/enjoy-digital/litepcie/releases) - [Commits](https://github.com/enjoy-digital/litepcie/compare/c28ec23bd05c0ee6b3f1d5609df7ad123128452d...17beae40c6ad3dc7c3ea67f88e9c55944993a1c7) Signed-off-by: dependabot-preview[bot] --- third_party/litepcie | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litepcie b/third_party/litepcie index c28ec23bd..17beae40c 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit c28ec23bd05c0ee6b3f1d5609df7ad123128452d +Subproject commit 17beae40c6ad3dc7c3ea67f88e9c55944993a1c7 From e7f98bacf6c4e9289077192f7b1c7edb258e3cc8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2020 19:46:07 +0000 Subject: [PATCH 055/153] build(deps): bump third_party/litex-renode from `70e884e` to `2ed761f` Bumps [third_party/litex-renode](https://github.com/litex-hub/litex-renode) from `70e884e` to `2ed761f`. - [Release notes](https://github.com/litex-hub/litex-renode/releases) - [Commits](https://github.com/litex-hub/litex-renode/compare/70e884e88c25d997ea5e3dd1e2a8bb08f0d02f90...2ed761f4c138f0237a7dca8d8dd45cea0b3c24d1) Signed-off-by: dependabot-preview[bot] --- third_party/litex-renode | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litex-renode b/third_party/litex-renode index 70e884e88..2ed761f4c 160000 --- a/third_party/litex-renode +++ b/third_party/litex-renode @@ -1 +1 @@ -Subproject commit 70e884e88c25d997ea5e3dd1e2a8bb08f0d02f90 +Subproject commit 2ed761f4c138f0237a7dca8d8dd45cea0b3c24d1 From f0844f812d9caab53cc2d1400378a69aaf75d1e2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2020 19:39:22 +0000 Subject: [PATCH 056/153] build(deps): bump third_party/litedram from `26564ba` to `4cfbc71` Bumps [third_party/litedram](https://github.com/enjoy-digital/litedram) from `26564ba` to `4cfbc71`. - [Release notes](https://github.com/enjoy-digital/litedram/releases) - [Commits](https://github.com/enjoy-digital/litedram/compare/26564ba93cf342a191dc68d31194caf81c7c0c6a...4cfbc71fc2e2561e82c984c074094a297c9d32e8) Signed-off-by: dependabot-preview[bot] --- third_party/litedram | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litedram b/third_party/litedram index 26564ba93..4cfbc71fc 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit 26564ba93cf342a191dc68d31194caf81c7c0c6a +Subproject commit 4cfbc71fc2e2561e82c984c074094a297c9d32e8 From ae811329932736bd93f22478f2aab2039253b661 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 3 Apr 2020 19:37:09 +0000 Subject: [PATCH 057/153] build(deps): bump third_party/litepcie from `17beae4` to `5b7e7cd` Bumps [third_party/litepcie](https://github.com/enjoy-digital/litepcie) from `17beae4` to `5b7e7cd`. - [Release notes](https://github.com/enjoy-digital/litepcie/releases) - [Commits](https://github.com/enjoy-digital/litepcie/compare/17beae40c6ad3dc7c3ea67f88e9c55944993a1c7...5b7e7cde0814e1c8337f60f6bc7b3a20d5518136) Signed-off-by: dependabot-preview[bot] --- third_party/litepcie | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litepcie b/third_party/litepcie index 17beae40c..5b7e7cde0 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit 17beae40c6ad3dc7c3ea67f88e9c55944993a1c7 +Subproject commit 5b7e7cde0814e1c8337f60f6bc7b3a20d5518136 From 0d3c2c11827e7be439c537dc572b1e8d780e652a Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 16 Jan 2020 15:10:13 +1000 Subject: [PATCH 058/153] Adding the litex-boards repository. --- .gitmodules | 3 +++ scripts/download-env.sh | 3 ++- scripts/enter-env.sh | 5 +++-- scripts/settings.sh | 1 + third_party/litex-boards | 1 + 5 files changed, 10 insertions(+), 3 deletions(-) create mode 160000 third_party/litex-boards diff --git a/.gitmodules b/.gitmodules index 9ab4c263a..7ba9caf6b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,3 +37,6 @@ [submodule "third_party/nmigen"] path = third_party/nmigen url = https://github.com/m-labs/nmigen.git +[submodule "third_party/litex-boards"] + path = third_party/litex-boards + url = https://github.com/litex-hub/litex-boards diff --git a/scripts/download-env.sh b/scripts/download-env.sh index b21546366..ec11a5b0a 100755 --- a/scripts/download-env.sh +++ b/scripts/download-env.sh @@ -655,13 +655,14 @@ echo "-----------------------" # lite for LITE in $LITE_REPOS; do LITE_DIR=$THIRD_DIR/$LITE + LITE_MOD=$(echo $LITE | sed -e's/-/_/g') ( echo cd $LITE_DIR echo "Installing $LITE from $LITE_DIR (local python module)" python setup.py develop ) - check_import $LITE + check_import $LITE_MOD done echo "-----------------------" diff --git a/scripts/enter-env.sh b/scripts/enter-env.sh index 6a30edad7..9def212f2 100755 --- a/scripts/enter-env.sh +++ b/scripts/enter-env.sh @@ -567,14 +567,15 @@ echo "-----------------------" # lite for LITE in $LITE_REPOS; do + LITE_DIR=$THIRD_DIR/$LITE + LITE_MOD=$(echo $LITE | sed -e's/-/_/g') - - check_import $LITE || return 1 + check_import $LITE_MOD || return 1 done echo "-----------------------" diff --git a/scripts/settings.sh b/scripts/settings.sh index 5ecbcf6d9..1f30e2a2b 100644 --- a/scripts/settings.sh +++ b/scripts/settings.sh @@ -28,6 +28,7 @@ LITE_REPOS=" migen nmigen litex + litex-boards litedram liteeth litepcie diff --git a/third_party/litex-boards b/third_party/litex-boards new file mode 160000 index 000000000..84164f8fa --- /dev/null +++ b/third_party/litex-boards @@ -0,0 +1 @@ +Subproject commit 84164f8fab5c65e2dd828ed20422d14026f5b140 From 688d49f4219de0fb79e8c8fafb3dd3c588905c20 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 16 Mar 2020 11:59:30 +0100 Subject: [PATCH 059/153] Add liteiclink submodule --- .gitmodules | 3 +++ scripts/settings.sh | 1 + third_party/liteiclink | 1 + 3 files changed, 5 insertions(+) create mode 160000 third_party/liteiclink diff --git a/.gitmodules b/.gitmodules index 7ba9caf6b..467761972 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,3 +40,6 @@ [submodule "third_party/litex-boards"] path = third_party/litex-boards url = https://github.com/litex-hub/litex-boards +[submodule "third_party/liteiclink"] + path = third_party/liteiclink + url = https://github.com/enjoy-digital/liteiclink.git diff --git a/scripts/settings.sh b/scripts/settings.sh index 1f30e2a2b..aa4566fc1 100644 --- a/scripts/settings.sh +++ b/scripts/settings.sh @@ -35,4 +35,5 @@ LITE_REPOS=" litesata litescope litevideo + liteiclink " diff --git a/third_party/liteiclink b/third_party/liteiclink new file mode 160000 index 000000000..864cd831f --- /dev/null +++ b/third_party/liteiclink @@ -0,0 +1 @@ +Subproject commit 864cd831f3475dffd1c92d6d4a1b86608680bcf2 From 2e63fa23d8ea5794585fa38243b11da135d6eb95 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Sat, 4 Apr 2020 13:34:01 +0200 Subject: [PATCH 060/153] Updating submodules. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * litedram changed from 4cfbc71 to b06e946 * b06e946 - Merge pull request #172 from antmicro/zcu104-sodimm |\ | * 7238a9c - modules: add MTA4ATF51264HZ DDR4 SO-DIMM * | f6babda - litedram_gen: fix LiteDRAMECP5DDRPHYCRG clkin freq (input_clk_freq and not sys_clk_freq). * | 7fab898 - litedram_gen: use replace_in_file from litex, add comment on phy selection. * | d4d9ab7 - litedram_gen/lattice: use trellis toolchain and LFE5UM5G-45F device for now. |/ * 6951428 - test/test_fifo: minor cleanup. * 0ee9d7d - test/test_ecc: review and cleanup. * 265e79f - test/gen_config: review/cleanup. * 2bb8f8f - test/gen_access_pattern: cleanup. * 72d2bbf - test/benchmarck: cleanup. * 0cbdbf1 - test/run_benchmarks: avoid relative imports as done on others tests. * 24c075e - Merge pull request #171 from antmicro/jboc/unit-tests-fifo |\ | * 4fd6dc0 - test: split test_fifo_ctrl into 2 separate tests | * 5d5bff3 - test: add frontend.fifo tests | * 72b91a8 - test: add timeout_generator * | 5919627 - Merge pull request #170 from antmicro/jboc/unit-tests |\ \ | * | c39a6bd - test: use @unittest.skip instead of commenting out code | * | 0afacba - test: replace ConverterDUT.write_* with .write | * | 7f36717 - test: add LiteDRAMNativePortCDC tests | * | 1f8868e - test: add frontend.adaptation tests for different conversion ratios | |/ * / 0436666 - phy/gensdrphy: sample rddata on sys_clk (assume clk generated to sdram is shifted), add cmd_latency parameter and simplify control logic. |/ * ebdbcac - Merge pull request #169 from antmicro/jboc/unit-tests |\ | * f19d92b - test: add wishbone tests with data width mismatch | * 7996ee5 - test: add missing write-enable handling | * 3c0fdf0 - test: handle 'we' in DRAMMemory, add memory debug messages | * e8558f6 - test: fix bits formatting | * 7593b2d - test: add basic wishbone test * | d96dd94 - phy/s7ddrphy: add ISERDESE2 MEMORY mode support that uses DQS to sample the DQ datas. |/ * 060d180 - Merge pull request #168 from antmicro/jboc/unit-tests-ecc |\ | * 68d078c - test: add tests for LiteDRAMNativePortECCW/LiteDRAMNativePortECCR | * 1b4647b - test: add tests for LiteDRAMNativePortECC * 4a784f0 - Merge pull request #165 from antmicro/jboc/unit-tests |\ | * 03f9399 - test: move DMA specific tests to test_dma.py | * 36d5b42 - test: correct DMAReaderDriver/DMAWriterDriver logic | * 6ef623e - test: cleanup test_bist.py code style | * a883f88 - test: add LiteDRAMDMAReader tests | * d86ebd7 - test: add LiteDRAMDMAWriter tests | * 5618d2a - test: fix quotes | * ef9b13d - test: add tests for BIST modules with clock domain crossing | * a00c8b7 - test: unify BIST tests, factor out repetitive code | * 13aeb3f - test: add _LiteDRAMBISTChecker/_LiteDRAMPatternChecker tests | * ba83e56 - test: add some more verbose _LiteDRAMBISTGenerator tests | * 239859d - test: add tests for _LiteDRAMPatternGenerator | * ac06382 - test: split GenCheckDriver run into configure/run * 1c5e940 - s6ddrphy/s7ddrphy: use IOBUFDS/IOBUF for DQS even if input is not currently used. * d68eff0 - Merge pull request #166 from Xiretza/standalone-builder-args * ab4ce5d - Allow specifying builder arguments for standalone generator * liteeth changed from f532a12 to fb47853 * fb47853 - phy/gmii: use a BUFG between eth_rx.clk and eth_rx.clk. * 8accd67 - Merge pull request #36 from antmicro/hybrid-mac |\ | * ac9f6d9 - mac: add crossbar for sharing PHY between HW ethernet cores and Wishbone * | 400ca97 - examples: increase clk_freq to 125MHz on udp_s7phyrgmii.yml. * | ea24ff6 - liteeth_gen: improve readability and add clk_freq checks. * | 693a6b1 - Merge pull request #35 from Xiretza/standalone-customization |\ \ | |/ |/| | * 2e9121d - Allow changing all SoC options through YAML config |/ * 32d4af1 - phy/__init__: import all phys. * b2e1272 - phy: add tx/rx_clk_freq to phys (useful to add an add_ethernet method in LiteX and simplify timing constraints). * 466223e - liteeth/gen: update copyrights * d6b5888 - Merge pull request #34 from Xiretza/generator-improvements |\ | * 7a44209 - Make memory/CSR regions customizable in config | * ca9cbd1 - Move more options to config file | * eea1086 - Use builder arguments in generator | * b9fb1f0 - Remove leftover classes in generator |/ * 358bc23 - examples/.ymls: add separators * ddcbc33 - test/test_gen: update * fcadd60 - liteeth/gen: initial switch to YAML config file (similar to LiteDRAM/LitePCIe) * b029088 - Merge branch 'ximinity-generator-lattice' |\ | * 0954fa3 - Merge branch 'generator-lattice' of git://github.com/ximinity/liteeth into ximinity-generator-lattice |/| | * ae10eea - gen: add lattice support * | fcf7b24 - Merge pull request #33 from Xiretza/standalone-features |\ \ | * | 5767dfc - Honour --output-dir argument in generator | * | 153c160 - Prioritise overridden interrupts and memory regions | * | ec9bc57 - Fix MII tx_en signal width in standalone generator | * | 42a7b6c - Allow little-endian interface for standalone design | * | a696ccd - Expose interrupt pin for standalone design |/ / * | 208bc09 - liteeth/gen: update * | ddd0431 - examples: use integrated sram instead of external one. (Also fix regression with new SoC that no longer support address decoders passed to add_wb_slave) |/ * 081bf46 - mac/sram: simplify code and improve SRAM read speed using async_read on Memory. * bf4a11a - mac/sram: simplify counter (use NextValue in FSM) * 721238b - mac/sram: cosmetic changes * liteiclink changed from 864cd83 to 370855d * 370855d - liteiclink/transceiver: use CSR fields in logic instead of CSR storage/status. * 1afbaa5 - transceiver: improve CSR descriptions using CSRField's values. * 5ac090e - transceiver: add CSR documentation to add_base_control/add_prbs_control. * litex changed from 02bfda5e to 536ae0e6 * 536ae0e6 - Merge pull request #425 from esden/csr-cod-split-reg |\ | * 57576fa8 - Add bit more logic to decide when to switch to multilane CSR documentation. | * dda7a8c5 - Split CSR documentation diagrams with more than 8 bits into multiple lanes. |/ * c0f067c3 - Merge pull request #427 from enjoy-digital/s7mmcm_fractional_divide |\ | * aec1bfbe - cores/clock: simplify Fractional Divide support on S7MMCM. |/ * f34593a1 - Merge pull request #421 from betrusted-io/clk0_fractional |\ | * 5b92bf2d - add fractional division options to clk0 config on PLL * | eb9f54b2 - test: add initial (minimal) test for clock abstraction modules. * | c304c4db - targets/icebreaker: add description of the board, link to crowdsupply campagin and to the more complete example. * | b5bddc23 - Merge pull request #426 from esden/update-wavedrom |\ \ | * | d063acb7 - Updating the vendored wavedrom js files. |/ / * | a27385a7 - soc/intergration: rename mr_memory_x parameter to memory_x. * | d5da9e0d - Merge pull request #424 from esden/generate-memory-x |\ \ | * | 4d022632 - Add --mr-memory-x parameter to generate memory regions memory.x file. |/ / * | e9f0ff68 - Merge branch 'master' of http://github.com/enjoy-digital/litex |\ \ | * \ 01b69693 - Merge pull request #422 from xobs/core-doc-fixes | |\ \ | | * | a2f61b4e - soc/cores/spi_opi: documentation fixes | | * | d2f6139d - soc/cores/i2s: fix rst parsing errors | | |/ | * | 4ccf62af - Merge pull request #423 from gsomlo/gls-ethmac-fixes | |\ \ | | * | a9040348 - integration/soc: add_ethernet: honor self.map["ethmac"], if present * | | | 979f98ea - software: revert LTO changes (Disable it). |/ / / * | | bb8905fa - cores/gpio: add CSR descriptions. * | | 4dabc5a6 - cores/icap: add CSR descriptions. * | | 77132a48 - cores/spi: add CSR descriptions. * | | 6d861c6e - cores/pwm: add CSR descriptions. * | | cbc1f594 - cores/xadc: add CSR descriptions. |/ / * | 846a2720 - targets/kcu105: move cd_pll4x. * | c97fabb2 - targets/kcu105: simplify CRG using USIDELAYCTRL. * | 3c0b97ee - cores/clock/USIDELAYCTRL: use separate reset/ready counters and set cd_sys.rst internally. * | bcbf558b - bios: add more Ultrascale SDRAM debug with sdram_cdly command to set clk/cmd delay. * | c4ce6da6 - Merge pull request #419 from gsomlo/gls-ultra-sdram-fixup |\ \ | * | 4d15e1f7 - software/bios: fixup for Ultrascale SDRAM debug * | | b5090687 - cores/clock: add logging to visualize clkin/clkouts and computed config. * | | 04b8a912 - integration/soc: add FPGA device and System clock to logs. * | | 02cba41d - targets/icebreaker: create CRG after SoC. |/ / * | ba2f31d4 - integration/soc: set use_rom when cpu_reset_address is defined in a rom region. * | 8808c884 - boards/platforms/icebreaker: cleanup a bit. * | 4656b1b2 - software/common: fix LTO checks. * | 2a91dead - soc/cores/clock/iCE40PLL: add SB_PLL40_PAD support. * | 38d7f8a6 - build/lattice/icestorm: add timingstrict parameter and default to False. (similar behavior than others backends) * | 1e9aa643 - targets/icebreaker: simplify, use standard VexRiscv, add iCE40PLL and run BIOS from SPI Flash. * | 197bdcb0 - lattice/icestorm: enable DSP inference with Yosys and avoid setting SPI Flash in deep sleep mode after configuration which prevent running ROM CPU code from SPI Flash. * | 37869e38 - boards: add initial icebreaker platform/target from litex-boards. * | 72af1b39 - software/bios: add Ultrascale SDRAM debug functions. * | 6480d180 - boards/platforms/kcu105: avoid unnecessary {{}} on INTERNAL_VREF. * | b02c2339 - integration/soc/SoCRegion: add size_pow2 and use this internally for checks since decoder is using rounded size to next power or 2. |/ * e801dc02 - soc: allow creating SoC without BIOS. * 5ded1447 - Merge pull request #416 from enjoy-digital/csr_svd |\ | * ecca3d80 - integration/builder: rename software methods to _prepare_rom_software/_generate_rom_software/_initialize_rom_software. | * 69ffafd8 - integration/builder: generate csr maps before compiling software. | * e2dab063 - Add SVD export capability to Builder (csr_svd parameter) and targets (--csr-svd argument) and fix svd regression. |/ * e124aed9 - software/common.mak: fix LTO refactoring issue. * 8bfb845f - Merge pull request #412 from antmicro/fix-copyrights |\ | * da580e31 - Fix copyrights |/ * 361b6a06 - Merge pull request #408 from gsomlo/gls-fix-nexys-sdcard |\ | * 020bef41 - targets/nexys4ddr: fix sdcard clocker initialization |/ * 9249fc90 - Merge pull request #410 from antmicro/netv2-edid |\ | * 72f63243 - platform/netv2: add proper I2C pins for HDMI IN0 * | ad11ff39 - targets/ecp5: make sure all BaseSoC/EthernetSoc default to trellis. * | 37701950 - bios/sdcard: update sdclk_mmcm_write with LiteSDCard clocker changes. * | 4c83c975 - doc: align to improve readability. * | 4f935714 - soc/doc: remove soc.get_csr_regions support. * | 6893222c - bios/main: rename flushl2 command to flush_l2_cache, add flush_cpu_dcache command and expose them in help. * | d2accbb1 - README: update quick start guide and add instructions for windows. * | fc9b3975 - README: update - improve presentation - add link to #litex freenode channel. - add example of complex SoC. - make it directly usable on Wiki. - only keep one quick start guide. - add community paragraph and link to Litex-Hub. * | 68f56542 - doc: remove partial doc imported from litex-buildenv-wiki: we'll create a LiteX wiki and doc. * | 0b923aa4 - build: assume vendor tools are in the PATH and remove automatic sourcing, source and toolchain_path parameters. * | 1d7c6943 - software/common: add LTO enable flag and cleanup. * | b29f443f - litex_sim: fix with_uart parameter. |/ * 98e41e2e - targets/nexys4ddr: add default kwargs parameters. * 598ad692 - Merge branch 'master' of https://github.com/enjoy-digital/litex |\ | * ddb264f3 - Merge pull request #405 from sajattack/sifive-triple | |\ | | * 68c013d1 - add riscv-sifive-elf triple * | | a67e19c6 - integration/soc_core: change disable parameters to no-xxyy. * | | 156a85b1 - integration/soc: add auto_int type and use it on all int parameters. * | | 7e96c911 - targets/nexys4ddr: use SoCCore and add_sdram to avoid use of specific SoCSDRAM. * | | cb0371b3 - integration/soc: add ethphy CSR in target. |/ / * | f27225c2 - targets/nexys4ddr: use soc.add_ethernet method. * | 9735bd5b - integration/soc: add add_ethernet method. * | 1c74143a - integration/soc: mode litedram imports to add_sdram, remove some separators. |/ * 54fb3a61 - test/test_targets: use uart-name=stub. * 59e99bfb - soc/uart: add configurable UART FIFO depth. * 9199306a - cores/uart: cleanup * ea856333 - soc/cores/uart/UARTCrossover: reduce fifo_depth to 1. * 12a75286 - interconnect/stream/SyncFIFO: allow depth down to 0. * 9e31bf35 - interconnect/axi: remove Record inheritance on AXIInterface/AXILiteInterface. * 1e0e96f9 - interconnect/axi: add AXI Stream definition and get_ios/connect_to_pads methods. * 6be7e9c3 - interconnect/axi: set default data_width/address_width to 32-bit. * 8e1d5286 - targets: default to trellis toolchain on all ECP5 targets (now able to build all supported targets). * a7c5dd5d - cores/gpio: use separate TSTriple for each bit. * 400492e2 - lattice/yosys: don't use quiet operation since logs are useful and for consistency with others build backends. * c4fd6a7f - targets/kc705: use DDRPHY_CMD_DELAY to center write leveling. * 78a32235 - software/bios/sdram: allow setting CLK/CMD delay from user design and configure it before write/read leveling. * eab5161d - boards: keep in sync with LiteX-boards * 935e4eff - interconnect/axi: remove mode on AXIInterface (not used and breaking LiteDRAM tests) * d324c54e - integration/soc: -x on soc.py * ee27a9e5 - soc/cores/bitbang: fix missing self.comb on miso. * a2d69869 - Merge pull request #402 from antmicro/litex-gen-fix-uart-pins |\ | * 75b000a3 - tools: litex_gen: fix missing UART pins * | e2aebb42 - software: disable LTO with LM32 (not supported by old GCC versions easily available). * | 9e70fcf8 - Merge pull request #401 from antmicro/enable-lto |\ \ | |/ |/| | * 718a65c3 - software: enable link time optimization (LTO) |/ * 9521f2ff - Merge pull request #400 from Xiretza/ecp5-pll-freqfix |\ | * 7a87d4e2 - Fix ECP5PLL VCO frequency range |/ * 0c7e0bf0 - integration/soc: improve presentation of SoCLocHandler's locations. * 0042a028 - interconnect/axi: remove bus_name on connect_to_pads * 5aba1fe8 - tools/litex_gen: add bus parameter and AXI (Lite) support. * a3584147 - litex_gen/axi: simplify the way the bus is exposed as ios and connected to pads. * d86db6f1 - litex_gen/wishbone: simplify the way the bus is exposed as ios and connected to pads. * 18c57a64 - tools: rename litex_extract to litex_gen (use similar name than litedram/liteeth generators) and cleanup/simplify. * 0083e097 - Merge pull request #396 from antmicro/external-wb |\ | * 9e2aede8 - tools: add script for extracting wishbone cores | * 79a14001 - axi: add to_pads method | * e0bcb57d - wishbone: add extracting module signals to the top * | 017c91a4 - Merge pull request #397 from gsomlo/gls-csr-volatile |\ \ | |/ |/| | * 173117ad - Add 'volatile' qualifier to new CSR accessors |/ * 485934ed - doc/socdoc: fix example * 53ee9a5e - cpu/blackparrot: first cleanup pass * f3829cf0 - integration/soc: set base_address on LiteDRAMWishbone2Native, fix addressing with >= 1GB SDRAMs. * 3a6f97ff - build/sim: add Verilator FST tracing support. * 8a715f3b - Merge pull request #390 from gsomlo/gls-add-sdcard |\ | * 516cf405 - targets/nexys4ddr: add optional sdcard support | * d4d2b7f7 - bios: add litesdcard test routines to boot menu | * 7a2e33b8 - targets/nexys4ddr: add ethernet via method instead of inheritance |/ * 774a55a2 - soc_core: fix missing init on main_ram * 5d580ca4 - Merge pull request #389 from antmicro/linux_flash_offsets |\ | * 659c244a - bios/boot: allow to customize flash offsets of Linux images * | 00895518 - cores/cpu: use standard+debug variant when only debug is specified. |/ * ae45be47 - soc/cores/clock: add reset_cycles parameter to S7IDELAYCTRL/USIDELAYCTRL * 9baa3ad5 - soc/csr_bus: fix aligned_paging computation (should be done with SoC's Bus data width not bus.alignment) * 854e7cc9 - integration/soc: improve Region logger * 9cb8f68e - bios/boot: update and fix flashboot, improve verbosity * 6ed0f445 - soc: increase supporteds address_width/paging * 5b3808cb - soc_core: expose CSR paging * 0497f3ca - soc/csr_bus: improve CSR paging genericity * 351896bf - tools/litex_sim: use new sdram verbosity parameter * 67e8a042 - integration/soc: add configurable CSR Paging * 65764701 - soc_core: add back identifier * 8f6114d0 - Merge pull request #387 from BracketMaster/master |\ | * 3da204ed - update to work with mac * | 3574b909 - tools/litex_sim: specify default local/remote-ip addresses. * | aebaea77 - tools/litex_sim: add ethernet local/remote-ip arguments. |/ * 18a9d4ff - interconnect/stream: cleanup imports/idents * 57fb3720 - Merge pull request #386 from antmicro/sdram-timing-checker |\ | * eff85a99 - tools/litex_sim: add cli options to control SDRAM timing checker |/ * e4712ff7 - soc_core: fix cpu_variant renaming regression * a2f1683b - doc: rename lxsocdoc -> socdoc and update readme * baa29f1b - doc: fix regression with new irq manager * 1620f9c5 - soc/CSR: show alignment in report and add info when updating. * 5b34f4cd - soc/add_cpu: use cpu.data_width as CSR alignment, fix regression on Rocket * 2f69f607 - integration/soc: fix refactoring issues * 1d6ce66b - soc/integration/builder: update copyright, align arguments * 98ae91ad - Merge pull request #383 from Xiretza/builder-directories |\ | * b5654579 - Unify output directory handling in builder |/ * 4a15c3e2 - Merge pull request #382 from enjoy-digital/new_soc |\ | * e9c665a5 - soc_core/soc_sdram: add disclaimer | * 5558865c - soc_core: provide full retro-compatibily when add_wb_slave is called before add_memory_region | * 1b5caf56 - soc: fix busword typo | * 8b5cc345 - targets/EthernetSoC: be sure memory region is added before adding Wishbone Slave (required by new SoC) | * 240a55ba - Merge branch 'master' into new_soc | |\ | |/ |/| * | d5ad1d56 - soc/integration: move mem_decoder to soc_core * | 0a737cb6 - soc/integration/common: simplify get_version * | 4d761e1a - cores/cpu: remove separators on io_regions (requires python 3.6) * | 7c57a33b - Merge pull request #380 from Xiretza/cpunone-all-io |\ \ | * | e301df7f - Allow all memory regions to be used as IO with CPUNone |/ / * | 16d1972b - integration/common: fix mem_decoder (shadow base has been deprecated) * | 7ee9ce38 - .gitmodules/black-parrot: switch to https://github.com/enjoy-digital/black-parrot (without the submodules) * | 1dced818 - Merge pull request #278 from scanakci/blackparrot_litex |\ \ | * | d15c911c - BlackParrot initial commit w/ Litex BIOS simulation including LiteDRAM w/ Litex BIOS working on FPGA excluding LiteDRAM * | | 1d70ef69 - soc/cores/spi_opi: cleanup, rename to S7SPIOPI (since 7-Series specific for now) * | | 62f3537d - soc/cores: rename spiopi to spi_opi * | | f58e8188 - soc/cores/i2s: cleanup pass, rename to S7I2SSlave (since 7-Series specific for now), rename fifodepth to fifo_depth for consistency with others cores. * | | c2c80b5d - Merge pull request #378 from betrusted-io/merge_ip |\ \ \ | * | | 98e46c27 - reduce indents | * | | d2b394a9 - update doc comments on events for i2s | * | | 416afd31 - add doc comment for event | * | | 33d9e45a - fix formatting on spiopi | * | | cc6ed667 - Request to merge I2S and SPIOPI cores | | | * 399b65fa - soc/add_uart: fix bridge | | | * 160c55d1 - soc_core/soc_sdram: remove disclaimer (we'll add it later when designs will be adapted) | | | * b2c66b1e - soc: avoid double definition of main_ram | | | * 5f994608 - soc: improve log colors on error reporting | | | * b22d2ca0 - soc: add linker regions management | | | * abc31a92 - soc: improve log presentation/colors | | | * 91e2797b - soc: fix cpu_reset_address | | | * 0d7430fc - tools/litex_sim_new: remove | | | * 21d38701 - soc: fix build_time format | | | * b43d830f - soc/add_sdram: simplify L2 Cache, use FullMemoryWE on L2 Cache by default (seems better on all devices) | | | * ea8e745a - soc_core/common: move old mem_decoder to soc_core, simplify get_version | | | * 5e11e839 - tools/litex_sim_new: switch to dynamically allocated ethmac origin | | | * dd0c71d7 - soc/SoCRegion/Decoder: pass bus to decoder and remove mask on origin | | | * e8e4537e - soc/add_sdram: avoid L2 cache when l2_cache_size == 0. | | | * dcbdb732 - soc: remove unneeded \n | | | * 0f1811fb - tools/litex_sim_new: use new bus/csr/irq methods | | | * d320be8e - soc: use io_regions for alloc_region | | | * 9ac09ddd - tools: add litex_sim_new based on SoCCore and using add_sdram method | | | * cbcd953d - soc_core: use add_rom | | | * 487ac3da - soc/add_cpu: simplify CPUNone integration | | | * f7d4648c - soc/SoCBusHandler: add add_adapter method and use it to convert Master/Slave before connecting to the Bus | | | * 379d47a8 - soc/add_sdram: add sdram csr | | | * 3921b634 - soc/add_sdram: fix rocket, shorten comments | | | * 14b627b4 - soc/add_sdram: improve API | | | * 1faefdc0 - soc: add LiteXSoC class and mode add_identifier/uart/sdram to it | | | * 11dbe190 - soc_core/sdram: cleanup, add disclaimer | | | * 5eb88cd9 - soc: add add_sdram | | | * 39011593 - soc: add csr_regions, update copyright | | | * d2b06951 - soc: add cpu rom/sram check | | | * de100fdd - soc: add SOCIORegion and manage it | | | * 6b8c425f - soc: reorder main components/peripherals | | | * 84b5df78 - soc: add add_cpu method | | | * b676a559 - soc: fix unit-tests | | | * 0a588390 - soc: integrate constants/build | | | * 014d5a56 - soc: show sorted regions (by origin) / locs | | | * c69b6b7c - soc: simplify color theme | | | * 3cb90297 - soc: add add_uart method | | | * e5cacb8b - soc_core: cleanup imports | | | * 33d498b8 - soc_core: get_csr_address no longer used | | | * 1feff1d7 - soc: integrate CSR master/interconnect/collection and IRQ collection | | | * 3ba7c29e - soc: add add_constant/add_config methods | | | * 29bbe4c0 - soc: add add_csr_bridge method | | | * b84c291c - soc: add add_controller/add_identifier/add_timer methods | | | * 9445c33e - soc: add add_ram/add_rom methods | | | * e5a8ac1d - soc: add automatic bus data width convertion to add_master/add_slave | | | * 8f67f115 - soc/soc_core: cleanup, remove some unused attributes | | | * 2c6e5066 - soc: move SoCController from soc_core to soc | | | * 848fa20d - soc: create SoCLocHandler and use it to simplify SoCCSRHandler and SoCIRQHandler | | | * 39458c92 - soc: add use_loc_if_exists on SoCIRQ.add to use current location is already defined | | | * 1eff0799 - soc: add use_loc_if_exists on SoCCSR.add to use current location is already defined | | | * 8bc42067 - soc/integration: initial adaptation to new SoC class | | | * 6baa07a6 - soc/integration: add new soc class prorotype with SoCRegion/SoCBus/SoCCSR/SoCIRQ/SoC | |_|/ |/| | * | | 9b11e919 - cpu/vexriscv: update submodule |/ / * | ae085782 - doc: add lxsocdoc.md (README from lxsocdoc repository) * | 5ff02e23 - Merge pull request #375 from xobs/add-lxsocdoc |\ \ | * | 58598d4f - integration: svd: move svd generation to `export` | * | 73ed7e56 - soc: doc: use sphinx toctree as it was intended | * | 7c3bc0b0 - litex-doc: initial merge of lxsocdoc * | | 1944d8d9 - bios/main: add LiteX tagline * | | 40cddca9 - Merge pull request #376 from antmicro/build-sim-do-not-override-C-LD-FLAGS |\ \ \ | |/ / |/| | | * | 90fe5850 - build/sim: allow to use environment's {C,LD}FLAGS |/ / * | bd6fd3da - Merge pull request #373 from antmicro/l2-reverse |\ \ | * | f3b068e2 - tools/litex_sim: use l2_reverse flag |/ / * | 3350d33f - wishbone/Cache: add reverse parameter * | eff9caee - soc_sdram: add l2_reverse parameter * | 6e5b47f4 - Merge pull request #370 from Disasm/fixes |\ \ | * | de88ed28 - Fix argument descriptions | * | eb49ec21 - Pass --csr-json to the Builder |/ / * | b69f2993 - soc_core: add UART bridge support (simplify having to do it externally) * | 7a6c04db - build/altera/quartus: fix fmt_r typo * | c6b9676d - cpu/minerva: update (use new nMigen API) * | 9d289472 - inteconnect/stream: use PipeValid implementation for Buffer * | 1c88c0f8 - inteconnect/stream: cleanup * | cafd9c35 - Merge pull request #366 from gsomlo/gls-csr-followup |\ \ | * | ff2775c2 - software, integration/export: (re-)expose CSR subregister accessors * | | f3f9808d - interconnect/stream: add PipeValid and PipeWait to cut timing paths. * | | b22ad1ac - build/xilinx/vivado: improve readability of generated tcl/xdc files |/ / * | 7bc34a9b - integration/soc_core: revert integrate_sram_size default value (cause issues when using External SPRAM). * | b4b56db4 - Merge pull request #363 from antmicro/litex-sim-ddr4 |\ \ | * | c02dd5e8 - tools/litex_sim: add ddr4 PhySettings |/ / * | 0820adbd - tools/litex_sim: add --sdram-init parameter * | 01ae10b8 - software/bios: revert M-Labs MiSoC copyright. * | ea5ef8c1 - README: update copyright year and make sure LICENSE/README both mention MiSoC * | 95cfa6a8 - platforms/netv2: add pcie pins * | f9bc98ed - Merge pull request #359 from gregdavill/bios_ddr3_ecp5 |\ \ | * | 1f439062 - soc/software/bios/sdram: ECP5 move strobe dly_sel | * | f84f57d6 - soc/software/bios/sdram: On ECP5 strobe dly_sel after read leveling |/ / * | 52765488 - tools/litex_sim: update copyrights and cosmetic changes * | b280bb2f - Merge pull request #358 from antmicro/litex_sim_ddr |\ \ | * | 9aa97c2e - tools/litex_sim: add support for other sdram types (DDR, LPDDR, DDR2, DDR3) * | | 19ef19ce - cores/clock/create_clkout: rename clk_ce to ce, improve error reporting * | | 7e088360 - Merge pull request #357 from betrusted-io/add_clk_ce |\ \ \ | |/ / |/| | | * | 1f7549b4 - add BUFIO to clockgen buffer options | * | b3f9aa11 - add option for BUFGCE to the clock generator buffer types * | | cbc081c4 - tools/litex_sim: review/cleanup sdram-module/sdram-data-width features. * | | b35ea459 - Merge pull request #354 from antmicro/litex_sim_ddr |\ \ \ | * | | 674cfcde - tools/litex_sim: specify dram chip and data width via commandline * | | | b23f13d9 - Merge pull request #351 from antmicro/fix_sram_size_argument |\ \ \ \ | |/ / / |/| | | | * | | 7a05353a - soc_core: rename integrated_sram_size argument | * | | c4bb4169 - soc_core: fix integrated_sram_size argument type * | | | 5845df76 - build/xilinx/vivado: add pre_placement/pre_routing commands * | | | 13880882 - cores/icap: add add_timing_constraints method * | | | 2074a86e - cores/dna: cleanup and add add_timing_constraints method |/ / / * | | d39dc8cf - tools/litex_sim: cleanup/simplify * | | a0d95766 - build/sim: add -Wl,--no-as-needed to LDFLAGS for Ubuntu 16.04 support (thanks kamejoko80) * | | 80c3dc41 - targets: use mem_region.origin instead of mem_map definition (prepare for automatic mem_region allocation) * | | 53bc18cc - soc_core: add new alloc_mem/add_mem_region to allow automatic allocation of memory regions |/ / * | eae0e004 - cores/clock/xadc: ease DRP timings * | 7b92a17c - test/test_targets: limit max_sdram_size to 1GB * | 008a0894 - targets/nexys4ddr: fix typo * | 36e5274a - SoCSDRAM: set default max_sdram_size to 1GB (maximum we can map with current mem_map) * | 46c1c5c1 - targets/kcu105: remove main_ram_size_limit * | 5913c91c - SoCSDRAM: rename main_ram_size_limit to max_sdram_size and make it a parameter of SoCSDRAM, expose SoCSDRAM parameters to user * | 1c465f89 - build/lattice: add add_false_path_constraint method for API compatibility but false paths are not yet used/translated to .lpf file * | b4ba2a47 - soc/cores/uart: set rx_fifo_rx_we to True on UARTCrossover |/ * 5aa516cb - soc/cores/uart: add rx_fifo_rx_we parameter to pulse rx_fifo.source.ready on rxtx register read. * 862e784e - cpu/vexriscv: use 32-bit signal for externalResetVector * f2a1673f - targets/arty/genesys2: fix EthernetSoC/EtherboneSoC selection * 990870d0 - targets/genesys2: add EtherboneSoC * 820e79bf - platforms/de0nano: specify gpio for serial * ba366d42 - targets: cleanup EthernetSoC * a2685370 - soc/interconnect/packet/Depacketizer: use both sink.valid and sink.ready to update sink_d, fix Etherbone regression on Arty. * a168ecba - targets/arty: add EtherboneSoC * 7a4ecfa5 - targets/kcu105: update * 68e225fb - test/test_targets: update * 42efa998 - SoCCore: set default integrated_rom/ram_size to 0. For targets, defaults values are provided by soc_core_args. * 4050e608 - SoCCore: use hex for integrated_rom/sram_size * f818755c - Merge pull request #339 from gsomlo/gls-csr-cleanup |\ | * b073ebad - bios/sdram: switch to updated CSR accessors, and misc. cleanup | * 2c393041 - software, integration/export: rename and reimplement CSR accessors * | f1606dbc - tools/litex_sim: use default integrated_rom_size * | 4648db0c - cores/uart/UARTInterface: remove connect method * | 6c9f418d - soc_core: fix uart stub |/ * 63cd23c9 - cpu/vexriscv: revert mem_map_linux/main_ram * 83a7225c - SoCCore: set integrated rom/sram size default values in soc_core_args and use it in targets * 6e3f25a7 - cpu/vexriscv/mem_map_linux: update main_ram to 0x40000000 * fe14b9cf - targets/genesys2: update self.register_sdram * 39ce39a2 - soc_sdram: add l2_data_width parameter to set minimal l2_data_width to improve DRAM accesses efficiency. * 23175190 - cores/uart: add UARTCrossover * 2f03d323 - cores/uart/UART: add stream interface (phy=None), add connect method and use this for UART Stub/Crossover. * d92bd8ff - gen/fhdl/verilog: fix signed init values * ff066a5e - Merge pull request #338 from DurandA/master |\ | * d24a4b54 - Add optional 'ignore-loops' flag to nextpnr * | 26fe45fc - cores/uart: rename BridgedUART to UARTEmulator and rework/simplify it. Also integrated it in SoCCore with uart_name="emulator" * | d40bf9d8 - Merge pull request #340 from xobs/bridged-uart |\ \ | |/ |/| | * 5079a3c3 - uart: add BridgedUart |/ * f70dd482 - bios/sdram: add memspeed * fa22d6aa - wishbone/Cache: avoid REFILL_WRTAG state to improve speed. * f408527d - soc/cores/cpu: add riscv64-linux toolchain support for risc-v cpus. * 8889821c - targets: sync with litex-boards * aba8fc5c - build/altera/quartus: allow multiple call of add_period_constraint if constraint is similar. * e318287e - Merge pull request #337 from gregdavill/spi-flash |\ | * 49781467 - soc/cores/spi_flash: Don't tristate DQ2/DQ3 when bitbanging * | 2cf95e9f - platforms/minispartan6: rename sd to sdcard and regroup data lines * | e99740e8 - platforms/nexys4ddr: add sdcard pins * | 83ad674f - build/lattice/trellis: use a single fonction to parse device * | 018c7ca8 - Merge pull request #336 from kbeckmann/trellis-speed |\ \ | * | 426ab676 - trellis: Pass speed grade argument to nextpnr |/ / * | fd4cbd80 - Merge pull request #331 from betrusted-io/xadc_mods |\ \ | * | 378722a7 - soc/cores/xadc: define analog_layout and simplify analog_pads connections | * | 87d456ca - bring back analog_pads specifier, remove reset conditions on VP | * | 4dc0a614 - soc/core/xadc: cleanup, simplify and add expose_drp method - keep CSR ordering with older version, requested for software compatibility. - always enable analog capability (user will just not use it if not needed). - add expose_drp method (similar to clock.py) for cases where DRP is needed. | * | 5eec7432 - fix a couple bugs in the DRP readout path | * | 56ccaeeb - add support for DRP on XADC * | | 642d0737 - cpu/minerva: fix variant syntax warning * | | 8ba204c7 - Merge pull request #332 from gsomlo/gls-csr-mem-sel |\ \ \ | * | | d087e2e0 - interconnect/csr_bus/SRAM: allow 64-bit alignment (on 64-bit CPUs) |/ / / * | | 690de79d - cpu/microwatt: reorder sources, add comments * | | e36df2a6 - build/lattice/icestorm: increase similarities with trellis. * | | 197edad3 - soc/integration/soc_core/SoCController: specify initial reset value of scratch register in description * | | b65a36e7 - soc/integration/soc_core/SoCController: rephrase CSR descriptions a bit * | | 1f27b21f - Merge pull request #330 from xobs/document-ctrl-timer0 |\ \ \ | * | | c5aa929d - cores: timer: clean up wording for timer documentation | * | | 2d75aee7 - soc_core: ctrl: document registers | * | | a251d712 - cores: timer: fix documentation formatting |/ / / * | | db7a48c0 - soc/cores/clock: also allow margin=0 on iCE40PLL and ECP5PLL * | | caacc411 - Merge pull request #328 from betrusted-io/precise_clocks |\| | | * | 219bb7f2 - add the possibility for a "precise" clock solution |/ / * | 9336fe11 - build/microsemi/libero_soc: update add_period_constraint behavior when clock is already constrainted. * | 3022f02b - build/xilinx/vivado: update add_period_constraint behavior when clock is already constrainted. * | fe4eaf58 - build/lattice/icestorm/add_period_constraint: improve * | 6b91e882 - soc/integration/builder: avoid try/except on LiteDRAM import, just check if SoC has an sdram and do the import if so * | 2157d0f3 - Merge pull request #327 from zakgi/master |\ \ | * | 39ae230b - moving RAM offsets outside of CSR_ETHMAC define * | | f0b5c672 - Allow specifying the same clock constraint multiple times. * | | 8b955e6f - Allow LiteX builder to be used without LiteDRAM. * | | a738739a - Improve the invalid CPU type error message. * | | 85ade2b3 - build/xilinx/programmer: fix vivado_cmd when settings are sourced manually. |/ / * | ffa7ca8f - Merge pull request #321 from gsomlo/gls-rocket-aximem-wide |\ \ | * | cd8feca5 - cpu/rocket: variants with double (128b) and quad (256b) wide mem_axi * | | e754c055 - Merge pull request #319 from DurandA/feature-integer-attributes |\ \ \ | |/ / |/| | | * | 94e239ff - Add integer attributes | * | f8c58216 - Revert "gen/fhdl/verilog: allow single element verilog inline attribute" * | | 40c35550 - Merge pull request #320 from gsomlo/gls-touch-up |\ \ \ | * | | 585b50b2 - soc_core: csr_alignment assertions | * | | b6818c20 - cpu/rocket: access PLIC registers via pointer dereference |/ / / * / / 0e46913d - cpu/microwatt: add initial software support |/ / * | f883f0c7 - cpu/microwatt: add submodule * | 5da0bcbd - cpu/microwatt: set csr to 0xc0000000 (IO region) * | 39a8ebe7 - cpu/microwatt: fix add_source/add_sources * | d74a7463 - soc/cores/pwm: remove debug print(n) * | bd15f07c - platforms/netv2: add xc7a100t support * | 76e57414 - platforms/minispartan6: add assert on available devices * | bfe0bf64 - cpu/microwatt: simplify add_sources * | b9edde20 - cpu/microwatt: add io_regions and gcc_flags * | 16e7c6b6 - cpu/microwatt: update copyright * | 3d79324f - cpu/microwatt: drive stall signal (no burst support) * | da3a178b - soc/cores/pwm: add clock_domain support * | 9da28c4e - build/xilinx/XilinxMultiRegImpl: fix n=0 case * | ec7dc2d8 - build/xilinx/ise: cleanup/simplify pass, remove mist support (not aware of anyone using it) * | 1b963bb2 - soc/cores/cpu: add initial Microwatt gateware support * | c34255d2 - soc/cores/cpu/minerva: add self.reset to i_rst * | 8b6f9e0a - Merge pull request #315 from gsomlo/gls-csr-assert |\ \ | * | a0dad1b0 - soc_core: additional CSR safety assertions |/ / * | fb6b0786 - soc_core: remove static 16MB csr region allocation (use csr_address_width to allocate the correct size) * | b1a1e5e2 - soc_core: add sort of CSR regions by origin (allow csr.h/csr.csv to be ordered by origin) * | 061d593d - cores/8b10b: use real Memory for 6b5b table (to improve timings on ECP5) * | a0122f98 - build/xilinx/vivado: move build_script generation * | 18ff8f38 - build/xilinx/vivado: cleanup/simplify * | 0931ccc9 - build/lattice/icestorm: cleanup/simplify (and remove arachne-pnr support) * | b1b92053 - build/xilinx/common/platform/programmer: cleanup pass * | edaa66bb - boards: add Lambdaconcept's PCIe Screamer (R02) * | a8635c48 - targets/versa_ecp5: fix compilation with diamond * | 30a18808 - boards/targets: keep attributes are no longer needed since automatically added when applying constraints to signals. * | 23c33cfa - build: automatically add keep attribute to signals with timing constraints. * | 4c9af635 - build/altera/quartus: allow adding period constraints on nets and add optional additional sdc/qsf commands * | 22e6f5ac - build/lattice/trellis: nextpnr now handle LPF timing constraints and multiple clock domains, freq_constraint is no longer needed. * | 8fb3f9a9 - build/lattice: cleanup/simplify (no functional changes) * | 946478a7 - build/lattice: cleanup/simplify * | 60edca23 - build/microsemi: cleanup/simplify (no functional change) * | 50fdc5ce - build/altera: cleanup/simplify (no functional change) * | b17dfafa - Merge pull request #313 from mmicko/yosys_ise_flow_fix |\ \ | * | 783dfa50 - Properly select family for those currently supported | * | 6560911d - Integrate with latest yosys changes * | | 8d90f4e9 - build/xilinx/vivado: use VHDL 2008 as default * | | cfd17321 - targets/nexys4ddr: remove MEMTEST_ADDR_SIZE limitation (no longer needed) * | | 201d60f3 - targets/netv2: switch to MVP DDR3 (K4B2G1646F instead of MT41J128M16) * | | 6b820647 - targets: uniformize, improve presentation * | | 718f6995 - README: fix LitePCIe Travis-CI link * | | 6de20f18 - soc/interconnect/csr: add fields support for CSRStorage's write simulation method * | | 2567a0ae - soc/cores/gpio: add GPIO Tristate * | | d702c0fe - setup.py: update long_description * | | c9665aed - README.md: use litex logo * | | 82819dd5 - README: switch to Markdown * | | 90f9ffc5 - Merge pull request #311 from kbeckmann/trellis_cabga256 |\ \ \ | |/ / |/| | | * | f411d6d3 - trellis: Support the CABGA256 package |/ / * | 3d20442f - Merge pull request #310 from xobs/spi-flash-mode3-doc |\ \ | |/ |/| | * 581c2372 - spi_flash: correct documentation on SPI mode |/ * de205d4a - tools/remote/comm_udp: only use one socket * bdaca40f - build/generic_platform: avoid duplicate in GenericPlatform.sources * 6883a436 - soc/cores/clock: change drp_locked to CSRStatus and connect it :) * 36107cdf - soc/cores/clock: reset PLL/MMCM on all 7-series/Ultrascale with self.reset signal * e8e70b16 - Merge pull request #309 from antmicro/mmcm-fix |\ | * fd14b765 - soc/cores/clock: add lock reg and assign reset * 04017519 - soc/interconnect/axi: add Wishbone2AXILite * 4b073a44 - test/test_axi: cosmetic * d9055211 - build/tools/get_migen/litex_git_revision: avoid git fatal error message is not installed as a git repository * litex-boards changed from 84164f8 to a7fbe0a * a7fbe0a - colorlight_5a_75b: add SoC with regular UART (on J19). * 19e5366 - targets/colorlight_5a_75b: update sys/sys_ps phases. * 9ae8a0c - colorlight_5a_75b/v7.0: add spiflash pins. * ccfc021 - Merge pull request #61 from ilya-epifanov/ecp5-evn-programming |\ | * 8afc9a5 - programming the ECP5-EVN flash through the OpenOCD JTAG-SPI proxy * | 89dd00d - platforms/aller: rename pcie to pcie_x4 (for consistency with others platforms). * | cc2ac08 - Merge pull request #60 from antmicro/zcu104-sodimm |\ \ | * | d2edf54 - zcu104: add fully working SO-DIMM config |/ / * | 3b91e96 - targets/add_constant: avoid specifying value when value is None (=default) * | 555bf6c - targets/Ultrascale(+): enable USDDRPHY_DEBUG. * | 4053c02 - targets/orangecrab: add USB PLL for USB CDC with ValentyUSB. |/ * 85f3887 - targets: update PCIe on Numato targets. * 6e6b6da - platforms/orangecrab: add spisdcard pins. * 87fd4dc - platforms/minispartan6: add spisdcard pins. * 24033e3 - targets: update SDRAM to use new GENSDRPHY and new ECP5PLL phase support. * 92f793f - platforms: remove versa_ecp3 (ECP3 no longer supported). * 131733a - Merge pull request #59 from gregdavill/OrangeCrab |\ | * fe2fa09 - test_targets: revert orangecrab test build | * eb35ec9 - orangecrab: combine revisions in target | * 357aeac - test_targets: Update orangecrab platforms | * 159360d - orangecrab: Add r0.2 support | * bf3c9dc - orangecrab: Add sdram selection option | * 88d3f1d - orangecrab: r0.1 OrangeCrab fixes |/ * 78224b1 - targets/colorlight_5a_75b: add SDRAM. * a95a4ee - targets/colorlight_5a_75b: switch to add_ethernet/add_etherbone methods. * 7bba5ca - targets/c10prefkit: remove keep attributes (no longer needed, added automatically). * 6c31933 - targets: switch to add_etherbone method. * 159386e - targets: always use sys_clk_freq on SDRAM modules. * 3fb3ba1 - targets: switch to add_ethernet method instead of EthernetSoC. * 83e6fb2 - targets: switch to SoCCore/add_sdram instead of SoCSDRAM. * 33bf1d3 - Merge pull request #58 from gsomlo/gls-trellisboard-spisdcard |\ | * f021c1d - targets/trellisboard: add '--with-spi-sdcard' build option | * 69a78c8 - targets/trellisboard: switch to SoCCore, use add_ethernet() method | * 396b038 - platforms/trellisboard: fix "sdcard" pads, add "spisdcard" pads * | fb1cab8 - targets/arty: use new ISERDESE2 MEMORY mode. |/ * d0d047d - platforms/ulx3s: add spisdcard pins. * 6ab13a0 - de10nano/MiSTer: rename SPI SD CARD pins to spisdcard and remove SPI SD Card integration from target. * db9d548 - Merge pull request #56 from rob-ng15/master |\ | * bc6ef0b - Allow access to secondary sd card via hardware spi bitbanging | * a6f8069 - Add in support for secondary sd card via spi hardware bitbanging * | 57bcadb - platforms/nexys4ddr: add spisdcard pins. * | f3d7f58 - platforms/kcu105: fix pcie tx0 p/n swap. |/ * a99d258 - targets/icebreaker: use simplified version closer to the others targets. * 74a5ffb - targets/Ultrascale+: use 500MHz IDELAYCTRL reference clock. * e2a6609 - targets/Ultrascale(+): simplify CRG using USIDELAYCTRL. * cf58550 - targets/Ultrascale+: use USPDDRPHY. * ce92261 - Merge pull request #55 from antmicro/jboc/mercury-xu5 |\ | * 90de99e - platforms/mercury_xu5: fix sdram timing issues * | 75286f8 - platforms/zcu104: add missing INTERNAL_VREF on bank 64 (DQ0-31) |/ * 95e1a05 - platforms/Ultrascale: avoid unnecessary {{}} on INTERNAL_VREF. * 3f191c8 - mercury_xu5: set INTERNAL_VREF to 0.84. (similar to others Ultrascale boards with DDR4). * f4ae21a - zcu104: fix copyrights. * 5031c11 - mercury_xu5: add missing copyrights. * 8c535d1 - platforms/mercury_xu5: replace ' with ". * dc13711 - Merge pull request #52 from antmicro/jboc/mercury-xu5 |\ | * d002059 - add Enclustra Mercury XU5 board * | 2b1b968 - targets/icebreaker: simplify CRG, just use a 12MHz sys_clk and por_clk for reset. * | 9416ddd - targets/icebreaker: simplify arguments and make it closer to others targets. * | 992f706 - targets/icebreaker: simplify leds. * | 6823162 - targets/icebreaker: use specific method to set Yosys/Nextpnr settings. Rename argument to nextpnr-xxyy. * | f777d4b - targets/icebreaker: +x * | 6f517ad - targets/ecp5: make sure all BaseSoC/EthernetSoc default to trellis. * | 7776764 - Merge pull request #51 from esden/icebreaker |\ \ | |/ |/| | * 745c99b - icebreaker: Updated to build on newer litex. Disabled bios building. | * 3ac9d92 - targets: icebreaker: Minor style fixes. | * 7389671 - targets: icebreaker: set the boot address to point to SPI flash | * 093e491 - targets: icebreaker: hack to get boot working | * 77b780e - targets: icebreaker: switch to single SPI | * e6dcdc3 - targets: icebreaker: fix cpu and add spi flash | * 0185095 - targets: icebreaker: fix argument parsing for cpu | * f0dd31f - target: targets: add crg and begin getting it working | * ce9b67e - Added icebreaker platform and target. |/ * fd6c555 - Merge pull request #50 from TomKeddie/tomk_20200228_colorlight_connectors |\ | * 7b4ca20 - platforms.colorlight_5a_75b: add J1-J8 connectors |/ * be5ed35 - targets: default to trellis toolchain on all ECP5 targets (now able to build all supported targets). * b44885d - vc707: fix copyrights (Michael Betz is the initial author) * b89af28 - targets/kc705: use DDRPHY_CMD_DELAY to center write leveling. * edcc2cf - test_targets: add vc707, zcu104, vcu118 and colorlight_5a_75b * aaa10c6 - platforms/colorlight_5a_75b: add default_clk_name/period * d8de4fb - platforms/targets: keep in sync with LiteX * 18f65a7 - platforms/kc705: cleanup ddram. * d4460c1 - platforms/kcu105/vcu118: remove PRE_EMPHASIS/EQUALIZATION on dm. * 58f588f - platforms/zcu104/ddram: add PRE_EMPHASIS/EQUALIZATION settings * d87b8b3 - zcu104: add separate ddram_32/64 definitions and use ddram_32 for now. * 8ecfb13 - zcu104: add copyrights * 22b0449 - Merge pull request #47 from antmicro/zcu104 |\ | * 608541d - add ZCU104 board * | e516ff3 - vcu118/ddram: use similar IO settings than Xilinx's MIG, comment unused pins. * | 9d2ca50 - kcu105/ddram: use similar IO settings than Xilinx's MIG, comment unused pins. * | 83d2c71 - platforms/vcu118: add missing Internal Vref configuration on DDR4 C1/C2 banks |/ * 4a84e9b - targets/colorlight_5a_75b: add instruction to build/load and use bitstream with wishbone-tool * f279fe9 - vc707: cleanup platform/targets, remove Ethernet support (no Ethernet pads defined) * 3581df5 - vc707: cleanup platform/targets, remove Ethernet support (SGMII is not currently supported) * 88a1f80 - vc707/vcu118: use proper copyrights * e34654f - Merge pull request #46 from fei-g/master |\ | * 373e74f - add new board files for VC707 and VCU118, only specified limited ports for VCU118, including clock, reset and DDR4 |/ * 133f735 - Merge pull request #45 from trabucayre/fix_colorlight5A-75B_SDRAM |\ | * 2cf4e08 - platforms/colorlight_5a_75b.py: fix sdram_clock and sdram a pins |/ * f72e7bd - Merge pull request #41 from lromor/fix-wrong-import |\ | * ec30cc0 - Changed wrong imports for fomu board. * | c94360c - targets: avoid direct use of mem_decoder. * | 4edf196 - targets/EthernetSoC: be sure memory region is added before adding Wishbone Slave (required by new SoC) |/ * 83c4894 - test/test_targets: make sure all platforms are tested. * c3d8c74 - test/test_targets: update * 8211aca - Avoid Official/Partner/Community differentiation: use same directory for all platforms/targets. * 7a24406 - targets: fomu: fix compatibility for when a cpu is added * 0627f55 - de10nano: cleanup a bit, rename SDRAMSoC to MiSTerSDRAMSoC and argument to --with-mister-sdram to make it clear that it's using the MiSTer SDRAM extension board. * cf9a9ff - de10nano: update copyrights, remove trailing whitespaces * 4f85d50 - Merge pull request #39 from sajattack/de10nano |\ | * 36e1f1f - rename sw to user_sw | * 1631b07 - finish up sdram, passes memtest | * 5091a1b - WIP sdram module option | * 3a6a925 - add de10 nano board |/ * 2ec6bc0 - colorlight_5a_75b: add disclaimer * 55c0b78 - colorlight_5a_75b: revert rx_delay to 2ns, improve comment (thanks @tnt) * 4fb89fc - colorlight_5a_75b: set RGMII tx/rx_delay to 0ns in the FPGA (added by PCB/PHY) * dcc65b3 - targets/colorlight_5a_75b: switch to SoCCore, CPU and Etherbone working :) * c07e4a6 - colorlight_5a_75b: fix rst_n * 8da8ed7 - colorlight_5a_75b/v7.0: update eth_clocks/rx pinout, remove FIXME * bb80599 - platforms/colorlight_5a_75b: fix 6.1 used_led_n/user_btn_n thanks @smunaut * 43badd1 - colorlight_5a_75b/v6.1: add led/btn and remove FIXME on sdram now that clarified * 1d9e349 - partner: add colorlight_5a_75b initial support * 0706730 - targets/linsn_rv901t: cleanup arguments * 8113b49 - aller/nereid/tagus: update litepcie * 684c164 - add Linsn RV901T support * 0e4569a - platforms/camlink_4k: remove #!/usr/bin/env python3 * e72cd14 - platforms/ac701: fix eth indent * 908539d - targets/nexys4ddr: fix typo * bb99a8d - targets/kcu105: remove main_ram_size_limit * migen changed from 0.6.dev-328-gd11565a to 0.6.dev-335-g3f9809b * 3f9809b - platforms: add zc706 + coraz7_07s * e2e6c72 - sayma: sata -> fat_pipe * 7a54c79 - metlino: add ddmtd_helper_clk * 56e1b4e - metlino: add DCXO control signals * 084e2a2 - metlino: add clock muxes * 4d4d055 - metlino: add SFPs * 2480d49 - metlino: fix clk200 * nmigen changed from f207f3f to 8f5a253 * 8f5a253 - rm travis-ci * 63a53fa - Revert "setup: update project URLs." * b2d924e - Merge remote-tracking branch 'wq/master' |\ | * 12c7902 - vendor: fix a few issues in commit 2f8669ca. | * 2f8669c - lib.cdc: extract AsyncFFSynchronizer. | * a14a572 - hdl.ast: fix off-by-1 in Initial.__init__(). | * ec7aee6 - back.pysim: fix RHS codegen for Cat() and Repl(..., 0). | * 377f2d9 - back.pysim: optionally allow introspecting generated code. | * 5ae8791 - nmigen.compat.genlib.cdc: add PulseSynchronizer. | * fcbabfe - nmigen.lib.cdc: port PulseSynchronizer. | * 71d9eea - Travis: prune dependencies. | * 3fd7fe7 - Travis: test on Python 3.8. | * 57b08db - cli: update use of deprecated code. | * 8947096 - back.pysim: accept write_vcd(vcd_file=None). | * 38aa9fb - setup: update project URLs. | * 4f17cb1 - doc: remove outdated files and references to them. | * 66f4510 - README: link to IRC channel. | * 36f498e - README: consolidate requirements in the Installation section. | * 3b67271 - test_build_res: fix after commit 3e2ecdf2. | * 3e2ecdf - build.res,vendor: place clock constraint on port, not net, if possible. | * 5888f29 - xilinx_{7series,ultrascale}: run `report_methodology`. | * 27b47fa - hdl.ast: add Value.{as_signed,as_unsigned}. | * 9301e31 - test_lib_fifo: define all referenced FSM states. | * a1c5863 - hdl.dsl: make referencing undefined FSM states an error. | * 97cc78a - hdl.ir: type check ports. | * 882fddf - back.pysim: emit toplevel inputs in VCD files as well. | * d3775ee - back.pysim: make `write_vcd(traces=)` actually use those traces. | * 3df4297 - hdl.dsl: reject name mismatch in `m.domains. +=`. | * 86b57fe - hdl.dsl: type check when adding to m.domains. | * 31cd72c - hdl.mem: add synthesis attribute support. | * f7abe36 - hdl.mem: document Memory. * | 57d95b7 - Merge branch 'master' of https://github.com/nmigen/nmigen |\| | * dfcf793 - hdl.{ast,dsl}: allow whitespace in bit patterns. * | 7245b1e - Update README. * | 60447a0 - Merge branch 'master' of https://github.com/nmigen/nmigen |\| | * a295e35 - hdl.ast: update documentation for Signal. | * 49758a3 - hdl.ast: prohibit shifts by signed value. | * cce6b86 - build.plat: align pipeline with Fragment.prepare(). | * 6fd7cba - hdl.dsl: don't allow inheriting from Module. | * afece15 - hdl.ast: warn on unused property statements (Assert, Assume, etc). | * 9fb4a4f - _unused: extract must-use logic from hdl.ir. | * 687d3a3 - hdl.dsl: add missing case width check for Enum values. | * a9da9ef - README: clarify relationship to Migen. | * 9964fc6 - hdl.dsl: make `if m.{If,Elif,Else}(...)` a syntax error. | * 3ac13eb - back.rtlil: don't emit wires for empty signals. | * b72c3fc - vendor.lattice_ecp5: support internal oscillator (OSCG). | * ec3a219 - build.dsl: allow strings to be used as connector numbers. | * 7792a6c - vendor.lattice_{ice40,ecp5}: Support .il (RTLIL) files in extra_files | * c280c7c - Update README. * | c42c3a0 - vendor.lattice_{ice40,ecp5}: Support .il (RTLIL) files in extra_files |/ * a7be3b4 - hdl.ir: resolve hierarchy conflicts before creating missing domains. * 7cb3095 - hdl.xfrm: transform drivers as well in DomainRenamer. * e18385b - Remove everything deprecated in nmigen 0.1. * e4e2671 - Signal: allow to use integral Enum for reset value. * 8184efd - vendor.intel: fix output enable width for XDR=0 case. * 63902dd - build.run: fix indentation. * 476ce15 - back.rtlil: do not consider unreachable array elements when legalizing. * 318274d - hdl.mem: fix src_loc_at in ReadPort, WritePort. * 6765021 - hdl.ast: Fix width for unary minus operator on signed argument. * 7650431 - back.pysim: fix miscompilation of Signal(unsigned) - Signal(signed). * d048f06 - hdl.ast: actually remove simulator commands. * 72cfdb0 - vendor.intel: silence meaningless warnings in nMigen files * 7df7005 - back.pysim: redesign the simulator. * f8428ff - back.rtlil: infer bit width for instance parameters. * 56bb42a - hdl.ir: for instance ports, prioritize defs over uses. Full submodule status -- 3a6108a75be356a3dc53760d22782f1323248b6b edid-decode (heads/master) 3a06aa84b62ad24467fb0d2c6ceddf565e9ea447 flash_proxies (heads/master) b06e946d09807f3ab9b2e72f9c599851ab8221b4 litedram (remotes/origin/HEAD) fb478537e7d45512567b9b35b5a69c536cb588b2 liteeth (remotes/origin/HEAD) 370855d8edceda29b60a6df3cf35d5fc8602812d liteiclink (remotes/origin/HEAD) 5b7e7cde0814e1c8337f60f6bc7b3a20d5518136 litepcie (remotes/origin/HEAD) 1e3573b07d382eac50ef764fd839009bf90cb8ce litesata (heads/master) b3d1e6938f42045ade1fcb10aa2498722a4ea041 litescope (remotes/origin/HEAD) 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 liteusb (heads/master) 49d812694951a924617d8e429d72c0d4da96372a litevideo (remotes/origin/HEAD) 536ae0e619e3d9820f4e9ff8f33dc2829bc68398 litex (remotes/origin/s7mmcm_fractional_divide-4-g536ae0e6) a7fbe0a724a1b2fd788699def52c89a05cd556e5 litex-boards (remotes/origin/HEAD) 2ed761f4c138f0237a7dca8d8dd45cea0b3c24d1 litex-renode (remotes/origin/HEAD) 3f9809b0ea62b26f6c99f1b5221b22f8255bc1f6 migen (0.6.dev-335-g3f9809b) 8f5a253b22cd4ebcd56304a3662f4c70e3b34ed5 nmigen (v0.1-69-g8f5a253) --- third_party/litedram | 2 +- third_party/liteeth | 2 +- third_party/liteiclink | 2 +- third_party/litex | 2 +- third_party/litex-boards | 2 +- third_party/migen | 2 +- third_party/nmigen | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/third_party/litedram b/third_party/litedram index 4cfbc71fc..b06e946d0 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit 4cfbc71fc2e2561e82c984c074094a297c9d32e8 +Subproject commit b06e946d09807f3ab9b2e72f9c599851ab8221b4 diff --git a/third_party/liteeth b/third_party/liteeth index f532a12b4..fb478537e 160000 --- a/third_party/liteeth +++ b/third_party/liteeth @@ -1 +1 @@ -Subproject commit f532a12b40648e84cef626e9343f428e5e366fb4 +Subproject commit fb478537e7d45512567b9b35b5a69c536cb588b2 diff --git a/third_party/liteiclink b/third_party/liteiclink index 864cd831f..370855d8e 160000 --- a/third_party/liteiclink +++ b/third_party/liteiclink @@ -1 +1 @@ -Subproject commit 864cd831f3475dffd1c92d6d4a1b86608680bcf2 +Subproject commit 370855d8edceda29b60a6df3cf35d5fc8602812d diff --git a/third_party/litex b/third_party/litex index 02bfda5e3..536ae0e61 160000 --- a/third_party/litex +++ b/third_party/litex @@ -1 +1 @@ -Subproject commit 02bfda5e38f33c66e2fe9bb2f63ec02756657233 +Subproject commit 536ae0e619e3d9820f4e9ff8f33dc2829bc68398 diff --git a/third_party/litex-boards b/third_party/litex-boards index 84164f8fa..a7fbe0a72 160000 --- a/third_party/litex-boards +++ b/third_party/litex-boards @@ -1 +1 @@ -Subproject commit 84164f8fab5c65e2dd828ed20422d14026f5b140 +Subproject commit a7fbe0a724a1b2fd788699def52c89a05cd556e5 diff --git a/third_party/migen b/third_party/migen index d11565a8e..3f9809b0e 160000 --- a/third_party/migen +++ b/third_party/migen @@ -1 +1 @@ -Subproject commit d11565a8ead28eb5a18d7d4f57abe2a7562cdc8c +Subproject commit 3f9809b0ea62b26f6c99f1b5221b22f8255bc1f6 diff --git a/third_party/nmigen b/third_party/nmigen index f207f3f62..8f5a253b2 160000 --- a/third_party/nmigen +++ b/third_party/nmigen @@ -1 +1 @@ -Subproject commit f207f3f62098a56d24de90bb833f02eedf55b054 +Subproject commit 8f5a253b22cd4ebcd56304a3662f4c70e3b34ed5 From e8b3ab0261bd6f6f2a547dad75f60a5f25f22fbc Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 21 Feb 2020 14:28:04 +0100 Subject: [PATCH 061/153] targets: switch from `shadow_base` to `io_regions` This follows changes introduced by: * LiteX/dc656d4 * LiteX/a54b80b --- targets/arty/net.py | 5 ++--- targets/atlys/hdmi2usb.py | 4 ++-- targets/atlys/net.py | 5 ++--- targets/mimas_a7/net.py | 5 ++--- targets/netv2/net.py | 5 ++--- targets/nexys_video/net.py | 5 ++--- targets/opsis/encoder.py | 4 ++-- targets/opsis/hdmi2usb.py | 4 ++-- targets/opsis/net.py | 5 ++--- targets/sim/net.py | 4 ++-- 10 files changed, 20 insertions(+), 26 deletions(-) diff --git a/targets/arty/net.py b/targets/arty/net.py index e42e63076..ee20047a8 100755 --- a/targets/arty/net.py +++ b/targets/arty/net.py @@ -16,7 +16,7 @@ class NetSoC(BaseSoC): csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) + "ethmac": 0xb0000000 } mem_map.update(BaseSoC.mem_map) @@ -33,8 +33,7 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", - self.mem_map["ethmac"] | self.shadow_base, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") diff --git a/targets/atlys/hdmi2usb.py b/targets/atlys/hdmi2usb.py index c7edf293e..e32e0b1b6 100644 --- a/targets/atlys/hdmi2usb.py +++ b/targets/atlys/hdmi2usb.py @@ -16,7 +16,7 @@ class HDMI2USBSoC(BaseSoC): ) csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "encoder": 0x50000000, # (shadow @0xd0000000) + "encoder": 0xd0000000 } mem_map.update(BaseSoC.mem_map) @@ -45,7 +45,7 @@ def __init__(self, platform, *args, **kwargs): ] self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), encoder.bus) self.add_memory_region("encoder", - self.mem_map["encoder"] + self.shadow_base, 0x2000) + self.mem_map["encoder"], 0x2000, type="io") self.platform.add_period_constraint(encoder_streamer.cd_usb.clk, 10.0) diff --git a/targets/atlys/net.py b/targets/atlys/net.py index 908b69f2d..254c46b5d 100644 --- a/targets/atlys/net.py +++ b/targets/atlys/net.py @@ -15,7 +15,7 @@ class NetSoC(BaseSoC): csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) + "ethmac": 0xb0000000 } mem_map.update(BaseSoC.mem_map) @@ -34,8 +34,7 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", - self.mem_map["ethmac"] | self.shadow_base, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") diff --git a/targets/mimas_a7/net.py b/targets/mimas_a7/net.py index 960a32e02..c6ef4dd56 100755 --- a/targets/mimas_a7/net.py +++ b/targets/mimas_a7/net.py @@ -16,7 +16,7 @@ class NetSoC(BaseSoC): csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) + "ethmac": 0xb0000000 } mem_map.update(BaseSoC.mem_map) @@ -29,8 +29,7 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", - self.mem_map["ethmac"] | self.shadow_base, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") diff --git a/targets/netv2/net.py b/targets/netv2/net.py index 4b76acd53..761e643c6 100755 --- a/targets/netv2/net.py +++ b/targets/netv2/net.py @@ -16,7 +16,7 @@ class NetSoC(BaseSoC): csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) + "ethmac": 0xb0000000 } mem_map.update(BaseSoC.mem_map) @@ -29,8 +29,7 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", - self.mem_map["ethmac"] | self.shadow_base, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") diff --git a/targets/nexys_video/net.py b/targets/nexys_video/net.py index 89bf00c9d..849d8f8c9 100755 --- a/targets/nexys_video/net.py +++ b/targets/nexys_video/net.py @@ -16,7 +16,7 @@ class NetSoC(BaseSoC): csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) + "ethmac": 0xb0000000 } mem_map.update(BaseSoC.mem_map) @@ -33,8 +33,7 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", - self.mem_map["ethmac"] | self.shadow_base, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") diff --git a/targets/opsis/encoder.py b/targets/opsis/encoder.py index 9ad69c9ba..04b409a1b 100644 --- a/targets/opsis/encoder.py +++ b/targets/opsis/encoder.py @@ -16,7 +16,7 @@ class EncoderSoC(BaseSoC): ) csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "encoder": 0x50000000, # (shadow @0xd0000000) + "encoder": 0xd0000000 } mem_map.update(BaseSoC.mem_map) @@ -41,7 +41,7 @@ def __init__(self, platform, *args, **kwargs): ] self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), encoder.bus) self.add_memory_region("encoder", - self.mem_map["encoder"] + self.shadow_base, 0x2000) + self.mem_map["encoder"], 0x2000, type="io") self.platform.add_period_constraint(encoder_streamer.cd_usb.clk, 10.0) diff --git a/targets/opsis/hdmi2usb.py b/targets/opsis/hdmi2usb.py index 00f94f2de..dabcb96c0 100644 --- a/targets/opsis/hdmi2usb.py +++ b/targets/opsis/hdmi2usb.py @@ -16,7 +16,7 @@ class HDMI2USBSoC(BaseSoC): ) csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "encoder": 0x50000000, # (shadow @0xd0000000) + "encoder": 0xd0000000 } mem_map.update(BaseSoC.mem_map) @@ -41,7 +41,7 @@ def __init__(self, platform, *args, **kwargs): ] self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), encoder.bus) self.add_memory_region("encoder", - self.mem_map["encoder"] + self.shadow_base, 0x2000) + self.mem_map["encoder"], 0x2000, type="io") self.platform.add_period_constraint(encoder_streamer.cd_usb.clk, 10.0) diff --git a/targets/opsis/net.py b/targets/opsis/net.py index 69b12fb82..ad91ae2c2 100644 --- a/targets/opsis/net.py +++ b/targets/opsis/net.py @@ -17,7 +17,7 @@ class NetSoC(BaseSoC): csr_map_update(BaseSoC.csr_map, csr_peripherals) mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) + "ethmac": 0xb0000000 } mem_map.update(BaseSoC.mem_map) @@ -35,8 +35,7 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", - self.mem_map["ethmac"] | self.shadow_base, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") diff --git a/targets/sim/net.py b/targets/sim/net.py index 463cabcf0..4c5d8e6d9 100644 --- a/targets/sim/net.py +++ b/targets/sim/net.py @@ -22,7 +22,7 @@ class NetSoC(BaseSoC): csr_map.update(BaseSoC.csr_map) mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) + "ethmac": 0xb0000000 } mem_map.update(BaseSoC.mem_map) @@ -36,7 +36,7 @@ def __init__(self, *args, **kwargs): self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth")) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) + self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.add_interupt("ethmac") From 99420fce4e81cbb452ce77d10a9f1b555c800809 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 21 Feb 2020 16:13:16 +0100 Subject: [PATCH 062/153] targets: remove usages of `mem_decoder` --- targets/arty/base.py | 2 +- targets/arty/net.py | 2 +- targets/atlys/hdmi2usb.py | 2 +- targets/atlys/net.py | 2 +- targets/basys3/base.py | 2 +- targets/cmod_a7/base.py | 2 +- targets/mimas_a7/base.py | 2 +- targets/mimas_a7/net.py | 2 +- targets/neso/base.py | 2 +- targets/netv2/net.py | 2 +- targets/nexys_video/base.py | 2 +- targets/nexys_video/net.py | 2 +- targets/opsis/encoder.py | 2 +- targets/opsis/hdmi2usb.py | 2 +- targets/opsis/net.py | 2 +- targets/sim/net.py | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/targets/arty/base.py b/targets/arty/base.py index 18e25c5e3..b18c35bca 100755 --- a/targets/arty/base.py +++ b/targets/arty/base.py @@ -162,7 +162,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): endianness=self.cpu.endianness) self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus) + self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) self.add_memory_region( "spiflash", self.mem_map["spiflash"], 16*1024*1024) diff --git a/targets/arty/net.py b/targets/arty/net.py index ee20047a8..87000c3bb 100755 --- a/targets/arty/net.py +++ b/targets/arty/net.py @@ -32,7 +32,7 @@ def __init__(self, platform, *args, **kwargs): platform.request("eth")) self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") diff --git a/targets/atlys/hdmi2usb.py b/targets/atlys/hdmi2usb.py index e32e0b1b6..627b1d68b 100644 --- a/targets/atlys/hdmi2usb.py +++ b/targets/atlys/hdmi2usb.py @@ -43,7 +43,7 @@ def __init__(self, platform, *args, **kwargs): encoder_buffer.source.connect(encoder.sink), encoder.source.connect(encoder_streamer.sink) ] - self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), encoder.bus) + self.add_wb_slave(self.mem_map["encoder"], encoder.bus) self.add_memory_region("encoder", self.mem_map["encoder"], 0x2000, type="io") diff --git a/targets/atlys/net.py b/targets/atlys/net.py index 254c46b5d..1cac6f0e3 100644 --- a/targets/atlys/net.py +++ b/targets/atlys/net.py @@ -33,7 +33,7 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") diff --git a/targets/basys3/base.py b/targets/basys3/base.py index f07527a0d..a8a99da1d 100755 --- a/targets/basys3/base.py +++ b/targets/basys3/base.py @@ -93,7 +93,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): div=2) self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus) + self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) self.add_memory_region( "spiflash", self.mem_map["spiflash"], 16*1024*1024) diff --git a/targets/cmod_a7/base.py b/targets/cmod_a7/base.py index 09555e260..e2dea04e3 100755 --- a/targets/cmod_a7/base.py +++ b/targets/cmod_a7/base.py @@ -68,7 +68,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): div=2) self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus) + self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) self.add_memory_region( "spiflash", self.mem_map["spiflash"], 16*1024*1024) diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index 61179e1e9..c34ae98b9 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -134,7 +134,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): div=2) self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus) + self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) self.add_memory_region( "spiflash", self.mem_map["spiflash"], 16*1024*1024) diff --git a/targets/mimas_a7/net.py b/targets/mimas_a7/net.py index c6ef4dd56..9f41b39e9 100755 --- a/targets/mimas_a7/net.py +++ b/targets/mimas_a7/net.py @@ -28,7 +28,7 @@ def __init__(self, platform, *args, **kwargs): platform.request("eth")) self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") diff --git a/targets/neso/base.py b/targets/neso/base.py index c98994290..f75a4b753 100755 --- a/targets/neso/base.py +++ b/targets/neso/base.py @@ -128,7 +128,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): div=2) self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus) + self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) self.add_memory_region( "spiflash", self.mem_map["spiflash"], 16*1024*1024) diff --git a/targets/netv2/net.py b/targets/netv2/net.py index 761e643c6..5307a65a8 100755 --- a/targets/netv2/net.py +++ b/targets/netv2/net.py @@ -28,7 +28,7 @@ def __init__(self, platform, *args, **kwargs): platform.request("eth")) self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") diff --git a/targets/nexys_video/base.py b/targets/nexys_video/base.py index 16bea9829..add01d911 100755 --- a/targets/nexys_video/base.py +++ b/targets/nexys_video/base.py @@ -152,7 +152,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): div=2) self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(mem_decoder(self.mem_map["spiflash"]), self.spiflash.bus) + self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) self.add_memory_region( "spiflash", self.mem_map["spiflash"], 16*1024*1024) diff --git a/targets/nexys_video/net.py b/targets/nexys_video/net.py index 849d8f8c9..0c516af37 100755 --- a/targets/nexys_video/net.py +++ b/targets/nexys_video/net.py @@ -32,7 +32,7 @@ def __init__(self, platform, *args, **kwargs): platform.request("eth")) self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") diff --git a/targets/opsis/encoder.py b/targets/opsis/encoder.py index 04b409a1b..641c4f0c9 100644 --- a/targets/opsis/encoder.py +++ b/targets/opsis/encoder.py @@ -39,7 +39,7 @@ def __init__(self, platform, *args, **kwargs): encoder_buffer.source.connect(encoder.sink), encoder.source.connect(encoder_streamer.sink) ] - self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), encoder.bus) + self.add_wb_slave(self.mem_map["encoder"], encoder.bus) self.add_memory_region("encoder", self.mem_map["encoder"], 0x2000, type="io") diff --git a/targets/opsis/hdmi2usb.py b/targets/opsis/hdmi2usb.py index dabcb96c0..c7376c88f 100644 --- a/targets/opsis/hdmi2usb.py +++ b/targets/opsis/hdmi2usb.py @@ -39,7 +39,7 @@ def __init__(self, platform, *args, **kwargs): encoder_buffer.source.connect(encoder.sink), encoder.source.connect(encoder_streamer.sink) ] - self.add_wb_slave(mem_decoder(self.mem_map["encoder"]), encoder.bus) + self.add_wb_slave(self.mem_map["encoder"], encoder.bus) self.add_memory_region("encoder", self.mem_map["encoder"], 0x2000, type="io") diff --git a/targets/opsis/net.py b/targets/opsis/net.py index ad91ae2c2..441aec88d 100644 --- a/targets/opsis/net.py +++ b/targets/opsis/net.py @@ -34,7 +34,7 @@ def __init__(self, platform, *args, **kwargs): self.platform.add_source("gateware/rgmii_if.vhd") self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") diff --git a/targets/sim/net.py b/targets/sim/net.py index 4c5d8e6d9..858a99e62 100644 --- a/targets/sim/net.py +++ b/targets/sim/net.py @@ -35,7 +35,7 @@ def __init__(self, *args, **kwargs): self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth")) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.add_interupt("ethmac") From 9dd9bf7c7b5e563fbfda292bb93d32aad7555db9 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 21 Feb 2020 16:15:53 +0100 Subject: [PATCH 063/153] targets: fix setting integrated sram/rom size --- targets/arty/base.py | 8 +++----- targets/arty/net.py | 6 +++--- targets/atlys/base.py | 8 +++----- targets/atlys/net.py | 2 +- targets/basys3/base.py | 8 +++----- targets/cmod_a7/base.py | 8 +++----- targets/galatea/base.py | 8 +++----- targets/ice40_hx8k_b_evn/base.py | 10 +++++----- targets/ice40_up5k_b_evn/base.py | 11 ++++++----- targets/icebreaker/base.py | 11 ++++++----- targets/icefun/base.py | 10 +++++----- targets/matrix_voice/base.py | 8 +++----- targets/mimas_a7/base.py | 10 +++++----- targets/mimasv2/base.py | 9 ++++----- targets/minispartan6/base.py | 10 +++++----- targets/neso/base.py | 8 +++----- targets/netv2/base.py | 8 +++----- targets/netv2/net.py | 6 ++++-- targets/nexys_video/base.py | 8 +++----- targets/nexys_video/net.py | 2 +- targets/opsis/base.py | 8 +++----- targets/opsis/net.py | 2 +- targets/pano_logic_g2/base.py | 8 +++----- targets/pipistrello/base.py | 8 +++----- targets/saturn/base.py | 8 +++----- targets/sim/base.py | 12 +++++------- targets/sim/net.py | 2 +- targets/tinyfpga_bx/base.py | 10 +++++----- targets/upduino_v1/base.py | 11 ++++++----- targets/utils.py | 4 ++++ targets/waxwing/base.py | 8 +++----- targets/waxwing/net.py | 8 +++----- 32 files changed, 112 insertions(+), 136 deletions(-) diff --git a/targets/arty/base.py b/targets/arty/base.py index b18c35bca..785a0c90e 100755 --- a/targets/arty/base.py +++ b/targets/arty/base.py @@ -16,7 +16,7 @@ from gateware import led from gateware import spi_flash -from targets.utils import csr_map_update, period_ns +from targets.utils import csr_map_update, period_ns, dict_set_max class _CRG(Module): @@ -127,10 +127,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) diff --git a/targets/arty/net.py b/targets/arty/net.py index 87000c3bb..4f934ff7a 100755 --- a/targets/arty/net.py +++ b/targets/arty/net.py @@ -4,7 +4,7 @@ from liteeth.core.mac import LiteEthMAC from liteeth.phy import LiteEthPHY -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max from targets.arty.base import SoC as BaseSoC @@ -22,8 +22,8 @@ class NetSoC(BaseSoC): def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': - kwargs['integrated_rom_size'] = 0x10000 + if kwargs.get('cpu_type', 'lm32') != 'lm32': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) BaseSoC.__init__(self, platform, *args, **kwargs) diff --git a/targets/atlys/base.py b/targets/atlys/base.py index cec8e5f5b..ca272202a 100644 --- a/targets/atlys/base.py +++ b/targets/atlys/base.py @@ -16,7 +16,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -191,10 +191,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = 75*1000000 SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) diff --git a/targets/atlys/net.py b/targets/atlys/net.py index 1cac6f0e3..a9dbc5f76 100644 --- a/targets/atlys/net.py +++ b/targets/atlys/net.py @@ -21,7 +21,7 @@ class NetSoC(BaseSoC): def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': + if kwargs.get('cpu_type', 'lm32') != 'lm32': kwargs['integrated_rom_size'] = 0x10000 BaseSoC.__init__(self, platform, *args, **kwargs) diff --git a/targets/basys3/base.py b/targets/basys3/base.py index a8a99da1d..33fe2c482 100755 --- a/targets/basys3/base.py +++ b/targets/basys3/base.py @@ -14,7 +14,7 @@ from gateware import led from gateware import spi_flash -from targets.utils import csr_map_update, period_ns +from targets.utils import csr_map_update, period_ns, dict_set_max class _CRG(Module): @@ -62,10 +62,8 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) SoCCore.__init__(self, platform, clk_freq, **kwargs) diff --git a/targets/cmod_a7/base.py b/targets/cmod_a7/base.py index e2dea04e3..741c32558 100755 --- a/targets/cmod_a7/base.py +++ b/targets/cmod_a7/base.py @@ -9,7 +9,7 @@ from gateware import led from gateware import spi_flash -from targets.utils import csr_map_update, period_ns +from targets.utils import csr_map_update, period_ns, dict_set_max class _CRG(Module): @@ -37,10 +37,8 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) SoCCore.__init__(self, platform, clk_freq, **kwargs) diff --git a/targets/galatea/base.py b/targets/galatea/base.py index 712966785..db80caba0 100644 --- a/targets/galatea/base.py +++ b/targets/galatea/base.py @@ -13,7 +13,7 @@ from gateware import info -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -186,10 +186,8 @@ class BaseSoC(SoCSDRAM): #mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x4000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x4000) if 'expansion' in kwargs: tofe_board_name = kwargs.get('expansion') diff --git a/targets/ice40_hx8k_b_evn/base.py b/targets/ice40_hx8k_b_evn/base.py index a1fc14702..d7ac350c3 100644 --- a/targets/ice40_hx8k_b_evn/base.py +++ b/targets/ice40_hx8k_b_evn/base.py @@ -13,7 +13,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -55,10 +55,10 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x2800 + dict_set_max(kwargs, 'integrated_sram_size', 0x2800) + + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 # FIXME: Force either lite or minimal variants of CPUs; full is too big. diff --git a/targets/ice40_up5k_b_evn/base.py b/targets/ice40_up5k_b_evn/base.py index d5c0a2b5e..058cb0813 100644 --- a/targets/ice40_up5k_b_evn/base.py +++ b/targets/ice40_up5k_b_evn/base.py @@ -14,7 +14,7 @@ from gateware import ice40 from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max import platforms.ice40_up5k_b_evn as up5k @@ -69,10 +69,11 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0 + # disable SRAM, it'll be added later + kwargs['integrated_sram_size'] = 0x0 + + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 # FIXME: Force either lite or minimal variants of CPUs; full is too big. platform.add_extension(pmod_serial) diff --git a/targets/icebreaker/base.py b/targets/icebreaker/base.py index e14e88e16..719a49c9d 100644 --- a/targets/icebreaker/base.py +++ b/targets/icebreaker/base.py @@ -15,7 +15,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max from platforms import icebreaker @@ -71,10 +71,11 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0 + # disable SRAM, it'll be added later + kwargs['integrated_sram_size'] = 0x0 + + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 # FIXME: Force either lite or minimal variants of CPUs; full is too big. diff --git a/targets/icefun/base.py b/targets/icefun/base.py index f03aa38a6..30170403d 100644 --- a/targets/icefun/base.py +++ b/targets/icefun/base.py @@ -13,7 +13,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -55,10 +55,10 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x2800 + dict_set_max(kwargs, 'integrated_sram_size', 0x2800) + + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 # FIXME: Force either lite or minimal variants of CPUs; full is too big. diff --git a/targets/matrix_voice/base.py b/targets/matrix_voice/base.py index f770654f2..c95615dcd 100644 --- a/targets/matrix_voice/base.py +++ b/targets/matrix_voice/base.py @@ -22,7 +22,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -175,10 +175,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x4000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x4000) kwargs['uart_baudrate']=230400 diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index c34ae98b9..141b4de3e 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -14,7 +14,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, period_ns +from targets.utils import csr_map_update, period_ns, dict_set_max class _CRG(Module): @@ -95,10 +95,10 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, spiflash="spiflash_1x", **kwargs): clk_freq = int(100e6) - SoCSDRAM.__init__(self, platform, clk_freq, - integrated_rom_size=0x10000, - integrated_sram_size=0x10000, - **kwargs) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + dict_set_max(kwargs, 'integrated_sram_size', 0x10000) + + SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) self.submodules.crg = _CRG(platform) self.crg.cd_sys.clk.attr.add("keep") diff --git a/targets/mimasv2/base.py b/targets/mimasv2/base.py index d7b082e7b..7e4cb98d7 100644 --- a/targets/mimasv2/base.py +++ b/targets/mimasv2/base.py @@ -18,7 +18,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -189,11 +189,10 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=None - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x4000 + dict_set_max(kwargs, 'integrated_sram_size', 0x4000) + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size if os.environ.get('JIMMO', '0') == '0': kwargs['uart_baudrate']=19200 diff --git a/targets/minispartan6/base.py b/targets/minispartan6/base.py index 9c9b2d393..86ea06a7e 100755 --- a/targets/minispartan6/base.py +++ b/targets/minispartan6/base.py @@ -16,7 +16,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -84,10 +84,10 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x4000 + dict_set_max(kwargs, 'integrated_sram_size', 0x4000) + + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 clk_freq = 80*1000000 SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) diff --git a/targets/neso/base.py b/targets/neso/base.py index f75a4b753..908e489f1 100755 --- a/targets/neso/base.py +++ b/targets/neso/base.py @@ -13,7 +13,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, period_ns +from targets.utils import csr_map_update, period_ns, dict_set_max class _CRG(Module): @@ -97,10 +97,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) diff --git a/targets/netv2/base.py b/targets/netv2/base.py index eb5c563b0..efe5f1ad5 100755 --- a/targets/netv2/base.py +++ b/targets/netv2/base.py @@ -14,7 +14,7 @@ from gateware import cas from gateware import info -from targets.utils import csr_map_update, period_ns +from targets.utils import csr_map_update, period_ns, dict_set_max class _CRG(Module): @@ -114,10 +114,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, csr_data_width=8, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) SoCSDRAM.__init__(self, platform, clk_freq, csr_data_width=csr_data_width, **kwargs) diff --git a/targets/netv2/net.py b/targets/netv2/net.py index 5307a65a8..05c6a5656 100755 --- a/targets/netv2/net.py +++ b/targets/netv2/net.py @@ -4,7 +4,7 @@ from liteeth.core.mac import LiteEthMAC from liteeth.phy.rmii import LiteEthPHYRMII -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max from targets.netv2.base import SoC as BaseSoC @@ -21,7 +21,9 @@ class NetSoC(BaseSoC): mem_map.update(BaseSoC.mem_map) def __init__(self, platform, *args, **kwargs): - BaseSoC.__init__(self, platform, integrated_rom_size=0x10000, *args, **kwargs) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + + BaseSoC.__init__(self, platform, *args, **kwargs) self.submodules.ethphy = LiteEthPHYRMII( platform.request("eth_clocks"), diff --git a/targets/nexys_video/base.py b/targets/nexys_video/base.py index add01d911..8e4a06fc8 100755 --- a/targets/nexys_video/base.py +++ b/targets/nexys_video/base.py @@ -15,7 +15,7 @@ from gateware import oled from gateware import spi_flash -from targets.utils import csr_map_update, period_ns +from targets.utils import csr_map_update, period_ns, dict_set_max class _CRG(Module): @@ -98,10 +98,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) SoCSDRAM.__init__(self, platform, clk_freq, with_uart=False, **kwargs) diff --git a/targets/nexys_video/net.py b/targets/nexys_video/net.py index 0c516af37..440dd02d3 100755 --- a/targets/nexys_video/net.py +++ b/targets/nexys_video/net.py @@ -22,7 +22,7 @@ class NetSoC(BaseSoC): def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': + if kwargs.get('cpu_type', 'lm32') != 'lm32': kwargs['integrated_rom_size'] = 0x10000 BaseSoC.__init__(self, platform, *args, **kwargs) diff --git a/targets/opsis/base.py b/targets/opsis/base.py index 199a1d00f..386748aaa 100644 --- a/targets/opsis/base.py +++ b/targets/opsis/base.py @@ -22,7 +22,7 @@ from gateware import tofe from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class FrontPanelGPIO(Module, AutoCSR): @@ -232,10 +232,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = 50*1000000 diff --git a/targets/opsis/net.py b/targets/opsis/net.py index 441aec88d..759746f86 100644 --- a/targets/opsis/net.py +++ b/targets/opsis/net.py @@ -23,7 +23,7 @@ class NetSoC(BaseSoC): def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': + if kwargs.get('cpu_type', 'lm32') != 'lm32': kwargs['integrated_rom_size'] = 0x10000 BaseSoC.__init__(self, platform, *args, **kwargs) diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index 3245e0077..b253ffc88 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -13,7 +13,7 @@ from gateware import info from gateware import cas -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -144,10 +144,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(50e6) SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) diff --git a/targets/pipistrello/base.py b/targets/pipistrello/base.py index 82311ae12..e6eb0c804 100644 --- a/targets/pipistrello/base.py +++ b/targets/pipistrello/base.py @@ -15,7 +15,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -188,10 +188,8 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x4000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x4000) clk_freq = (83 + Fraction(1, 3))*1000*1000 diff --git a/targets/saturn/base.py b/targets/saturn/base.py index bda1b302f..25e6ed44a 100644 --- a/targets/saturn/base.py +++ b/targets/saturn/base.py @@ -14,7 +14,7 @@ from litedram.phy import s6ddrphy from litedram.core import ControllerSettings -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -189,10 +189,8 @@ class BaseSoC(SoCSDRAM): #mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x4000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x4000) clk_freq = (31 + Fraction(1, 4))*1000*1000 diff --git a/targets/sim/base.py b/targets/sim/base.py index 7defcde40..c16952e63 100644 --- a/targets/sim/base.py +++ b/targets/sim/base.py @@ -13,7 +13,7 @@ from gateware import firmware -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class BaseSoC(SoCSDRAM): @@ -28,12 +28,10 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 - if 'firmware_ram_size' not in kwargs: - kwargs['firmware_ram_size']=0x10000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) + dict_set_max(kwargs, 'firmware_ram_size', 0x10000) + if 'firmware_filename' not in kwargs: kwargs['firmware_filename'] = "build/sim_{}_{}/software/firmware/firmware.fbi".format( self.__class__.__name__.lower()[:-3], kwargs.get('cpu_type', 'lm32')) diff --git a/targets/sim/net.py b/targets/sim/net.py index 858a99e62..b396a6b90 100644 --- a/targets/sim/net.py +++ b/targets/sim/net.py @@ -28,7 +28,7 @@ class NetSoC(BaseSoC): def __init__(self, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': + if kwargs.get('cpu_type', 'lm32') != 'lm32': kwargs['integrated_rom_size'] = 0x10000 BaseSoC.__init__(self, *args, **kwargs) diff --git a/targets/tinyfpga_bx/base.py b/targets/tinyfpga_bx/base.py index bcfed41d3..703313127 100755 --- a/targets/tinyfpga_bx/base.py +++ b/targets/tinyfpga_bx/base.py @@ -13,7 +13,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max serial = [ @@ -63,10 +63,10 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x2800 + dict_set_max(kwargs, 'integrated_sram_size', 0x2800) + + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 # FIXME: Force either lite or minimal variants of CPUs; full is too big. diff --git a/targets/upduino_v1/base.py b/targets/upduino_v1/base.py index bd1fb6d74..68112068c 100644 --- a/targets/upduino_v1/base.py +++ b/targets/upduino_v1/base.py @@ -15,7 +15,7 @@ from gateware import ice40 from gateware import spi_flash -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max import platforms.upduino_v1 as upduino @@ -54,10 +54,11 @@ class BaseSoC(SoCCore): mem_map.update(SoCCore.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0 + # disable SRAM, it'll be added later + kwargs['integrated_sram_size'] = 0x0 + + # disable ROM, it'll be added later + kwargs['integrated_rom_size'] = 0x0 # FIXME: Force either lite or minimal variants of CPUs; full is too big. platform.add_extension(upduino.serial) diff --git a/targets/utils.py b/targets/utils.py index ff88ff5ac..37f6f3590 100644 --- a/targets/utils.py +++ b/targets/utils.py @@ -1,6 +1,10 @@ import pprint +def dict_set_max(d, key, value): + d[key] = max(d[key], value) if key in d else value + + def period_ns(freq): return 1e9/freq diff --git a/targets/waxwing/base.py b/targets/waxwing/base.py index dd4076fb7..b645c2ac5 100644 --- a/targets/waxwing/base.py +++ b/targets/waxwing/base.py @@ -14,7 +14,7 @@ from litedram.phy import s6ddrphy from litedram.core import ControllerSettings -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max class _CRG(Module): @@ -187,10 +187,8 @@ class BaseSoC(SoCSDRAM): #mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = (31 + Fraction(1, 4))*1000*1000 diff --git a/targets/waxwing/net.py b/targets/waxwing/net.py index ec8c6cb02..eb60f7914 100755 --- a/targets/waxwing/net.py +++ b/targets/waxwing/net.py @@ -18,7 +18,7 @@ from litedram.phy import s6ddrphy from litedram.core import ControllerSettings -from targets.utils import csr_map_update +from targets.utils import csr_map_update, dict_set_max from liteeth.phy.mii import LiteEthPHYMII from liteeth.mac import LiteEthMAC @@ -200,10 +200,8 @@ class BaseSoC(SoCSDRAM): mem_map.update(SoCSDRAM.mem_map) def __init__(self, platform, **kwargs): - if 'integrated_rom_size' not in kwargs: - kwargs['integrated_rom_size']=0x8000 - if 'integrated_sram_size' not in kwargs: - kwargs['integrated_sram_size']=0x8000 + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = (31 + Fraction(1, 4))*1000*1000 SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) From 4d69110b99209d4f2f5368d83e0f47ad1bda234d Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 31 Mar 2020 09:12:13 +0200 Subject: [PATCH 064/153] utils: add function for rounding up to 4 --- targets/utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/targets/utils.py b/targets/utils.py index 37f6f3590..d42922909 100644 --- a/targets/utils.py +++ b/targets/utils.py @@ -1,6 +1,10 @@ import pprint +def round_up_to_4(i): + return int((i + 3) / 4) * 4 + + def dict_set_max(d, key, value): d[key] = max(d[key], value) if key in d else value From 575ed00ab64be02abf66e10e7aa1ec7947c14e85 Mon Sep 17 00:00:00 2001 From: Mariusz Glebocki Date: Thu, 20 Feb 2020 18:07:34 +0100 Subject: [PATCH 065/153] pano_logic_g2: Prevent adding "keep" attribute to default clock --- platforms/pano_logic_g2.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platforms/pano_logic_g2.py b/platforms/pano_logic_g2.py index ba7917b8c..bffbc3c2b 100644 --- a/platforms/pano_logic_g2.py +++ b/platforms/pano_logic_g2.py @@ -178,6 +178,9 @@ def __init__(self, programmer="impact", device="xc6slx150"): self.add_platform_command("""CONFIG VCCAUX="2.5";""") + def do_finalize(self, fragment, *args, **kwargs): + pass + def create_programmer(self): if self.programmer == "impact": return iMPACT() From 2e7c42678154d31b90a44fd3cdac939fddd98a93 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 26 Feb 2020 11:13:18 +0100 Subject: [PATCH 066/153] build-linux: fix building VexRiscv's emulator --- ...-Use-external-hw-common.h-from-LiteX.patch | 82 +++++++++++++++++++ scripts/build-linux.sh | 7 +- 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch diff --git a/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch b/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch new file mode 100644 index 000000000..42e7bfdec --- /dev/null +++ b/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch @@ -0,0 +1,82 @@ +From f88b259ebacb84624f2df3cfd14db56a5dd2ca4f Mon Sep 17 00:00:00 2001 +From: Mateusz Holenko +Date: Mon, 24 Feb 2020 12:43:35 +0100 +Subject: [PATCH] emulator: Use external hw/common.h from LiteX + +Remove code copied from `hw/common.h` and use +the header from the LiteX repository provided +using `LITEX_BASE` environment variable. + +Content of `common.h` is now evolving (new functions +are added, some are removed) and syncing it +between repos would be cumbersome. +--- + src/main/c/emulator/makefile | 7 ++++--- + src/main/c/emulator/src/hal.c | 32 -------------------------------- + 2 files changed, 4 insertions(+), 35 deletions(-) + +diff --git a/src/main/c/emulator/makefile b/src/main/c/emulator/makefile +index 7534d08..6f3c8fc 100755 +--- a/src/main/c/emulator/makefile ++++ b/src/main/c/emulator/makefile +@@ -18,10 +18,11 @@ sim: all + qemu: CFLAGS += -DQEMU + qemu: all + +-litex: CFLAGS += -DLITEX -I${LITEX_BASE}/software/include +-litex: | check_litex_base all +-check_litex_base: ++litex: CFLAGS += -DLITEX -I${LITEX_GENERATED} -I${LITEX_BASE}/litex/soc/software/include ++litex: | check_litex all ++check_litex: + @[ "${LITEX_BASE}" ] || ( echo ">> LITEX_BASE is not set"; exit 1 ) ++ @[ "${LITEX_GENERATED}" ] || ( echo ">> LITEX_GENERATED is not set"; exit 1 ) + + include ${STANDALONE}/common/riscv64-unknown-elf.mk + include ${STANDALONE}/common/standalone.mk +diff --git a/src/main/c/emulator/src/hal.c b/src/main/c/emulator/src/hal.c +index 5a151bb..aa6745b 100644 +--- a/src/main/c/emulator/src/hal.c ++++ b/src/main/c/emulator/src/hal.c +@@ -146,38 +146,6 @@ void halInit(){ + + #ifdef LITEX + +-// this is copied from LiteX +-#define CSR_ACCESSORS_DEFINED +-static inline void csr_writeb(uint8_t value, unsigned long addr) +-{ +- *((volatile uint8_t *)addr) = value; +-} +- +-static inline uint8_t csr_readb(unsigned long addr) +-{ +- return *(volatile uint8_t *)addr; +-} +- +-static inline void csr_writew(uint16_t value, unsigned long addr) +-{ +- *((volatile uint16_t *)addr) = value; +-} +- +-static inline uint16_t csr_readw(unsigned long addr) +-{ +- return *(volatile uint16_t *)addr; +-} +- +-static inline void csr_writel(uint32_t value, unsigned long addr) +-{ +- *((volatile uint32_t *)addr) = value; +-} +- +-static inline uint32_t csr_readl(unsigned long addr) +-{ +- return *(volatile uint32_t *)addr; +-} +- + // this is a file generated by LiteX + #include + +-- +2.25.0 + diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 70d1d8627..56dcaf572 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -175,11 +175,16 @@ if [ ${CPU} = vexriscv ]; then RAM_BASE_ADDRESS=${RAM_BASE_ADDRESS::-1} EMULATOR_RAM_BASE_ADDRESS=${EMULATOR_RAM_BASE_ADDRESS::-1} + # this is a temp fix for building the emulator + cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv + git am $TOP_DIR/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch + cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv/src/main/c/emulator # offsets are hardcoded in BIOS export CFLAGS="-DDTB=$((RAM_BASE_ADDRESS + 0x01000000)) -Wl,--defsym,__ram_origin=$EMULATOR_RAM_BASE_ADDRESS" - export LITEX_BASE="$TOP_DIR/$TARGET_BUILD_DIR" + export LITEX_GENERATED="$TOP_DIR/$TARGET_BUILD_DIR/software/include" + export LITEX_BASE="$TOP_DIR/third_party/litex" export RISCV_BIN="${CPU_ARCH}-elf-newlib-" make clean make litex From 94115bf4f7f9390c599d02c100afda40ee9b226a Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:18:49 +0100 Subject: [PATCH 067/153] mkmake: Rework a bit. --- Makefile | 5 ++ mkimage.py | 135 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 127 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 8a11de777..878e7e445 100644 --- a/Makefile +++ b/Makefile @@ -203,9 +203,14 @@ ifeq ($(FIRMWARE),none) OVERRIDE_FIRMWARE=--override-firmware=none FIRMWARE_FBI= else +ifeq ($(FIRMWARE),clear) +OVERRIDE_FIRMWARE=--override-firmware=clear +FIRMWARE_FBI= +else OVERRIDE_FIRMWARE=--override-firmware=$(FIRMWARE_FILEBASE).fbi FIRMWARE_FBI=$(FIRMWARE_FILEBASE).fbi endif +endif $(IMAGE_FILE): $(GATEWARE_FILEBASE).bin $(BIOS_FILE) $(FIRMWARE_FBI) $(PYTHON) mkimage.py \ diff --git a/mkimage.py b/mkimage.py index 009ef3ad8..d852bc1e5 100755 --- a/mkimage.py +++ b/mkimage.py @@ -8,6 +8,99 @@ import make +from collections import namedtuple +from targets.utils import round_up_to_4 + + +_Region = namedtuple("Region", ["name", "desc", "start", "size"]) +class Region(_Region): + def __init__(self, name, desc, start, size): + #_Region.__init__(self, name, start, size, desc) + assert round_up_to_4(start) == start, ( + "Start invalid {} != {}".format(start, round_up_to_4(start))) + assert round_up_to_4(size) == size, ( + "Size invalid {} != {}".format(size, round_up_to_4(size))) + + def __str__(self): + return "Region(0x{:06x}, 0x{:06x}, {:10s}, {})".format( + self.start, self.end, repr(self.name), repr(self.desc)) + + @property + def end(self): + return self.start + self.size + + +def get_regions(size_gw, size_bios, size_flash): + """ + + >>> regions = get_regions(256, 128, 1000) + >>> for r in regions: + ... print(r) + Region(0x000000, 0x000100, 'Gateware', 'FPGA bitstream') + Region(0x000100, 0x000180, 'BIOS' , 'LiteX BIOS with CRC') + Region(0x000180, 0x0003e8, 'Firmware', 'Firmware in FBI format') + + """ + region_gw = Region( + "Gateware", + "FPGA bitstream", + 0, + round_up_to_4(size_gw), + ) + region_bios = Region( + "BIOS", + "LiteX BIOS with CRC", + region_gw.end, + size_bios, + ) + size_fw = round_up_to_4(size_flash - region_bios.end) + region_fw = Region( + "Firmware", + "Firmware in FBI format", + region_bios.end, + size_fw, + ) + return [region_gw, region_bios, region_fw] + + +def fill_region(image_fileobj, region, input_filename, fill_zero=False): + """ + + Output; + ----- + Gateware @ 0x00000000 (using 135100 bytes of 163840 bytes) build/ice40_hx8k_b_evn_base_vexriscv.minimal+debug//gateware/top.bin - FPGA Bitstream + ff 00 00 ff 7e aa 99 7e 51 00 01 05 92 00 21 62 03 67 72 01 10 82 00 00 11 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + ----- + + {name } @ {start } (using {input_len} bytes of {length } bytes) {input_fn} - {desc} + {hex file data} + """ + + if inputfile: + input_data = open(input_filename, "rb").read() + input_size = len(input_data) + input_result = "Loaded from {}".format(input_filename) + else: + input_data = b"" + input_size = len(input_data) + input_result = "Skipped" + + # "{name:08s} @ 0x{start:08x} " + # "(using {input_size:10} bytes of {:10} bytes - {:02.2)%) {:60s} - {}" + + #print( + # "{:08s} @ 0x{:08x} (using {:10} bytes of {:10} bytes - {:02.2)% {:60s} - {}" + #).format() + + print(" ".join("{:02x}".format(i) for i in input_data[:64])) + assert input_size < region.size + assert f.tell() < region.start, "{} < {}".format(f.tell(), region.start) + f.seek(region.start) + f.write(input_data) + if fill_zero: + while f.tell() < region.end: + f.write('\0') + def main(): parser = argparse.ArgumentParser(description=__doc__) @@ -56,8 +149,9 @@ def main(): firmware = make.get_firmware(builddir, "flash") if args.override_firmware: - if args.override_firmware.lower() == "none": + if args.override_firmware.lower() in ("none", "clear"): firmware = None + args.firmware_name = args.override_firmware else: firmware = args.override_firmware if firmware: @@ -75,6 +169,10 @@ def main(): bios_pos = platform.gateware_size firmware_pos = platform.gateware_size + bios_size + flash_size = platform.spiflash_total_size + if args.force_image_size and args.force_image_size.lower() not in ("true", "1"): + flash_size = int(args.force_image_size) + print() with open(output_file, "wb") as f: # FPGA gateware @@ -84,9 +182,13 @@ def main(): gateware_data = b"" gateware = "Skipped" - print(("Gateware @ 0x{:08x} ({:10} bytes) {:60}" + print(("Gateware @ 0x{:08x} (using {:10} bytes of {:10} bytes) {:60}" " - FPGA Bitstream" - ).format(gateware_pos, len(gateware_data), gateware)) + ).format( + gateware_pos, + len(gateware_data), + bios_pos - gateware_pos, + gateware)) print(" ".join("{:02x}".format(i) for i in gateware_data[:64])) assert len(gateware_data) < platform.gateware_size f.seek(0) @@ -102,22 +204,31 @@ def main(): assert len(bios_data) < bios_size f.seek(bios_pos) f.write(bios_data) - print((" BIOS @ 0x{:08x} ({:10} bytes) {:60}" + print((" BIOS @ 0x{:08x} (using {:10} bytes of {:10} bytes) {:60}" " - LiteX BIOS with CRC" - ).format(bios_pos, len(bios_data), bios)) + ).format( + bios_pos, + len(bios_data), + firmware_pos - bios_pos, + bios)) print(" ".join("{:02x}".format(i) for i in bios_data[:64])) if firmware: firmware_data = open(firmware, "rb").read() else: - firmware_data = b"" - firmware = "Skipped" + firmware_data = b"\xff\xff\xff\xff" + firmware = "Cleared" + #firmware_data = b"" + #firmware = "Skipped" # SoftCPU firmware - print(("Firmware @ 0x{:08x} ({:10} bytes) {:60}" + print(("Firmware @ 0x{:08x} (using {:10} bytes of {:10} bytes) {:60}" " - {} Firmware in FBI format (loaded into DRAM)" ).format( - firmware_pos, len(firmware_data), firmware, + firmware_pos, + len(firmware_data), + flash_size - firmware_pos, + firmware, args.firmware_name)) print(" ".join("{:02x}".format(i) for i in firmware_data[:64])) f.seek(firmware_pos) @@ -136,10 +247,6 @@ def main(): ).format(total, int(total*8/1024/1024), total/1024/1024)) if args.force_image_size: - if args.force_image_size.lower() in ("true", "1"): - flash_size = platform.spiflash_total_size - else: - flash_size = int(args.force_image_size) f.write(b'\xff' * (flash_size - f.tell())) print() @@ -149,4 +256,6 @@ def main(): if __name__ == "__main__": + import doctest + doctest.testmod() main() From 064a9d50ccef6128f882e6f1f946b5199aab54d9 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:22:41 +0100 Subject: [PATCH 068/153] gateware/info: Only use DNA on Xilinx devices. --- gateware/info/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gateware/info/__init__.py b/gateware/info/__init__.py index 2cc968699..45a772ca2 100644 --- a/gateware/info/__init__.py +++ b/gateware/info/__init__.py @@ -14,11 +14,12 @@ class Info(Module, AutoCSR): def __init__(self, platform, target_name): - self.submodules.dna = dna.DNA() self.submodules.git = git.GitInfo() target = target_name.lower()[:-3] self.submodules.platform = platform_info.PlatformInfo(platform.name, target) + if "xc" in platform.device: + self.submodules.dna = dna.DNA() if "xc7" in platform.device: self.submodules.xadc = xadc.XADC() From 1fe3862eb1e2ba642e8b134b96833f774c24179e Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:23:52 +0100 Subject: [PATCH 069/153] targets/utils: Fix docstring. --- targets/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) mode change 100644 => 100755 targets/utils.py diff --git a/targets/utils.py b/targets/utils.py old mode 100644 new mode 100755 index d42922909..16077088f --- a/targets/utils.py +++ b/targets/utils.py @@ -44,12 +44,14 @@ class MHzType(int): >>> a = MHzType(1) >>> a == int(1e9) True - >>> a + >>> print(a) 1 MHz >>> b = 5 * MHzType(1) >>> b == int(5e9) True >>> b + 5.000000 * MHz() + >>> print(b) 5 MHz >>> c = 200 * MHzType(1) >>> From d9cb989a5f0470a018584274b73a862249f6475e Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:25:04 +0100 Subject: [PATCH 070/153] targets/utils: Allow rewriting the commands. --- targets/utils.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/targets/utils.py b/targets/utils.py index 16077088f..0632630de 100755 --- a/targets/utils.py +++ b/targets/utils.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python3 + +import difflib import pprint @@ -77,3 +80,85 @@ def to_ns(self): MHz = MHzType(1) + + +test_build_template = [ + "yosys -q -l {build_name}.rpt {build_name}.ys", + "nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf", + "icepack {build_name}.txt {build_name}.bin" +] + + +def _platform_toolchain_cmd_split(template): + """ + + >>> cmds = _platform_toolchain_cmd_split(test_build_template) + >>> cmds["icepack"] + (2, ['icepack', '{build_name}.txt', '{build_name}.bin']) + >>> pprint.pprint(cmds["nextpnr-ice40"]) + (1, + ['nextpnr-ice40', '--json', '{build_name}.json', '--pcf', '{build_name}.pcf']) + >>> cmds["yosys"] + (0, ['yosys', '-q', '-l', '{build_name}.rpt', '{build_name}.ys']) + + """ + cmds = {} + for i, cmdline in enumerate(template): + cmdline_parts = cmdline.split() + cmds[cmdline_parts[0]] = (i, list(cmdline_parts)) + return cmds + + +def _platform_toolchain_cmd_join(cmds): + """ + + >>> cmds = _platform_toolchain_cmd_split(test_build_template) + >>> out_template = _platform_toolchain_cmd_join(cmds) + >>> "\\n".join(difflib.context_diff("\\n".join(test_build_template), "\\n".join(out_template))) + '' + >>> pprint.pprint(out_template) + ['yosys -q -l {build_name}.rpt {build_name}.ys', + 'nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf', + 'icepack {build_name}.txt {build_name}.bin'] + + """ + template = [] + while len(template) < len(cmds): + for i, cmdline_parts in cmds.values(): + if i != len(template): + continue + template.append(" ".join(cmdline_parts)) + break + else: + raise ValueError("{} not found\n{}\n{}\n".format(len(template), template, cmds)) + return template + + +def _add_switch(cmds, cmdname, argument): + """ + + >>> cmds = _platform_toolchain_cmd_split(test_build_template) + >>> _add_switch(cmds, 'icepack', '-s') + >>> out_template = _platform_toolchain_cmd_join(cmds) + >>> pprint.pprint(out_template) + ['yosys -q -l {build_name}.rpt {build_name}.ys', + 'nextpnr-ice40 --json {build_name}.json --pcf {build_name}.pcf', + 'icepack -s {build_name}.txt {build_name}.bin'] + + """ + assert argument.startswith('-'), argument + assert cmdname in cmds, (cmdname, cmds) + cmds[cmdname][-1].insert(1, argument) + + +def platform_toolchain_extend(platform, cmdname, argument): + bt = platform.toolchain.build_template + cmds = _platform_toolchain_cmd_split(bt) + _add_switch(cmds, cmdname, argument) + bt.clear() + bt.extend(_platform_toolchain_cmd_join(cmds)) + + +if __name__ == "__main__": + import doctest + doctest.testmod() From 58eab6c37458b6ee9c52b2e643c94c0b80178376 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:25:32 +0100 Subject: [PATCH 071/153] Remove old `csr_map_XXX` functions. --- targets/utils.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/targets/utils.py b/targets/utils.py index 0632630de..bd2b39557 100755 --- a/targets/utils.py +++ b/targets/utils.py @@ -16,25 +16,6 @@ def period_ns(freq): return 1e9/freq -def csr_map_update(csr_map, csr_peripherals): - csr_map.update(dict((n, v) - for v, n in enumerate(csr_peripherals, start=(max(csr_map.values()) + 1) if csr_map else 0))) - - -def csr_map_update_print(csr_map, csr_peripherals): - print() - print("-"*75) - print("Previous Max: {}".format(max(csr_map.values()))) - csr_map.update(dict((n, v) - for v, n in enumerate(csr_peripherals, start=max(csr_map.values()) + 1))) - print(" New Max: {}".format(max(csr_map.values()))) - csr_values = list((b,a) for a, b in csr_map.items()) - csr_values.sort() - pprint.pprint(csr_values) - print("-"*75) - print() - - def assert_pll_clock(requested_freq, input, feedback, divide, msg): output_freq = int(input * feedback / divide / 1e6) assert output_freq == int(requested_freq / 1e6), ( From d0c48c65ecddcd03eb4b3d25f8720a2afbaa5f1a Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:26:58 +0100 Subject: [PATCH 072/153] arty: Cleanup and modernize. --- targets/arty/base.py | 221 ++++++++++++-------------------------- targets/arty/crg.py | 30 ++++++ targets/arty/etherbone.py | 71 ++++++++++++ targets/arty/net.py | 46 ++++---- targets/arty/tf.py | 16 +-- 5 files changed, 191 insertions(+), 193 deletions(-) create mode 100755 targets/arty/crg.py create mode 100755 targets/arty/etherbone.py diff --git a/targets/arty/base.py b/targets/arty/base.py index 785a0c90e..568b49bec 100755 --- a/targets/arty/base.py +++ b/targets/arty/base.py @@ -1,192 +1,105 @@ # Support for the Digilent Arty Board from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from litex.soc.integration.soc_core import mem_decoder from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * from litex.soc.interconnect import wishbone from litedram.modules import MT41K128M16 -from litedram.phy import a7ddrphy -from litedram.core import ControllerSettings +from litedram.phy import s7ddrphy from gateware import cas from gateware import info -from gateware import led from gateware import spi_flash -from targets.utils import csr_map_update, period_ns, dict_set_max - - -class _CRG(Module): - def __init__(self, platform): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) - self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() - self.clock_domains.cd_clk100 = ClockDomain() - self.clock_domains.cd_clk50 = ClockDomain() - - clk100 = platform.request("clk100") - rst = ~platform.request("cpu_reset") - - pll_locked = Signal() - pll_fb = Signal() - self.pll_sys = Signal() - pll_sys4x = Signal() - pll_sys4x_dqs = Signal() - pll_clk200 = Signal() - pll_clk100 = Signal() - pll_clk50 = Signal() - self.specials += [ - Instance("PLLE2_BASE", - p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, - - # VCO @ 1600 MHz - p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, - p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, - i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, - - # 100 MHz - p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, - o_CLKOUT0=self.pll_sys, - - # 400 MHz - p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0, - o_CLKOUT1=pll_sys4x, - - # 400 MHz dqs - p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0, - o_CLKOUT2=pll_sys4x_dqs, - - # 200 MHz - p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0, - o_CLKOUT3=pll_clk200, - - # 50MHz - p_CLKOUT4_DIVIDE=32, p_CLKOUT4_PHASE=0.0, - o_CLKOUT4=pll_clk50, - - # 100MHz - p_CLKOUT5_DIVIDE=16, p_CLKOUT5_PHASE=0.0, - o_CLKOUT5=pll_clk100 - ), - Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), - Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk), - Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk), - Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), - Instance("BUFG", i_I=pll_clk100, o_O=self.cd_clk100.clk), - Instance("BUFG", i_I=pll_clk50, o_O=self.cd_clk50.clk), - AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), - AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst), - AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst), - AsyncResetSynchronizer(self.cd_clk50, ~pll_locked | rst), - ] - - reset_counter = Signal(4, reset=15) - ic_reset = Signal(reset=1) - self.sync.clk200 += \ - If(reset_counter != 0, - reset_counter.eq(reset_counter - 1) - ).Else( - ic_reset.eq(0) - ) - self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) - - # 25MHz clock for Ethernet - eth_clk = Signal() - self.specials += [ - Instance("BUFR", p_BUFR_DIVIDE="4", i_CE=1, i_CLR=0, i_I=clk100, o_O=eth_clk), - Instance("BUFG", i_I=eth_clk, o_O=platform.request("eth_ref_clk")), - ] +from targets.utils import period_ns, dict_set_max +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "ddrphy", - "info", - "cas", -# "leds", -# "rgb_leds", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - SoCSDRAM.mem_map = { - "rom": 0x00000000, - "sram": 0x10000000, - "main_ram": 0x40000000, - "csr": 0xe0000000, - } - - mem_map = { - "spiflash": 0x20000000, - "emulator_ram": 0x50000000, - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'emulator_ram': 0x20000000, + 'spiflash': 0xd0000000 + }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = int(100e6) - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - - self.submodules.crg = _CRG(platform) - self.crg.cd_sys.clk.attr.add("keep") - self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) - - # Basic peripherals + sys_clk_freq = int(100e6) + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR3 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT41K128M16(sys_clk_freq, "1:4") + self.submodules.ddrphy = s7ddrphy.A7DDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + nphases = 4, + sys_clk_freq = sys_clk_freq) + self.add_csr("ddrphy") + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings) + + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) - self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) -# self.submodules.leds = led.ClassicLed(Cat(platform.request("user_led", i) for i in range(4))) -# self.submodules.rgb_leds = led.RGBLed(platform.request("rgb_leds")) - - # spi flash + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ spiflash_pads = platform.request(spiflash) spiflash_pads.clk = Signal() - self.specials += Instance("STARTUPE2", - i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, - i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) + self.specials += Instance( + "STARTUPE2", + i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, + i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) spiflash_dummy = { "spiflash_1x": 9, "spiflash_4x": 11, } self.submodules.spiflash = spi_flash.SpiFlash( - spiflash_pads, - dummy=spiflash_dummy[spiflash], - div=platform.spiflash_clock_div, - endianness=self.cpu.endianness) - self.add_constant("SPIFLASH_PAGE_SIZE", 256) - self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) + spiflash_pads, + dummy=spiflash_dummy[spiflash], + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) self.add_memory_region( - "spiflash", self.mem_map["spiflash"], 16*1024*1024) - - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - # sdram - sdram_module = MT41K128M16(self.clk_freq, "1:4") - self.submodules.ddrphy = a7ddrphy.A7DDRPHY( - platform.request("ddram")) - self.add_constant("READ_LEVELING_BITSLIP", 3) - self.add_constant("READ_LEVELING_DELAY", 14) - controller_settings = ControllerSettings( - with_bandwidth=True, - cmd_buffer_depth=8, - with_refresh=True) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings) + # Support for soft-emulation for full Linux support ---------------------------------------- + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) SoC = BaseSoC diff --git a/targets/arty/crg.py b/targets/arty/crg.py new file mode 100755 index 000000000..6b6d6b590 --- /dev/null +++ b/targets/arty/crg.py @@ -0,0 +1,30 @@ +# Support for the Digilent Arty Board + +from migen import * + +from litex.soc.cores.clock import * + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) + self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_eth = ClockDomain() + + # # # + + self.submodules.pll = pll = S7PLL(speedgrade=-1) + self.comb += pll.reset.eq(~platform.request("cpu_reset")) + pll.register_clkin(platform.request("clk100"), 100e6) + pll.create_clkout(self.cd_sys, sys_clk_freq) + pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq) + pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90) + pll.create_clkout(self.cd_clk200, 200e6) + pll.create_clkout(self.cd_eth, 25e6) + + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + + self.comb += platform.request("eth_ref_clk").eq(self.cd_eth.clk) diff --git a/targets/arty/etherbone.py b/targets/arty/etherbone.py new file mode 100755 index 000000000..b53ad3da1 --- /dev/null +++ b/targets/arty/etherbone.py @@ -0,0 +1,71 @@ +from litex.soc.integration.soc_core import mem_decoder +from litex.soc.integration.soc_sdram import * + +from liteeth.common import convert_ip +from liteeth.core import LiteEthUDPIPCore +from liteeth.frontend.etherbone import LiteEthEtherbone +from liteeth.mac import LiteEthMAC +from liteeth.phy import LiteEthPHY + +from targets.arty.base import SoC as BaseSoC + + +class EtherboneSoC(BaseSoC): + def __init__(self, platform, *args, **kwargs): + # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. + if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': + kwargs['integrated_rom_size'] = 0x10000 + + BaseSoC.__init__(self, platform, *args, **kwargs) + + # Ethernet --------------------------------------------------------------------------------- + # Ethernet Phy + self.submodules.ethphy = LiteEthPHY( + clock_pads = self.platform.request("eth_clocks"), + pads = self.platform.request("eth")) + self.add_csr("ethphy") + # Ethernet Core + etherbone_mac_address = 0x10e2d5000000 + etherbone_ip_address = "192.168.100.50" + self.submodules.ethcore = LiteEthUDPIPCore( + phy = self.ethphy, + mac_address = etherbone_mac_address, + ip_address = etherbone_ip_address, + clk_freq = self.clk_freq) + # Etherbone Core + self.submodules.etherbone = LiteEthEtherbone(self.ethcore.udp, 1234) + self.add_wb_master(self.etherbone.wishbone.bus) + # timing constraints + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 1e9/25e6) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 1e9/25e6) + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.ethphy.crg.cd_eth_rx.clk, + self.ethphy.crg.cd_eth_tx.clk) + + # Analyzer --------------------------------------------------------------------------------- + #analyzer_signals = [ + # # FIXME: find interesting signals to probe + # self.cpu.ibus, + # self.cpu.dbus + #] + #self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 512) + #self.add_csr("analyzer") + + def configure_iprange(self, iprange): + iprange = [int(x) for x in iprange.split(".")] + while len(iprange) < 4: + iprange.append(0) + # Our IP address + self._configure_ip("LOCALIP", iprange[:-1]+[50]) + # IP address of tftp host + self._configure_ip("REMOTEIP", iprange[:-1]+[100]) + + def _configure_ip(self, ip_type, ip): + for i, e in enumerate(ip): + s = ip_type + str(i + 1) + s = s.upper() + self.add_constant(s, e) + + +SoC = EtherboneSoC diff --git a/targets/arty/net.py b/targets/arty/net.py index 4f934ff7a..009604804 100755 --- a/targets/arty/net.py +++ b/targets/arty/net.py @@ -1,24 +1,16 @@ -from litex.soc.integration.soc_core import mem_decoder from litex.soc.integration.soc_sdram import * from liteeth.core.mac import LiteEthMAC from liteeth.phy import LiteEthPHY -from targets.utils import csr_map_update, dict_set_max -from targets.arty.base import SoC as BaseSoC +from targets.utils import dict_set_max +from .base import BaseSoC class NetSoC(BaseSoC): - csr_peripherals = ( - "ethphy", - "ethmac", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - - mem_map = { - "ethmac": 0xb0000000 - } - mem_map.update(BaseSoC.mem_map) + mem_map = {**BaseSoC.mem_map, **{ + "ethmac": 0xb0000000, + }} def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. @@ -27,26 +19,32 @@ def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) + # Ethernet --------------------------------------------------------------------------------- + # Ethernet PHY self.submodules.ethphy = LiteEthPHY( platform.request("eth_clocks"), platform.request("eth")) - self.submodules.ethmac = LiteEthMAC( - phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) - self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") + self.add_csr("ethphy") - self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") - self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") - #self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0) - self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 40.0) - self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 40.0) + # Ethernet MAC + ethmac_win_size = 0x2000 + self.submodules.ethmac = LiteEthMAC( + phy = self.ethphy, + dw = 32, + interface = "wishbone", + endianness = self.cpu.endianness) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, ethmac_win_size) + self.add_memory_region("ethmac", self.mem_map["ethmac"], ethmac_win_size, type="io") + self.add_csr("ethmac") + self.add_interrupt("ethmac") + # timing constraints + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_rx.clk, 1e9/25e6) + self.platform.add_period_constraint(self.ethphy.crg.cd_eth_tx.clk, 1e9/25e6) self.platform.add_false_path_constraints( self.crg.cd_sys.clk, self.ethphy.crg.cd_eth_rx.clk, self.ethphy.crg.cd_eth_tx.clk) - self.add_interrupt("ethmac") - def configure_iprange(self, iprange): iprange = [int(x) for x in iprange.split(".")] while len(iprange) < 4: diff --git a/targets/arty/tf.py b/targets/arty/tf.py index 8c2211a69..ba74b0b5e 100755 --- a/targets/arty/tf.py +++ b/targets/arty/tf.py @@ -1,24 +1,10 @@ # Support for the Digilent Arty Board + from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer -from litex.build.generic_platform import Pins, Subsignal, IOStandard, Misc -from litex.soc.integration.soc_core import mem_decoder -from litex.soc.integration.soc_sdram import * -from litex.soc.integration.builder import * -from litex.soc.interconnect import wishbone from litex.soc.cores.bitbang import I2CMaster -from litedram.modules import MT41K128M16 -from litedram.phy import a7ddrphy -from litedram.core import ControllerSettings - -from gateware import cas -from gateware import info -from gateware import led -from gateware import spi_flash - -from targets.utils import csr_map_update, period_ns from targets.arty.base import BaseSoC i2c_pmod_d = [ From 8f876c9c1a5bd2f2a34477689e84ed6bee45bf78 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:28:45 +0100 Subject: [PATCH 073/153] test: Fixing up ipython_etherbone. --- test/common.py | 113 ++++++++++++++++++++++++++++++-------- test/ipython_etherbone.py | 4 +- 2 files changed, 92 insertions(+), 25 deletions(-) diff --git a/test/common.py b/test/common.py index 11fa49c70..fd5a85fc8 100644 --- a/test/common.py +++ b/test/common.py @@ -4,9 +4,8 @@ import sys import threading -from litex.soc.tools.remote import RemoteServer -from litex.soc.tools.remote import RemoteClient -from litex.soc.tools.remote import CommUART +from litex.tools.litex_server import RemoteServer +from litex.tools.litex_client import RemoteClient TOP_DIR=os.path.join(os.path.dirname(__file__), "..") @@ -17,43 +16,111 @@ class ServerProxy(threading.Thread): daemon = True - def __init__(self, port): + def __init__(self, args): threading.Thread.__init__(self) - self.port = port + self.args = args self.ready = False def run(self): - print("Starting proxy to {}".format(self.port)) - self.comm = CommUART(self.port, 115200) - self.server = RemoteServer(self.comm) + args = self.args + if args.uart: + from litex.tools.remote.comm_uart import CommUART + if args.uart_port is None: + print("Need to specify --uart-port, exiting.") + exit() + uart_port = args.uart_port + uart_baudrate = int(float(args.uart_baudrate)) + print("[CommUART] port: {} / baudrate: {} / ".format(uart_port, uart_baudrate), end="") + comm = CommUART(uart_port, uart_baudrate) + elif args.udp: + from litex.tools.remote.comm_udp import CommUDP + udp_ip = args.udp_ip + udp_port = int(args.udp_port) + print("[CommUDP] ip: {} / port: {} / ".format(udp_ip, udp_port), end="") + comm = CommUDP(udp_ip, udp_port) + elif args.pcie: + from litex.tools.remote.comm_pcie import CommPCIe + pcie_bar = args.pcie_bar + if args.pcie_bar is None: + print("Need to speficy --pcie-bar, exiting.") + exit() + print("[CommPCIe] bar: {} / ".format(args.pcie_bar), end="") + comm = CommPCIe(args.pcie_bar) + elif args.usb: + from litex.tools.remote.comm_usb import CommUSB + if args.usb_pid is None and args.usb_vid is None: + print("Need to speficy --usb-vid or --usb-pid, exiting.") + exit() + print("[CommUSB] vid: {} / pid: {} / ".format(args.usb_vid, args.usb_pid), end="") + pid = args.usb_pid + if pid is not None: + pid = int(pid, base=0) + vid = args.usb_vid + if vid is not None: + vid = int(vid, base=0) + comm = CommUSB(vid=vid, pid=pid, max_retries=args.usb_max_retries) + else: + exit() + + self.server = RemoteServer(comm, args.bind_ip, int(args.bind_port)) self.server.open() - self.server.start() + self.server.start(4) self.ready = True def connect(desc, *args, add_args=None, **kw): parser = argparse.ArgumentParser(description=desc) get_args(parser, *args, **kw) - parser.add_argument("--ipaddress") - parser.add_argument("--port") #, desc="Serial port") + + # Common arguments + parser.add_argument("--bind-ip", default="localhost", + help="Host bind address") + parser.add_argument("--bind-port", default=1234, + help="Host bind port") + + # UART arguments + parser.add_argument("--uart", action="store_true", + help="Select UART interface") + parser.add_argument("--uart-port", default=None, + help="Set UART port") + #parser.add_argument("--uart-baudrate", default=115200, + # help="Set UART baudrate") + + # UDP arguments + parser.add_argument("--udp", action="store_true", + help="Select UDP interface") + parser.add_argument("--udp-ip", default="192.168.100.50", + help="Set UDP remote IP address") + parser.add_argument("--udp-port", default=1234, + help="Set UDP remote port") + + # PCIe arguments + parser.add_argument("--pcie", action="store_true", + help="Select PCIe interface") + parser.add_argument("--pcie-bar", default=None, + help="Set PCIe BAR") + + # USB arguments + parser.add_argument("--usb", action="store_true", + help="Select USB interface") + parser.add_argument("--usb-vid", default=None, + help="Set USB vendor ID") + parser.add_argument("--usb-pid", default=None, + help="Set USB product ID") + parser.add_argument("--usb-max-retries", default=10, + help="Number of times to try reconnecting to USB") + if add_args is not None: add_args(parser) args = parser.parse_args() - if args.port: - s = ServerProxy(args.port) - s.start() - while not s.ready: - continue - - args.ipaddress = "127.0.0.1" - - elif not args.ipaddress: - args.ipaddress = "{}.50".format(args.iprange) + s = ServerProxy(args) + s.start() + while not s.ready: + continue - print("Connecting to {}".format(args.ipaddress)) test_dir = os.path.join(TOP_DIR, get_testdir(args)) - wb = RemoteClient(args.ipaddress, 1234, csr_csv="{}/csr.csv".format(test_dir)) + wb = RemoteClient(args.bind_ip, int(args.bind_port), csr_csv="{}/csr.csv".format(test_dir), debug=True) wb.open() print() print("Device DNA: {}".format(get_dna(wb))) diff --git a/test/ipython_etherbone.py b/test/ipython_etherbone.py index df8f001c4..83ac526ca 100755 --- a/test/ipython_etherbone.py +++ b/test/ipython_etherbone.py @@ -5,14 +5,14 @@ from litescope.software.driver.analyzer import LiteScopeAnalyzerDriver from common import * - +from make import get_testdir def main(): args, wb = connect("LiteX Etherbone Interactive Console") print_memmap(wb) print() - analyzer_csv = '{}/analyzer.csv'.format(make_testdir(args)) + analyzer_csv = '{}/analyzer.csv'.format(get_testdir(args)) if os.path.exists(analyzer_csv): analyzer = LiteScopeAnalyzerDriver(wb.regs, "analyzer", config_csv=analyzer_csv, debug=True) else: From 3381b3180fcc5348adc96268450d05bef92f6f0e Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:29:31 +0100 Subject: [PATCH 074/153] atlys: Cleanup and modernize. --- targets/atlys/base.py | 273 ++++++++++---------------------------- targets/atlys/crg.py | 163 +++++++++++++++++++++++ targets/atlys/hdmi2usb.py | 14 +- targets/atlys/net.py | 47 +++---- targets/atlys/video.py | 22 ++- 5 files changed, 270 insertions(+), 249 deletions(-) create mode 100644 targets/atlys/crg.py diff --git a/targets/atlys/base.py b/targets/atlys/base.py index ca272202a..3049282fc 100644 --- a/targets/atlys/base.py +++ b/targets/atlys/base.py @@ -1,12 +1,10 @@ +#!/usr/bin/env python3 # Support for the Digilent Atlys board - digilentinc.com/atlys/ -from fractions import Fraction - from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.genlib.misc import WaitTimer from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * +from litex.soc.interconnect import wishbone from litedram.modules import P3R1GE4JGF from litedram.phy import s6ddrphy @@ -16,224 +14,93 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - # Clock domain for peripherals (such as HDMI output). - self.clock_domains.cd_base50 = ClockDomain() - self.clock_domains.cd_encoder = ClockDomain() - - self.reset = Signal() - - # Input 100MHz clock - f0 = 100*1000000 - clk100 = platform.request("clk100") - clk100a = Signal() - # Input 100MHz clock (buffered) - self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) - clk100b = Signal() - self.specials += Instance( - "BUFIO2", p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk100a, o_DIVCLK=clk100b) - - f = Fraction(int(clk_freq), int(f0)) - n, m = f.denominator, f.numerator - assert f0/n*m == clk_freq - p = 8 - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_encoder = Signal() - unbuf_sys = Signal() - unbuf_unused = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=1, - # Input Clocks (100MHz) - i_CLKIN1=clk100b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., - # (300MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, - # ( 66MHz) encoder - o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=9, - # (150MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, - # (150MHz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=p//2, - # ( 50MHz) unused? - Was peripheral - o_CLKOUT4=unbuf_unused, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=12, - # ( 75MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, - ) - - - # power on reset? - reset = ~platform.request("cpu_reset") | self.reset - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - # System clock - 75MHz - self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance("BUFPLL", name="sdram_full_bufpll", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb) - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - # sdram_half - self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) - clk_sdram_half_shifted = Signal() - self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) - - output_clk = Signal() - clk = platform.request("ddram_clock") - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=output_clk) - self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) - - # Peripheral clock - 50MHz - # ------------------------------------------------------------------------------ - # The peripheral clock is kept separate from the system clock to allow - # the system clock to be increased in the future. - dcm_base50_locked = Signal() - self.specials += [ - Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", - p_CLKIN_PERIOD=10.0, - p_CLKFX_MULTIPLY=2, - p_CLKFX_DIVIDE=4, - p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE - p_CLKFXDV_DIVIDE=2, - p_SPREAD_SPECTRUM="NONE", - p_STARTUP_WAIT="FALSE", - - i_CLKIN=clk100a, - o_CLKFX=self.cd_base50.clk, - o_LOCKED=dcm_base50_locked, - i_FREEZEDCM=0, - i_RST=ResetSignal(), - ), - AsyncResetSynchronizer(self.cd_base50, - self.cd_sys.rst | ~dcm_base50_locked) - ] - platform.add_period_constraint(self.cd_base50.clk, 20) - - # Encoder clock - 66 MHz - # ------------------------------------------------------------------------------ - self.specials += Instance("BUFG", name="encoder_bufg", i_I=unbuf_encoder, o_O=self.cd_encoder.clk) - self.specials += AsyncResetSynchronizer(self.cd_encoder, self.cd_sys.rst) +from targets.utils import dict_set_max +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", -# "cas", - "ddrphy", - "info", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = 75*1000000 - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - - self.submodules.crg = _CRG(platform, clk_freq) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) - + sys_clk_freq = 75*1000000 + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR2 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = P3R1GE4JGF(sys_clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + rd_bitslip = 0, + wr_bitslip = 4, + dqs_ddr_alignment="C0") + self.add_csr("ddrphy") + controller_settings = ControllerSettings( + with_bandwidth=True) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ + # info module self.submodules.info = info.Info(platform, self.__class__.__name__) - + self.add_csr("info") + # control and status module + #self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ self.submodules.spiflash = spi_flash.SpiFlash( platform.request("spiflash4x"), dummy=platform.spiflash_read_dummy_bits, - div=platform.spiflash_clock_div) + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) - self.register_mem("spiflash", self.mem_map["spiflash"], - self.spiflash.bus, size=platform.spiflash_total_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) + self.add_memory_region( + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - #self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) - - # sdram - sdram_module = P3R1GE4JGF(self.clk_freq, "1:2") - self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( - platform.request("ddram"), - sdram_module.memtype, - rd_bitslip=0, - wr_bitslip=4, - dqs_ddr_alignment="C0") - controller_settings = ControllerSettings(with_bandwidth=True) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings) - self.comb += [ - self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), - self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), - ] + # Support for soft-emulation for full Linux support ---------------------------------------- + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) SoC = BaseSoC diff --git a/targets/atlys/crg.py b/targets/atlys/crg.py new file mode 100644 index 000000000..7d813898e --- /dev/null +++ b/targets/atlys/crg.py @@ -0,0 +1,163 @@ +# Support for the Digilent Atlys board - digilentinc.com/atlys/ + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + # Clock domain for peripherals (such as HDMI output). + self.clock_domains.cd_base50 = ClockDomain() + self.clock_domains.cd_encoder = ClockDomain() + + self.reset = Signal() + + # Input 100MHz clock + f0 = 100*1000000 + clk100 = platform.request("clk100") + clk100a = Signal() + # Input 100MHz clock (buffered) + self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) + clk100b = Signal() + self.specials += Instance( + "BUFIO2", p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk100a, o_DIVCLK=clk100b) + + f = Fraction(int(clk_freq), int(f0)) + n, m = f.denominator, f.numerator + assert f0/n*m == clk_freq + p = 8 + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_encoder = Signal() + unbuf_sys = Signal() + unbuf_unused = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=1, + # Input Clocks (100MHz) + i_CLKIN1=clk100b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., + # (300MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, + # ( 66MHz) encoder + o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=9, + # (150MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, + # (150MHz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=p//2, + # ( 50MHz) unused? - Was peripheral + o_CLKOUT4=unbuf_unused, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=12, + # ( 75MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, + ) + + + # power on reset? + reset = ~platform.request("cpu_reset") | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - 75MHz + self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) + + output_clk = Signal() + clk = platform.request("ddram_clock") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=output_clk) + self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) + + # Peripheral clock - 50MHz + # ------------------------------------------------------------------------------ + # The peripheral clock is kept separate from the system clock to allow + # the system clock to be increased in the future. + dcm_base50_locked = Signal() + self.specials += [ + Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", + p_CLKIN_PERIOD=10.0, + p_CLKFX_MULTIPLY=2, + p_CLKFX_DIVIDE=4, + p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE + p_CLKFXDV_DIVIDE=2, + p_SPREAD_SPECTRUM="NONE", + p_STARTUP_WAIT="FALSE", + + i_CLKIN=clk100a, + o_CLKFX=self.cd_base50.clk, + o_LOCKED=dcm_base50_locked, + i_FREEZEDCM=0, + i_RST=ResetSignal(), + ), + AsyncResetSynchronizer(self.cd_base50, + self.cd_sys.rst | ~dcm_base50_locked) + ] + platform.add_period_constraint(self.cd_base50.clk, 20) + + # Encoder clock - 66 MHz + # ------------------------------------------------------------------------------ + self.specials += Instance("BUFG", name="encoder_bufg", i_I=unbuf_encoder, o_O=self.cd_encoder.clk) + self.specials += AsyncResetSynchronizer(self.cd_encoder, self.cd_sys.rst) diff --git a/targets/atlys/hdmi2usb.py b/targets/atlys/hdmi2usb.py index 627b1d68b..f43c0fab5 100644 --- a/targets/atlys/hdmi2usb.py +++ b/targets/atlys/hdmi2usb.py @@ -5,20 +5,14 @@ from gateware.encoder import EncoderDMAReader, EncoderBuffer, Encoder from gateware.streamer import USBStreamer -from targets.utils import csr_map_update from targets.atlys.video import SoC as BaseSoC class HDMI2USBSoC(BaseSoC): - csr_peripherals = ( - "encoder_reader", - "encoder", + mem_map = dict( + **BaseSoC.mem_map, + encoder = 0xd0000000, ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - mem_map = { - "encoder": 0xd0000000 - } - mem_map.update(BaseSoC.mem_map) def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) @@ -29,6 +23,7 @@ def __init__(self, platform, *args, **kwargs): reverse=True, ) self.submodules.encoder_reader = EncoderDMAReader(encoder_port) + self.add_csr("encoder_reader") encoder_cdc = stream.AsyncFIFO([("data", 128)], 4) encoder_cdc = ClockDomainsRenamer({"write": "sys", "read": "encoder"})(encoder_cdc) @@ -36,6 +31,7 @@ def __init__(self, platform, *args, **kwargs): encoder = Encoder(platform) encoder_streamer = USBStreamer(platform, platform.request("fx2")) self.submodules += encoder_cdc, encoder_buffer, encoder, encoder_streamer + self.add_csr("encoder") self.comb += [ self.encoder_reader.source.connect(encoder_cdc.sink), diff --git a/targets/atlys/net.py b/targets/atlys/net.py index a9dbc5f76..53b4efb74 100644 --- a/targets/atlys/net.py +++ b/targets/atlys/net.py @@ -1,23 +1,15 @@ -from litex.soc.integration.soc_core import mem_decoder +from litex.soc.integration.soc_sdram import * from liteeth.core.mac import LiteEthMAC from liteeth.phy import LiteEthPHY -from targets.utils import csr_map_update -from targets.atlys.base import SoC as BaseSoC +from .base import BaseSoC class NetSoC(BaseSoC): - csr_peripherals = ( - "ethphy", - "ethmac", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - - mem_map = { - "ethmac": 0xb0000000 - } - mem_map.update(BaseSoC.mem_map) + mem_map = {**BaseSoC.mem_map, **{ + "ethmac": 0xb0000000, + }} def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. @@ -26,16 +18,26 @@ def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) + # Ethernet --------------------------------------------------------------------------------- + # Ethernet PHY self.submodules.ethphy = LiteEthPHY( - platform.request("eth_clocks"), - platform.request("eth"), - self.clk_freq) + clock_pads = platform.request("eth_clocks"), + pads = platform.request("eth"), + clk_freq = self.clk_freq) + self.add_csr("ethphy") + # Ethernet MAC + ethmac_win_size = 0x2000 self.submodules.ethmac = LiteEthMAC( - phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) - self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") - + phy = self.ethphy, + dw = 32, + interface = "wishbone", + endianness = self.cpu.endianness) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, ethmac_win_size) + self.add_memory_region("ethmac", self.mem_map["ethmac"], ethmac_win_size, type="io") + self.add_csr("ethmac") + self.add_interrupt("ethmac") + # timing constraints self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") # FIXME: This is probably too tight? @@ -43,7 +45,8 @@ def __init__(self, platform, *args, **kwargs): self.platform.add_false_path_constraints( self.crg.cd_sys.clk, - self.ethphy.crg.cd_eth_rx.clk) + self.ethphy.crg.cd_eth_rx.clk, + self.ethphy.crg.cd_eth_tx.clk) self.platform.add_platform_command(""" # FIXME: ERROR:Place:1108 - A clock IOB / BUFGMUX clock component pair have @@ -57,8 +60,6 @@ def __init__(self, platform, *args, **kwargs): eth_clocks_tx=platform.lookup_request("eth_clocks").tx, ) - self.add_interrupt("ethmac") - def configure_iprange(self, iprange): iprange = [int(x) for x in iprange.split(".")] while len(iprange) < 4: diff --git a/targets/atlys/video.py b/targets/atlys/video.py index 370dfd683..9155ab054 100644 --- a/targets/atlys/video.py +++ b/targets/atlys/video.py @@ -1,21 +1,10 @@ from litevideo.input import HDMIIn from litevideo.output import VideoOut -from targets.utils import csr_map_update from targets.atlys.base import BaseSoC class VideoSoC(BaseSoC): - csr_peripherals = ( - "hdmi_out0", - "hdmi_out1", - "hdmi_in0", - "hdmi_in0_edid_mem", - "hdmi_in1", - "hdmi_in1_edid_mem", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) # hdmi in 0 @@ -26,6 +15,9 @@ def __init__(self, platform, *args, **kwargs): ), fifo_depth=512, ) + self.add_csr("hdmi_in0") + self.add_csr("hdmi_in0_edid_mem") + self.add_interrupt("hdmi_in0") # hdmi in 1 self.submodules.hdmi_in1 = HDMIIn( platform.request("hdmi_in", 1), @@ -34,6 +26,9 @@ def __init__(self, platform, *args, **kwargs): ), fifo_depth=512, ) + self.add_csr("hdmi_in1") + self.add_csr("hdmi_in1_edid_mem") + self.add_interrupt("hdmi_in1") # hdmi out 0 self.submodules.hdmi_out0 = VideoOut( platform.device, @@ -47,6 +42,7 @@ def __init__(self, platform, *args, **kwargs): mode="ycbcr422", fifo_depth=4096, ) + self.add_csr("hdmi_out0") # hdmi out 1 : Share clocking with hdmi_out0 since no PLL_ADV left. self.submodules.hdmi_out1 = VideoOut( platform.device, @@ -61,6 +57,7 @@ def __init__(self, platform, *args, **kwargs): fifo_depth=4096, external_clocking=self.hdmi_out0.driver.clocking, ) + self.add_csr("hdmi_out1") # all PLL_ADV are used: router needs help... platform.add_platform_command("""INST crg_pll_adv LOC=PLL_ADV_X0Y0;""") @@ -86,8 +83,5 @@ def __init__(self, platform, *args, **kwargs): for name, value in sorted(self.platform.hdmi_infos.items()): self.add_constant(name, value) - self.add_interrupt("hdmi_in0") - self.add_interrupt("hdmi_in1") - SoC = VideoSoC From 651a9df95275503da5459b5cc9f0e1d06459d2bf Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:31:16 +0100 Subject: [PATCH 075/153] basys3: Cleanup and modernize. --- targets/basys3/base.py | 115 ++++++++++++++++++----------------------- targets/basys3/crg.py | 36 +++++++++++++ 2 files changed, 85 insertions(+), 66 deletions(-) create mode 100755 targets/basys3/crg.py diff --git a/targets/basys3/base.py b/targets/basys3/base.py index 33fe2c482..16c3936a3 100755 --- a/targets/basys3/base.py +++ b/targets/basys3/base.py @@ -1,99 +1,82 @@ # Support for the Digilent Arty Board from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer from litex.soc.integration.soc_core import * -from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * -from litedram.modules import MT41K128M16 -from litedram.phy import a7ddrphy -from litedram.core import ControllerSettings - +from gateware import cas from gateware import info -from gateware import led from gateware import spi_flash -from targets.utils import csr_map_update, period_ns, dict_set_max - - -class _CRG(Module): - def __init__(self, platform): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) - self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() - self.clock_domains.cd_clk50 = ClockDomain() - - clk100 = platform.request("clk100") - rst = platform.request("user_btn") - - pll_locked = Signal() - pll_fb = Signal() - self.pll_sys = Signal() - self.specials += [ - Instance("PLLE2_BASE", - p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, +from targets.utils import period_ns, dict_set_max - # VCO @ 1600 MHz - p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, - p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, - i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, - - # 100 MHz - p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, - o_CLKOUT0=self.pll_sys, - ), - Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), - AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), - ] +from .crg import _CRG class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "info", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + mem_map = {**SoCCore.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = int(100e6) - SoCCore.__init__(self, platform, clk_freq, **kwargs) + sys_clk_freq = int(100e6) + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) - self.submodules.crg = _CRG(platform) + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) self.crg.cd_sys.clk.attr.add("keep") - self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) + self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(sys_clk_freq)) - # Basic peripherals + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) - - # spi flash + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ spiflash_pads = platform.request(spiflash) spiflash_pads.clk = Signal() - self.specials += Instance("STARTUPE2", - i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, - i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) + self.specials += Instance( + "STARTUPE2", + i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, + i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) spiflash_dummy = { "spiflash_1x": 9, "spiflash_4x": 11, } self.submodules.spiflash = spi_flash.SpiFlash( - spiflash_pads, - dummy=spiflash_dummy[spiflash], - div=2) - self.add_constant("SPIFLASH_PAGE_SIZE", 256) - self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) + spiflash_pads, + dummy=spiflash_dummy[spiflash], + div=2, + endianness=self.cpu.endianness) + self.add_csr("spiflash") + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) self.add_memory_region( - "spiflash", self.mem_map["spiflash"], 16*1024*1024) + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) + + bios_size = 0x8000 + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size + self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) SoC = BaseSoC diff --git a/targets/basys3/crg.py b/targets/basys3/crg.py new file mode 100755 index 000000000..7d40aee4e --- /dev/null +++ b/targets/basys3/crg.py @@ -0,0 +1,36 @@ +# Support for the Digilent Arty Board + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) + self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_clk50 = ClockDomain() + + clk100 = platform.request("clk100") + rst = platform.request("user_btn") + + pll_locked = Signal() + pll_fb = Signal() + self.pll_sys = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1600 MHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, + p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 100 MHz + p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, + o_CLKOUT0=self.pll_sys, + ), + Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), + ] From d24a5fe0a8c1692ccda7c78cb3d126bab11719db Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:52:44 +0100 Subject: [PATCH 076/153] cmod_a7: Cleanup and modernize. --- targets/cmod_a7/base.py | 88 ++++++++++++++++++++++------------------- targets/cmod_a7/crg.py | 16 ++++++++ 2 files changed, 64 insertions(+), 40 deletions(-) create mode 100755 targets/cmod_a7/crg.py diff --git a/targets/cmod_a7/base.py b/targets/cmod_a7/base.py index 741c32558..fecb9d2e0 100755 --- a/targets/cmod_a7/base.py +++ b/targets/cmod_a7/base.py @@ -1,74 +1,82 @@ # Support for the Digilent Cmod A7 Board from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * +from gateware import cas from gateware import info -from gateware import led from gateware import spi_flash -from targets.utils import csr_map_update, period_ns, dict_set_max +from targets.utils import period_ns, dict_set_max - -class _CRG(Module): - def __init__(self, platform): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_clk200 = ClockDomain() - clk12 = platform.request("clk12") - rst = platform.request("user_btn", 0) - self.specials += [ - Instance("BUFG", i_I=clk12, o_O=self.cd_sys.clk), - AsyncResetSynchronizer(self.cd_sys, rst), - ] +from .crg import _CRG class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "info", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + mem_map = {**SoCCore.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = int(100e6) - SoCCore.__init__(self, platform, clk_freq, **kwargs) + sys_clk_freq = int(100e6) + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) - self.submodules.crg = _CRG(platform) + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) self.crg.cd_sys.clk.attr.add("keep") - self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) + self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(sys_clk_freq)) - # Basic peripherals + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") - # spi flash + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ spiflash_pads = platform.request(spiflash) spiflash_pads.clk = Signal() - self.specials += Instance("STARTUPE2", - i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, - i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) + self.specials += Instance( + "STARTUPE2", + i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, + i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) spiflash_dummy = { "spiflash_1x": 9, "spiflash_4x": 11, } self.submodules.spiflash = spi_flash.SpiFlash( - spiflash_pads, - dummy=spiflash_dummy[spiflash], - div=2) - self.add_constant("SPIFLASH_PAGE_SIZE", 256) - self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) + spiflash_pads, + dummy=spiflash_dummy[spiflash], + div=2, + endianness=self.cpu.endianness) + self.add_csr("spiflash") + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) self.add_memory_region( - "spiflash", self.mem_map["spiflash"], 16*1024*1024) + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) + + bios_size = 0x8000 + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size + self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) SoC = BaseSoC diff --git a/targets/cmod_a7/crg.py b/targets/cmod_a7/crg.py new file mode 100755 index 000000000..bc6fde1b2 --- /dev/null +++ b/targets/cmod_a7/crg.py @@ -0,0 +1,16 @@ +# Support for the Digilent Cmod A7 Board + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_clk200 = ClockDomain() + clk12 = platform.request("clk12") + rst = platform.request("user_btn", 0) + self.specials += [ + Instance("BUFG", i_I=clk12, o_O=self.cd_sys.clk), + AsyncResetSynchronizer(self.cd_sys, rst), + ] From 2d6489c8dd4812503feca85153f2b138c648d954 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:53:05 +0100 Subject: [PATCH 077/153] galatea: Cleanup and modernize. --- targets/galatea/base.py | 242 +++++++--------------------------------- targets/galatea/crg.py | 161 ++++++++++++++++++++++++++ 2 files changed, 202 insertions(+), 201 deletions(-) create mode 100644 targets/galatea/crg.py diff --git a/targets/galatea/base.py b/targets/galatea/base.py index db80caba0..21519bcb9 100644 --- a/targets/galatea/base.py +++ b/targets/galatea/base.py @@ -1,8 +1,6 @@ # Support for Numato Galatea - https://numato.com/product/galatea-pci-express-spartan-6-fpga-development-board -from fractions import Fraction from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * @@ -11,215 +9,57 @@ from litedram.phy import s6ddrphy from litedram.core import ControllerSettings +from gateware import cas from gateware import info +from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys2x = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - # Clock domain for peripherals (such as HDMI output). - self.clock_domains.cd_base50 = ClockDomain() - - self.reset = Signal() - - # Input 100MHz clock - f0 = 100*1000000 - clk100 = platform.request("clk100") - clk100a = Signal() - # Input 100MHz clock (buffered) - self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) - clk100b = Signal() - self.specials += Instance( - "BUFIO2", p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk100a, o_DIVCLK=clk100b) - - f = Fraction(int(clk_freq), int(f0)) - n, m = f.denominator, f.numerator - assert f0/n*m == clk_freq - p = 8 - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_encoder = Signal() - unbuf_sys = Signal() - unbuf_sys2x = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=1, - # Input Clocks (100MHz) - i_CLKIN1=clk100b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., - # (400MHz) ddr3 wr/rd full clock - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//8, - # ( 66MHz) encoder - o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=6, - # (200MHz) sdram_half - ddr3 dqs adr ctrl off-chip - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=230., p_CLKOUT2_DIVIDE=p//4, - # (200MHz) off-chip ddr - ddr3 half clock - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=210., p_CLKOUT3_DIVIDE=p//4, - # (100MHz) sys2x - 2x system clock - o_CLKOUT4=unbuf_sys2x, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//2, - # ( 50MHz) periph / sys - system clock - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, - ) - - - # power on reset? - reset = ~platform.request("cpu_reset") | self.reset - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - # System clock - 50MHz - self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - # sys2x - self.specials += Instance("BUFG", name="sys2x_bufg", i_I=unbuf_sys2x, o_O=self.cd_sys2x.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys2x, ~pll_lckd | (por > 0)) - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk8x_wr_strb = Signal() - self.clk8x_rd_strb = Signal() - - # sdram_full - self.specials += Instance("BUFPLL", name="sdram_full_bufpll", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys2x.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk8x_wr_strb) - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk8x_rd_strb.eq(self.clk8x_wr_strb), - ] - # sdram_half - self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) - clk_sdram_half_shifted = Signal() - self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) - - output_clk = Signal() - clk = platform.request("ddram_clock") - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=output_clk) - self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) - - # Peripheral clock - 50MHz - # ------------------------------------------------------------------------------ - # The peripheral clock is kept separate from the system clock to allow - # the system clock to be increased in the future. - dcm_base50_locked = Signal() - self.specials += [ - Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", - p_CLKIN_PERIOD=10.0, - p_CLKFX_MULTIPLY=2, - p_CLKFX_DIVIDE=4, - p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE - p_CLKFXDV_DIVIDE=2, - p_SPREAD_SPECTRUM="NONE", - p_STARTUP_WAIT="FALSE", - - i_CLKIN=clk100a, - o_CLKFX=self.cd_base50.clk, - o_LOCKED=dcm_base50_locked, - i_FREEZEDCM=0, - i_RST=ResetSignal(), - ), - AsyncResetSynchronizer(self.cd_base50, - self.cd_sys.rst | ~dcm_base50_locked) - ] - platform.add_period_constraint(self.cd_base50.clk, 20) +from targets.utils import dict_set_max +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "ddrphy", - "info", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - # FIXME: Add spiflash - #mem_map = { - # "spiflash": 0x20000000, # (default shadow @0xa0000000) - #} - #mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} - def __init__(self, platform, **kwargs): + def __init__(self, platform, spiflash="spiflash_1x", **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) - if 'expansion' in kwargs: - tofe_board_name = kwargs.get('expansion') - del kwargs['expansion'] - else: - tofe_board_name = None - - - clk_freq = 50*1000000 - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - - self.submodules.crg = _CRG(platform, clk_freq) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) - - # Basic peripherals + sys_clk_freq = 50*1000000 + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR3 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT41J128M16(self.clk_freq, "1:4") + self.submodules.ddrphy = s6ddrphy.S6QuarterRateDDRPHY( + platform.request("ddram"), + rd_bitslip=0, + wr_bitslip=4, + dqs_ddr_alignment="C0") + controller_settings = ControllerSettings(with_bandwidth=True) + self.add_csr("ddrphy") + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk8x_wr_strb.eq(self.crg.clk8x_wr_strb), + self.ddrphy.clk8x_rd_strb.eq(self.crg.clk8x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + - # sdram - sdram_module = MT41J128M16(self.clk_freq, "1:4") - self.submodules.ddrphy = s6ddrphy.S6QuarterRateDDRPHY( - platform.request("ddram"), - rd_bitslip=0, - wr_bitslip=4, - dqs_ddr_alignment="C0") - controller_settings = ControllerSettings(with_bandwidth=True) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings) - self.comb += [ - self.ddrphy.clk8x_wr_strb.eq(self.crg.clk8x_wr_strb), - self.ddrphy.clk8x_rd_strb.eq(self.crg.clk8x_rd_strb), - ] SoC = BaseSoC diff --git a/targets/galatea/crg.py b/targets/galatea/crg.py new file mode 100644 index 000000000..0bdc24b7d --- /dev/null +++ b/targets/galatea/crg.py @@ -0,0 +1,161 @@ +# Support for Numato Galatea - https://numato.com/product/galatea-pci-express-spartan-6-fpga-development-board + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys2x = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + # Clock domain for peripherals (such as HDMI output). + self.clock_domains.cd_base50 = ClockDomain() + + self.reset = Signal() + + # Input 100MHz clock + f0 = 100*1000000 + clk100 = platform.request("clk100") + clk100a = Signal() + # Input 100MHz clock (buffered) + self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) + clk100b = Signal() + self.specials += Instance( + "BUFIO2", p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk100a, o_DIVCLK=clk100b) + + f = Fraction(int(clk_freq), int(f0)) + n, m = f.denominator, f.numerator + assert f0/n*m == clk_freq + p = 8 + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_encoder = Signal() + unbuf_sys = Signal() + unbuf_sys2x = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=1, + # Input Clocks (100MHz) + i_CLKIN1=clk100b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., + # (400MHz) ddr3 wr/rd full clock + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//8, + # ( 66MHz) encoder + o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=6, + # (200MHz) sdram_half - ddr3 dqs adr ctrl off-chip + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=230., p_CLKOUT2_DIVIDE=p//4, + # (200MHz) off-chip ddr - ddr3 half clock + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=210., p_CLKOUT3_DIVIDE=p//4, + # (100MHz) sys2x - 2x system clock + o_CLKOUT4=unbuf_sys2x, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//2, + # ( 50MHz) periph / sys - system clock + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, + ) + + + # power on reset? + reset = ~platform.request("cpu_reset") | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - 50MHz + self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + # sys2x + self.specials += Instance("BUFG", name="sys2x_bufg", i_I=unbuf_sys2x, o_O=self.cd_sys2x.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys2x, ~pll_lckd | (por > 0)) + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk8x_wr_strb = Signal() + self.clk8x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys2x.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk8x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk8x_rd_strb.eq(self.clk8x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) + + output_clk = Signal() + clk = platform.request("ddram_clock") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=output_clk) + self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) + + # Peripheral clock - 50MHz + # ------------------------------------------------------------------------------ + # The peripheral clock is kept separate from the system clock to allow + # the system clock to be increased in the future. + dcm_base50_locked = Signal() + self.specials += [ + Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", + p_CLKIN_PERIOD=10.0, + p_CLKFX_MULTIPLY=2, + p_CLKFX_DIVIDE=4, + p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE + p_CLKFXDV_DIVIDE=2, + p_SPREAD_SPECTRUM="NONE", + p_STARTUP_WAIT="FALSE", + + i_CLKIN=clk100a, + o_CLKFX=self.cd_base50.clk, + o_LOCKED=dcm_base50_locked, + i_FREEZEDCM=0, + i_RST=ResetSignal(), + ), + AsyncResetSynchronizer(self.cd_base50, + self.cd_sys.rst | ~dcm_base50_locked) + ] + platform.add_period_constraint(self.cd_base50.clk, 20) From 9d50811a7e4a4fdb980df426ad20870c0498624b Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:53:39 +0100 Subject: [PATCH 078/153] mimas_a7: Cleanup and modernize. --- targets/mimas_a7/base.py | 188 ++++++++++++++------------------- targets/mimas_a7/bridge_net.py | 26 +++-- targets/mimas_a7/crg.py | 67 ++++++++++++ targets/mimas_a7/net.py | 42 ++++---- targets/mimas_a7/video.py | 23 ++-- 5 files changed, 187 insertions(+), 159 deletions(-) create mode 100755 targets/mimas_a7/crg.py diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index 141b4de3e..d7dddcd84 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -1,142 +1,110 @@ # Support for Numato Mimas A7 board from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from litex.soc.integration.soc_core import mem_decoder from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * -from litex.soc.cores.uart import * +from litex.soc.interconnect import wishbone from litedram.modules import MT41K128M16 -from litedram.phy import a7ddrphy +from litedram.phy import s7ddrphy from litedram.core import ControllerSettings +from gateware import cas from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, period_ns, dict_set_max - - -class _CRG(Module): - def __init__(self, platform): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) - self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() - self.clock_domains.cd_clk100 = ClockDomain() - - clk100 = platform.request("clk100") - rst = platform.request("cpu_reset") - - pll_locked = Signal() - pll_fb = Signal() - self.pll_sys = Signal() - pll_sys4x = Signal() - pll_sys4x_dqs = Signal() - pll_clk200 = Signal() - self.specials += [ - Instance("PLLE2_BASE", - p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, - - # VCO @ 1600 MHz - p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, - p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, - i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, - - # 100 MHz - p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, - o_CLKOUT0=self.pll_sys, - - # 400 MHz - p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0, - o_CLKOUT1=pll_sys4x, - - # 400 MHz dqs - p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0, - o_CLKOUT2=pll_sys4x_dqs, - - # 200 MHz - p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0, - o_CLKOUT3=pll_clk200 - ), - Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), - Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk), - Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk), - Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), - Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk), - AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), - AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst), - AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst), - ] - - reset_counter = Signal(4, reset=15) - ic_reset = Signal(reset=1) - self.sync.clk200 += \ - If(reset_counter != 0, - reset_counter.eq(reset_counter - 1) - ).Else( - ic_reset.eq(0) - ) - self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) +from targets.utils import dict_set_max +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "ddrphy", - "info", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - clk_freq = int(100e6) dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x10000) - - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - self.submodules.crg = _CRG(platform) - self.crg.cd_sys.clk.attr.add("keep") - self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) - - # Basic peripherals + sys_clk_freq = int(100e6) + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR3 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT41K128M16(sys_clk_freq, "1:4") + self.submodules.ddrphy = s7ddrphy.A7DDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + nphases = 4, + sys_clk_freq = sys_clk_freq) + self.add_csr("ddrphy") + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=ControllerSettings( + with_bandwidth=True, + cmd_buffer_depth=8, + with_refresh=True)) + + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) - - # sdram - self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram")) - sdram_module = MT41K128M16(self.clk_freq, "1:4") - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=ControllerSettings( - with_bandwidth=True, - cmd_buffer_depth=8, - with_refresh=True)) - - # spi flash + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ spiflash_pads = platform.request(spiflash) spiflash_pads.clk = Signal() - self.specials += Instance("STARTUPE2", - i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, - i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) + self.specials += Instance( + "STARTUPE2", + i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, + i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) spiflash_dummy = { "spiflash_1x": 9, "spiflash_4x": 11, } self.submodules.spiflash = spi_flash.SpiFlash( - spiflash_pads, - dummy=spiflash_dummy[spiflash], - div=2) - self.add_constant("SPIFLASH_PAGE_SIZE", 256) - self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) + + spiflash_pads, + dummy=spiflash_dummy[spiflash], + div=2, + endianness=self.cpu.endianness) + self.add_csr("spiflash") + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) self.add_memory_region( - "spiflash", self.mem_map["spiflash"], 16*1024*1024) + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) + + bios_size = 0x8000 + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size + self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + + # Support for soft-emulation for full Linux support ---------------------------------------- + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) SoC = BaseSoC diff --git a/targets/mimas_a7/bridge_net.py b/targets/mimas_a7/bridge_net.py index 05df401c3..1298ed2bf 100755 --- a/targets/mimas_a7/bridge_net.py +++ b/targets/mimas_a7/bridge_net.py @@ -3,7 +3,7 @@ from litex.soc.integration.soc_core import * from litex.soc.cores.uart import * -from targets.utils import csr_map_update, period_ns +from targets.utils import period_ns from liteeth.common import convert_ip from liteeth.phy.s7rgmii import LiteEthPHYRGMII @@ -61,12 +61,6 @@ def __init__(self, platform): class EtherboneSoC(SoCCore): - csr_peripherals = ( - "ethphy", - "ethcore", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - def __init__(self, platform, cpu_type=None, mac_address=0x10e2d5000000, ip_address="192.168.100.50", **kwargs): clk_freq = int(142e6) SoCCore.__init__(self, platform, clk_freq, @@ -84,13 +78,17 @@ def __init__(self, platform, cpu_type=None, mac_address=0x10e2d5000000, ip_addre self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) # ethernet mac/udp/ip stack - self.submodules.ethphy = LiteEthPHYRGMII(self.platform.request("eth_clocks"), - self.platform.request("eth")) - self.submodules.ethcore = LiteEthUDPIPCore(self.ethphy, - mac_address, - convert_ip(ip_address), - self.clk_freq, - with_icmp=True) + self.submodules.ethphy = LiteEthPHYRGMII( + self.platform.request("eth_clocks"), + self.platform.request("eth")) + self.add_csr("ethphy") + self.submodules.ethcore = LiteEthUDPIPCore( + self.ethphy, + mac_address, + convert_ip(ip_address), + self.clk_freq, + with_icmp=True) + self.add_csr("ethcore") # etherbone bridge self.add_cpu_or_bridge(LiteEthEtherbone(self.ethcore.udp, 1234)) diff --git a/targets/mimas_a7/crg.py b/targets/mimas_a7/crg.py new file mode 100755 index 000000000..972249dce --- /dev/null +++ b/targets/mimas_a7/crg.py @@ -0,0 +1,67 @@ +# Support for Numato Mimas A7 board + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) + self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_clk100 = ClockDomain() + + clk100 = platform.request("clk100") + rst = platform.request("cpu_reset") + + pll_locked = Signal() + pll_fb = Signal() + self.pll_sys = Signal() + pll_sys4x = Signal() + pll_sys4x_dqs = Signal() + pll_clk200 = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1600 MHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, + p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 100 MHz + p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, + o_CLKOUT0=self.pll_sys, + + # 400 MHz + p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0, + o_CLKOUT1=pll_sys4x, + + # 400 MHz dqs + p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0, + o_CLKOUT2=pll_sys4x_dqs, + + # 200 MHz + p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0, + o_CLKOUT3=pll_clk200 + ), + Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), + Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk), + Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk), + Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), + Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst), + ] + + reset_counter = Signal(4, reset=15) + ic_reset = Signal(reset=1) + self.sync.clk200 += \ + If(reset_counter != 0, + reset_counter.eq(reset_counter - 1) + ).Else( + ic_reset.eq(0) + ) + self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) diff --git a/targets/mimas_a7/net.py b/targets/mimas_a7/net.py index 9f41b39e9..31d8b5aa7 100755 --- a/targets/mimas_a7/net.py +++ b/targets/mimas_a7/net.py @@ -1,36 +1,42 @@ -from litex.soc.integration.soc_core import mem_decoder from litex.soc.integration.soc_sdram import * from liteeth.core.mac import LiteEthMAC from liteeth.phy.s7rgmii import LiteEthPHYRGMII -from targets.utils import csr_map_update -from targets.mimas_a7.base import SoC as BaseSoC +from .base import BaseSoC class NetSoC(BaseSoC): - csr_peripherals = ( - "ethphy", - "ethmac", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - - mem_map = { - "ethmac": 0xb0000000 - } - mem_map.update(BaseSoC.mem_map) + mem_map = {**BaseSoC.mem_map, **{ + "ethmac": 0xb0000000, + }} def __init__(self, platform, *args, **kwargs): + # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. + if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': + kwargs['integrated_rom_size'] = 0x10000 + BaseSoC.__init__(self, platform, *args, **kwargs) + # Ethernet --------------------------------------------------------------------------------- + # Ethernet PHY self.submodules.ethphy = LiteEthPHYRGMII( platform.request("eth_clocks"), platform.request("eth")) - self.submodules.ethmac = LiteEthMAC( - phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) - self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") + self.add_csr("ethphy") + # Ethernet MAC + ethmac_win_size = 0x2000 + self.submodules.ethmac = LiteEthMAC( + phy = self.ethphy, + dw = 32, + interface = "wishbone", + endianness = self.cpu.endianness) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, ethmac_win_size) + self.add_memory_region("ethmac", self.mem_map["ethmac"], ethmac_win_size, type="io") + self.add_csr("ethmac") + self.add_interrupt("ethmac") + # timing constraints self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") #self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0) @@ -41,8 +47,6 @@ def __init__(self, platform, *args, **kwargs): self.ethphy.crg.cd_eth_rx.clk, self.ethphy.crg.cd_eth_tx.clk) - self.add_interrupt("ethmac") - def configure_iprange(self, iprange): iprange = [int(x) for x in iprange.split(".")] while len(iprange) < 4: diff --git a/targets/mimas_a7/video.py b/targets/mimas_a7/video.py index 6d22dfa93..884b051ec 100755 --- a/targets/mimas_a7/video.py +++ b/targets/mimas_a7/video.py @@ -5,19 +5,11 @@ from litescope import LiteScopeAnalyzer -from targets.utils import csr_map_update, period_ns +from targets.utils import period_ns from targets.mimas_a7.net import NetSoC as BaseSoC class VideoSoC(BaseSoC): - csr_peripherals = ( - "hdmi_out0", - "hdmi_in0", - "hdmi_in0_freq", - "hdmi_in0_edid_mem", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) @@ -39,8 +31,11 @@ def __init__(self, platform, *args, **kwargs): self.sdram.crossbar.get_port(mode="write"), fifo_depth=512, device="xc7") + self.add_csr("hdmi_in0") + self.add_csr("hdmi_in0_edid_mem") self.submodules.hdmi_in0_freq = FreqMeter(period=self.clk_freq) + self.add_csr("hdmi_in0_freq") self.comb += [ self.hdmi_in0_freq.clk.eq(self.hdmi_in0.clocking.cd_pix.clk), @@ -70,6 +65,8 @@ def __init__(self, platform, *args, **kwargs): hdmi_out0_dram_port, mode=mode, fifo_depth=4096) + self.add_csr("hdmi_out0") + self.add_interrupt("hdmi_in0") self.platform.add_false_path_constraints( self.crg.cd_sys.clk, @@ -86,15 +83,8 @@ def __init__(self, platform, *args, **kwargs): for name, value in sorted(self.platform.hdmi_infos.items()): self.add_constant(name, value) - self.add_interrupt("hdmi_in0") - class VideoSoCDebug(VideoSoC): - csr_peripherals = ( - "analyzer", - ) - csr_map_update(VideoSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): VideoSoC.__init__(self, platform, *args, **kwargs) @@ -120,6 +110,7 @@ def __init__(self, platform, *args, **kwargs): self.hdmi_in0.syncpol.vsync, ] self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 1024, cd="hdmi_in0_pix", cd_ratio=2) + self.add_csr("analyzer") # leds pix_counter = Signal(32) From 972bb08a073e4f7e9b6f25def3e46c81bb2d8379 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:54:03 +0100 Subject: [PATCH 079/153] mimasv2: Cleanup and modernize. --- targets/mimasv2/base.py | 262 +++++++++------------------------------ targets/mimasv2/crg.py | 159 ++++++++++++++++++++++++ targets/mimasv2/scope.py | 9 +- 3 files changed, 223 insertions(+), 207 deletions(-) create mode 100644 targets/mimasv2/crg.py diff --git a/targets/mimasv2/base.py b/targets/mimasv2/base.py index 7e4cb98d7..c9ea4e784 100644 --- a/targets/mimasv2/base.py +++ b/targets/mimasv2/base.py @@ -1,11 +1,9 @@ # Support for the MimasV2 import os - from fractions import Fraction from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * @@ -14,179 +12,18 @@ from litedram.phy import s6ddrphy from litedram.core import ControllerSettings -from gateware import info from gateware import cas +from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - # Clock domain for peripherals (such as HDMI output). - self.clock_domains.cd_base50 = ClockDomain() - - self.reset = Signal() - - # Input 100MHz clock - f0 = 100*1000000 - clk100 = platform.request("clk100") - clk100a = Signal() - # Input 100MHz clock (buffered) - self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) - clk100b = Signal() - self.specials += Instance( - "BUFIO2", p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk100a, o_DIVCLK=clk100b) - - p = 8 - f = Fraction(clk_freq*p, f0) - n, d = f.numerator, f.denominator - assert 19e6 <= f0/d <= 500e6 # pfd - assert 400e6 <= f0*n/d <= 1080e6 # vco - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_unused = Signal() - unbuf_sys = Signal() - unbuf_periph = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=d, - # Input Clocks (100MHz) - i_CLKIN1=clk100b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., - # (333MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, - # unused? - o_CLKOUT1=unbuf_unused, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//4, - # (???MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, - # (????Hz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=p//2, - # ( 50MHz) periph - o_CLKOUT4=unbuf_periph, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, - # ( ??MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, - ) - - - # power on reset? - reset = ~platform.request("user_btn", 5) | self.reset - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - # System clock - ??MHz - self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance("BUFPLL", name="sdram_full_bufpll", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb) - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - # sdram_half - self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) - clk_sdram_half_shifted = Signal() - self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) - clk = platform.request("ddram_clock") - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.p) - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted, - o_Q=clk.n) - - # Peripheral clock - 50MHz - # ------------------------------------------------------------------------------ - # The peripheral clock is kept separate from the system clock to allow - # the system clock to be increased in the future. - dcm_base50_locked = Signal() - self.specials += [ - Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", - p_CLKIN_PERIOD=10.0, - p_CLKFX_MULTIPLY=2, - p_CLKFX_DIVIDE=4, - p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE - p_CLKFXDV_DIVIDE=2, - p_SPREAD_SPECTRUM="NONE", - p_STARTUP_WAIT="FALSE", - - i_CLKIN=clk100a, - o_CLKFX=self.cd_base50.clk, - o_LOCKED=dcm_base50_locked, - i_FREEZEDCM=0, - i_RST=ResetSignal(), - ), - AsyncResetSynchronizer(self.cd_base50, - self.cd_sys.rst | ~dcm_base50_locked) - ] - platform.add_period_constraint(self.cd_base50.clk, 20) +from targets.utils import dict_set_max +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "ddrphy", - "info", - "cas", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_sram_size', 0x4000) @@ -199,25 +36,68 @@ def __init__(self, platform, **kwargs): else: kwargs['uart_baudrate']=115200 - clk_freq = (83 + Fraction(1, 3))*1000*1000 - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - - self.submodules.crg = _CRG(platform, clk_freq) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) - - # Basic peripherals + sys_clk_freq = (83 + Fraction(1, 3))*1000*1000 + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR2 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT46H32M16(self.clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + rd_bitslip = 1, + wr_bitslip = 3, + dqs_ddr_alignment="C1") + self.add_csr("ddrphy") + controller_settings = ControllerSettings( + with_bandwidth=True) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) - self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) - - # spi flash + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, - div=platform.spiflash_clock_div) + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) - self.register_mem("spiflash", self.mem_map["spiflash"], - self.spiflash.bus, size=platform.spiflash_total_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) + self.add_memory_region( + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) bios_size = 0x8000 self.add_constant("ROM_DISABLE", 1) @@ -227,23 +107,5 @@ def __init__(self, platform, **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - # sdram - sdram_module = MT46H32M16(self.clk_freq, "1:2") - self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( - platform.request("ddram"), - sdram_module.memtype, - rd_bitslip=1, - wr_bitslip=3, - dqs_ddr_alignment="C1") - controller_settings = ControllerSettings( - with_bandwidth=True) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings) - self.comb += [ - self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), - self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), - ] SoC = BaseSoC diff --git a/targets/mimasv2/crg.py b/targets/mimasv2/crg.py new file mode 100644 index 000000000..8e7a5e837 --- /dev/null +++ b/targets/mimasv2/crg.py @@ -0,0 +1,159 @@ +# Support for the MimasV2 + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + # Clock domain for peripherals (such as HDMI output). + self.clock_domains.cd_base50 = ClockDomain() + + self.reset = Signal() + + # Input 100MHz clock + f0 = 100*1000000 + clk100 = platform.request("clk100") + clk100a = Signal() + # Input 100MHz clock (buffered) + self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) + clk100b = Signal() + self.specials += Instance( + "BUFIO2", p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk100a, o_DIVCLK=clk100b) + + p = 8 + f = Fraction(clk_freq*p, f0) + n, d = f.numerator, f.denominator + assert 19e6 <= f0/d <= 500e6 # pfd + assert 400e6 <= f0*n/d <= 1080e6 # vco + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_unused = Signal() + unbuf_sys = Signal() + unbuf_periph = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=d, + # Input Clocks (100MHz) + i_CLKIN1=clk100b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., + # (333MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, + # unused? + o_CLKOUT1=unbuf_unused, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//4, + # (???MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, + # (????Hz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=p//2, + # ( 50MHz) periph + o_CLKOUT4=unbuf_periph, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, + # ( ??MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, + ) + + + # power on reset? + reset = ~platform.request("user_btn", 5) | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - ??MHz + self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) + clk = platform.request("ddram_clock") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.p) + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted, + o_Q=clk.n) + + # Peripheral clock - 50MHz + # ------------------------------------------------------------------------------ + # The peripheral clock is kept separate from the system clock to allow + # the system clock to be increased in the future. + dcm_base50_locked = Signal() + self.specials += [ + Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", + p_CLKIN_PERIOD=10.0, + p_CLKFX_MULTIPLY=2, + p_CLKFX_DIVIDE=4, + p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE + p_CLKFXDV_DIVIDE=2, + p_SPREAD_SPECTRUM="NONE", + p_STARTUP_WAIT="FALSE", + + i_CLKIN=clk100a, + o_CLKFX=self.cd_base50.clk, + o_LOCKED=dcm_base50_locked, + i_FREEZEDCM=0, + i_RST=ResetSignal(), + ), + AsyncResetSynchronizer(self.cd_base50, + self.cd_sys.rst | ~dcm_base50_locked) + ] + platform.add_period_constraint(self.cd_base50.clk, 20) diff --git a/targets/mimasv2/scope.py b/targets/mimasv2/scope.py index 791362baf..e914ed591 100644 --- a/targets/mimasv2/scope.py +++ b/targets/mimasv2/scope.py @@ -8,17 +8,10 @@ from gateware.memtest import LiteDRAMBISTCheckerScope -from targets.utils import csr_map_update from targets.mimasv2.base import BaseSoC class MemTestSoC(BaseSoC): - csr_peripherals = ( - "analyzer", - "io", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): kwargs['cpu_type'] = None BaseSoC.__init__(self, platform, *args, with_uart=False, **kwargs) @@ -34,6 +27,7 @@ def __init__(self, platform, *args, **kwargs): self.comb += platform.request("user_led", i).eq(self.io.output[i]) except: pass + self.add_csr("io") analyzer_signals = [ self.spiflash.bus, @@ -44,6 +38,7 @@ def __init__(self, platform, *args, **kwargs): # self.spiflash.sr, ] self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, 1024) + self.add_csr("analyzer") def do_exit(self, vns, filename="test/analyzer.csv"): self.analyzer.export_csv(vns, filename) From 1fd7bcd68da826c092af0fe5cef0a3a0267e5f75 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:54:27 +0100 Subject: [PATCH 080/153] minispartan6: Cleanup and modernize. --- targets/minispartan6/base.py | 146 ++++++++++++++--------------------- targets/minispartan6/crg.py | 57 ++++++++++++++ 2 files changed, 115 insertions(+), 88 deletions(-) create mode 100755 targets/minispartan6/crg.py diff --git a/targets/minispartan6/base.py b/targets/minispartan6/base.py index 86ea06a7e..062c446be 100755 --- a/targets/minispartan6/base.py +++ b/targets/minispartan6/base.py @@ -1,9 +1,5 @@ # Support for the MiniSpartan6+ - https://www.scarabhardware.com/minispartan6/ -from fractions import Fraction - from migen import * -from migen.genlib.io import CRG -from migen.genlib.resetsync import AsyncResetSynchronizer from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * @@ -12,76 +8,18 @@ from litedram.phy import gensdrphy from litedram.core import ControllerSettings -from gateware import info from gateware import cas +from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys_ps = ClockDomain() - - f0 = 32*1000000 - clk32 = platform.request("clk32") - clk32a = Signal() - self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a) - clk32b = Signal() - self.specials += Instance("BUFIO2", p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk32a, o_DIVCLK=clk32b) - f = Fraction(int(clk_freq), int(f0)) - n, m, p = f.denominator, f.numerator, 8 - assert f0/n*m == clk_freq - pll_lckd = Signal() - pll_fb = Signal() - pll = Signal(6) - self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6", - p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT", - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., - i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1, - p_CLKIN1_PERIOD=1000000000/f0, p_CLKIN2_PERIOD=0., - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5, - o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5, - o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5, - o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5, - o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5, - o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//1, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//1, - p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p//1, - p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p//1, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, # sys - p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p//1, # sys_ps - ) - self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk) - self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd) - - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, - i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk, - o_Q=platform.request("sdram_clock")) +from targets.utils import dict_set_max +from .crg import _CRG + class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "cas", - "ddrphy", - "info", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_sram_size', 0x4000) @@ -89,35 +27,67 @@ def __init__(self, platform, **kwargs): # disable ROM, it'll be added later kwargs['integrated_rom_size'] = 0x0 - clk_freq = 80*1000000 - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) + kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size - self.submodules.crg = _CRG(platform, clk_freq) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) + sys_clk_freq = 80*1000000 + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, sys_clk_freq, **kwargs) - # Basic peripherals + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + # DDR2 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = AS4C16M16(sys_clk_freq, "1:1") + self.submodules.ddrphy = gensdrphy.GENSDRPHY( + platform.request("sdram")) + self.add_csr("ddrphy") + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings) + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) - self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) - - + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ self.submodules.spiflash = spi_flash.SpiFlash( platform.request("spiflash2x"), dummy=platform.spiflash_read_dummy_bits, - div=platform.spiflash_clock_div) + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) - self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) + self.add_memory_region( + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) + + bios_size = 0x8000 + self.add_constant("ROM_DISABLE", 1) + self.add_memory_region( + "rom", kwargs['cpu_reset_address'], bios_size, + type="cached+linker") + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - self.register_mem("spiflash", self.mem_map["spiflash"], - self.spiflash.bus, size=platform.spiflash_total_size) - - # sdram - sdram_module = AS4C16M16(self.clk_freq, "1:1") - self.submodules.ddrphy = gensdrphy.GENSDRPHY(platform.request("sdram")) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings) + SoC = BaseSoC diff --git a/targets/minispartan6/crg.py b/targets/minispartan6/crg.py new file mode 100755 index 000000000..36094dbab --- /dev/null +++ b/targets/minispartan6/crg.py @@ -0,0 +1,57 @@ +# Support for the MiniSpartan6+ - https://www.scarabhardware.com/minispartan6/ + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys_ps = ClockDomain() + + f0 = 32*1000000 + clk32 = platform.request("clk32") + clk32a = Signal() + self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a) + clk32b = Signal() + self.specials += Instance("BUFIO2", p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk32a, o_DIVCLK=clk32b) + f = Fraction(int(clk_freq), int(f0)) + n, m, p = f.denominator, f.numerator, 8 + assert f0/n*m == clk_freq + pll_lckd = Signal() + pll_fb = Signal() + pll = Signal(6) + self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6", + p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT", + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., + i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1, + p_CLKIN1_PERIOD=1000000000/f0, p_CLKIN2_PERIOD=0., + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5, + o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5, + o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5, + o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5, + o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5, + o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//1, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//1, + p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p//1, + p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p//1, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, # sys + p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p//1, # sys_ps + ) + self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk) + self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd) + + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, + i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk, + o_Q=platform.request("sdram_clock")) From fc321e9b91e9c1856fa4aa2dfb36698c4a0ba7c3 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:55:11 +0100 Subject: [PATCH 081/153] nexys_video: Cleanup and modernize. --- targets/nexys_video/base.py | 199 +++++++++++++++-------------------- targets/nexys_video/crg.py | 67 ++++++++++++ targets/nexys_video/net.py | 26 +++-- targets/nexys_video/video.py | 22 ++-- 4 files changed, 170 insertions(+), 144 deletions(-) create mode 100755 targets/nexys_video/crg.py diff --git a/targets/nexys_video/base.py b/targets/nexys_video/base.py index 8e4a06fc8..7b85defa3 100755 --- a/targets/nexys_video/base.py +++ b/targets/nexys_video/base.py @@ -1,160 +1,131 @@ # Support for Digilent Nexys Video board from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from litex.soc.integration.soc_core import mem_decoder +from litex.soc.cores.uart import * #UART, RS232PHYInterface, RS232PHY, RS232PHYMultiplexer +from litex.soc.interconnect.wishbonebridge import WishboneStreamingBridge from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * -from litex.soc.cores.uart import * from litedram.modules import MT41K256M16 -from litedram.phy import a7ddrphy +from litedram.phy import s7ddrphy from litedram.core import ControllerSettings +from gateware import cas from gateware import info from gateware import oled from gateware import spi_flash -from targets.utils import csr_map_update, period_ns, dict_set_max - - -class _CRG(Module): - def __init__(self, platform): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) - self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() - self.clock_domains.cd_clk100 = ClockDomain() - - clk100 = platform.request("clk100") - rst = ~platform.request("cpu_reset") - - pll_locked = Signal() - pll_fb = Signal() - self.pll_sys = Signal() - pll_sys4x = Signal() - pll_sys4x_dqs = Signal() - pll_clk200 = Signal() - self.specials += [ - Instance("PLLE2_BASE", - p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, - - # VCO @ 1600 MHz - p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, - p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, - i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, - - # 100 MHz - p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, - o_CLKOUT0=self.pll_sys, - - # 400 MHz - p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0, - o_CLKOUT1=pll_sys4x, - - # 400 MHz dqs - p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0, - o_CLKOUT2=pll_sys4x_dqs, - - # 200 MHz - p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0, - o_CLKOUT3=pll_clk200 - ), - Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), - Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk), - Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk), - Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), - Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk), - AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), - AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst), - AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst), - ] - - reset_counter = Signal(4, reset=15) - ic_reset = Signal(reset=1) - self.sync.clk200 += \ - If(reset_counter != 0, - reset_counter.eq(reset_counter - 1) - ).Else( - ic_reset.eq(0) - ) - self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) +from targets.utils import dict_set_max +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "ddrphy", - "info", - "oled", - "uart", - "uart_phy", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} + + # "oled", + # "uart", + # "uart_phy", def __init__(self, platform, spiflash="spiflash_1x", **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = int(100e6) - SoCSDRAM.__init__(self, platform, clk_freq, with_uart=False, **kwargs) + sys_clk_freq = int(100e6) - self.submodules.crg = _CRG(platform) - self.crg.cd_sys.clk.attr.add("keep") - self.platform.add_period_constraint(self.crg.cd_sys.clk, period_ns(clk_freq)) + # disable uart + kwargs['with_uart'] = False + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.crg.cd_sys.clk.attr.add("keep") + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR3 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT41K256M16(sys_clk_freq, "1:4") + self.submodules.ddrphy = s7ddrphy.A7DDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + nphases = 4, + sys_clk_freq = sys_clk_freq) + self.add_csr("ddrphy") + self.add_constant("READ_LEVELING_BITSLIP", 3) + self.add_constant("READ_LEVELING_DELAY", 14) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=ControllerSettings( + with_bandwidth=True, + cmd_buffer_depth=8, + with_refresh=True)) + + # Extended UART ---------------------------------------------------------------------------- uart_interfaces = [RS232PHYInterface() for i in range(2)] self.submodules.uart = UART(uart_interfaces[0]) - self.submodules.bridge = WishboneStreamingBridge(uart_interfaces[1], self.clk_freq) + self.submodules.bridge = WishboneStreamingBridge(uart_interfaces[1], sys_clk_freq) self.add_wb_master(self.bridge.wishbone) + self.add_csr("uart") + self.add_interrupt("uart") self.submodules.uart_phy = RS232PHY(platform.request("serial"), self.clk_freq, 115200) self.submodules.uart_multiplexer = RS232PHYMultiplexer(uart_interfaces, self.uart_phy) self.comb += self.uart_multiplexer.sel.eq(platform.request("user_sw", 0)) + self.add_csr("uart_phy") - # Basic peripherals + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") self.submodules.oled = oled.OLED(platform.request("oled")) + self.add_csr("oled") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) - # sdram - self.submodules.ddrphy = a7ddrphy.A7DDRPHY(platform.request("ddram")) - self.add_constant("READ_LEVELING_BITSLIP", 3) - self.add_constant("READ_LEVELING_DELAY", 14) - sdram_module = MT41K256M16(self.clk_freq, "1:4") - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=ControllerSettings( - with_bandwidth=True, - cmd_buffer_depth=8, - with_refresh=True)) - - # spi flash + # Memory mapped SPI Flash ------------------------------------------------------------------ spiflash_pads = platform.request(spiflash) spiflash_pads.clk = Signal() - self.specials += Instance("STARTUPE2", - i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, - i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) + self.specials += Instance( + "STARTUPE2", + i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0, + i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1) spiflash_dummy = { "spiflash_1x": 9, "spiflash_4x": 11, } self.submodules.spiflash = spi_flash.SpiFlash( - spiflash_pads, - dummy=spiflash_dummy[spiflash], - div=2) - self.add_constant("SPIFLASH_PAGE_SIZE", 256) - self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) - self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) + spiflash_pads, + dummy=spiflash_dummy[spiflash], + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) self.add_memory_region( - "spiflash", self.mem_map["spiflash"], 16*1024*1024) + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) - self.add_interrupt("uart") + bios_size = 0x8000 + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size + self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) SoC = BaseSoC diff --git a/targets/nexys_video/crg.py b/targets/nexys_video/crg.py new file mode 100755 index 000000000..ca9175abc --- /dev/null +++ b/targets/nexys_video/crg.py @@ -0,0 +1,67 @@ +# Support for Digilent Nexys Video board + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) + self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True) + self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_clk100 = ClockDomain() + + clk100 = platform.request("clk100") + rst = ~platform.request("cpu_reset") + + pll_locked = Signal() + pll_fb = Signal() + self.pll_sys = Signal() + pll_sys4x = Signal() + pll_sys4x_dqs = Signal() + pll_clk200 = Signal() + self.specials += [ + Instance("PLLE2_BASE", + p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked, + + # VCO @ 1600 MHz + p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=10.0, + p_CLKFBOUT_MULT=16, p_DIVCLK_DIVIDE=1, + i_CLKIN1=clk100, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, + + # 100 MHz + p_CLKOUT0_DIVIDE=16, p_CLKOUT0_PHASE=0.0, + o_CLKOUT0=self.pll_sys, + + # 400 MHz + p_CLKOUT1_DIVIDE=4, p_CLKOUT1_PHASE=0.0, + o_CLKOUT1=pll_sys4x, + + # 400 MHz dqs + p_CLKOUT2_DIVIDE=4, p_CLKOUT2_PHASE=90.0, + o_CLKOUT2=pll_sys4x_dqs, + + # 200 MHz + p_CLKOUT3_DIVIDE=8, p_CLKOUT3_PHASE=0.0, + o_CLKOUT3=pll_clk200 + ), + Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk), + Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk), + Instance("BUFG", i_I=pll_sys4x_dqs, o_O=self.cd_sys4x_dqs.clk), + Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk), + Instance("BUFG", i_I=clk100, o_O=self.cd_clk100.clk), + AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst), + AsyncResetSynchronizer(self.cd_clk100, ~pll_locked | rst), + ] + + reset_counter = Signal(4, reset=15) + ic_reset = Signal(reset=1) + self.sync.clk200 += \ + If(reset_counter != 0, + reset_counter.eq(reset_counter - 1) + ).Else( + ic_reset.eq(0) + ) + self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset) diff --git a/targets/nexys_video/net.py b/targets/nexys_video/net.py index 440dd02d3..7484dd2b4 100755 --- a/targets/nexys_video/net.py +++ b/targets/nexys_video/net.py @@ -4,21 +4,14 @@ from liteeth.core.mac import LiteEthMAC from liteeth.phy.s7rgmii import LiteEthPHYRGMII -from targets.utils import csr_map_update from targets.nexys_video.base import SoC as BaseSoC class NetSoC(BaseSoC): - csr_peripherals = ( - "ethphy", - "ethmac", + mem_map = dict( + **BaseSoC.mem_map, + ethmac=0xb0000000, ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - - mem_map = { - "ethmac": 0xb0000000 - } - mem_map.update(BaseSoC.mem_map) def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. @@ -27,13 +20,20 @@ def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) + # Ethernet PHY self.submodules.ethphy = LiteEthPHYRGMII( platform.request("eth_clocks"), platform.request("eth")) + self.add_csr("ethphy") + + # Ethernet MAC + ethmac_win_size = 0x2000 self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) - self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, ethmac_win_size) + self.add_memory_region("ethmac", self.mem_map["ethmac"], ethmac_win_size, type="io") + self.add_csr("ethmac") + self.add_interrupt("ethmac") self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") @@ -45,8 +45,6 @@ def __init__(self, platform, *args, **kwargs): self.ethphy.crg.cd_eth_rx.clk, self.ethphy.crg.cd_eth_tx.clk) - self.add_interrupt("ethmac") - def configure_iprange(self, iprange): iprange = [int(x) for x in iprange.split(".")] while len(iprange) < 4: diff --git a/targets/nexys_video/video.py b/targets/nexys_video/video.py index 38665cbdf..ab65e2a2e 100755 --- a/targets/nexys_video/video.py +++ b/targets/nexys_video/video.py @@ -5,19 +5,11 @@ from litescope import LiteScopeAnalyzer -from targets.utils import csr_map_update, period_ns +from targets.utils import period_ns from targets.nexys_video.net import NetSoC as BaseSoC class VideoSoC(BaseSoC): - csr_peripherals = ( - "hdmi_out0", - "hdmi_in0", - "hdmi_in0_freq", - "hdmi_in0_edid_mem", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) @@ -40,8 +32,12 @@ def __init__(self, platform, *args, **kwargs): fifo_depth=512, device="xc7", ) + self.add_csr("hdmi_in0") + self.add_csr("hdmi_in0_edid_mem") + self.add_interrupt("hdmi_in0") self.submodules.hdmi_in0_freq = FreqMeter(period=self.clk_freq) + self.add_csr("hdmi_in0_freq") self.comb += [ self.hdmi_in0_freq.clk.eq(self.hdmi_in0.clocking.cd_pix.clk), @@ -74,6 +70,7 @@ def __init__(self, platform, *args, **kwargs): mode=mode, fifo_depth=4096, ) + self.add_csr("hdmi_out0") self.platform.add_false_path_constraints( self.crg.cd_sys.clk, @@ -90,15 +87,8 @@ def __init__(self, platform, *args, **kwargs): for name, value in sorted(self.platform.hdmi_infos.items()): self.add_constant(name, value) - self.add_interrupt("hdmi_in0") - class VideoSoCDebug(VideoSoC): - csr_peripherals = ( - "analyzer", - ) - csr_map_update(VideoSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): VideoSoC.__init__(self, platform, *args, **kwargs) From 831d5e06519807976b774f8d6b0d15b2d4e679d2 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:55:41 +0100 Subject: [PATCH 082/153] opsis: Cleanup and modernize. --- targets/opsis/axiom.py | 7 +- targets/opsis/base.py | 313 +++++++++++--------------------------- targets/opsis/crg.py | 168 ++++++++++++++++++++ targets/opsis/encoder.py | 15 +- targets/opsis/hdmi2usb.py | 15 +- targets/opsis/net.py | 38 ++--- targets/opsis/video.py | 29 ++-- 7 files changed, 297 insertions(+), 288 deletions(-) create mode 100644 targets/opsis/crg.py diff --git a/targets/opsis/axiom.py b/targets/opsis/axiom.py index db3ab5121..d0c7477c0 100644 --- a/targets/opsis/axiom.py +++ b/targets/opsis/axiom.py @@ -1,7 +1,6 @@ from migen import * from litex.soc.cores.gpio import GPIOIn, GPIOOut -from targets.utils import csr_map_update from targets.opsis.net import NetSoC as BaseSoC @@ -22,15 +21,11 @@ def get_csrs(self): class AxiomSoC(BaseSoC): - csr_peripherals = ( - "gpio", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, expansion='tofe2axiom', **kwargs) self.submodules.gpio = GPIO2TOFE(platform.request("tofe", 0)) + self.add_csr("gpio") SoC = AxiomSoC diff --git a/targets/opsis/base.py b/targets/opsis/base.py index 386748aaa..6db5dd7a1 100644 --- a/targets/opsis/base.py +++ b/targets/opsis/base.py @@ -1,8 +1,6 @@ # Support for Numato Opsis - https://opsis.hdmi2usb.tv -from fractions import Fraction from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer from migen.genlib.misc import WaitTimer from litex.soc.integration.soc_sdram import * @@ -15,6 +13,7 @@ from litedram.phy import s6ddrphy from litedram.core import ControllerSettings +#from gateware import cas from gateware import i2c from gateware import info from gateware import opsis_i2c @@ -22,7 +21,9 @@ from gateware import tofe from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max +from .crg import _CRG + +from targets.utils import dict_set_max class FrontPanelGPIO(Module, AutoCSR): @@ -50,192 +51,17 @@ def __init__(self, platform, clk_freq): ] -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sys2x = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - # Clock domain for peripherals (such as HDMI output). - self.clock_domains.cd_base50 = ClockDomain() - self.clock_domains.cd_encoder = ClockDomain() - - self.reset = Signal() - - # Input 100MHz clock - f0 = 100*1000000 - clk100 = platform.request("clk100") - clk100a = Signal() - # Input 100MHz clock (buffered) - self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) - clk100b = Signal() - self.specials += Instance( - "BUFIO2", p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk100a, o_DIVCLK=clk100b) - - f = Fraction(int(clk_freq), int(f0)) - n, m = f.denominator, f.numerator - assert f0/n*m == clk_freq - p = 8 - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_encoder = Signal() - unbuf_sys = Signal() - unbuf_sys2x = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=1, - # Input Clocks (100MHz) - i_CLKIN1=clk100b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., - # (400MHz) ddr3 wr/rd full clock - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//8, - # ( 66MHz) encoder - o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=6, - # (200MHz) sdram_half - ddr3 dqs adr ctrl off-chip - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=230., p_CLKOUT2_DIVIDE=p//4, - # (200MHz) off-chip ddr - ddr3 half clock - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=210., p_CLKOUT3_DIVIDE=p//4, - # (100MHz) sys2x - 2x system clock - o_CLKOUT4=unbuf_sys2x, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//2, - # ( 50MHz) periph / sys - system clock - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, - ) - - - # power on reset? - reset = ~platform.request("cpu_reset") | self.reset - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - # System clock - 50MHz - self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - # sys2x - self.specials += Instance("BUFG", name="sys2x_bufg", i_I=unbuf_sys2x, o_O=self.cd_sys2x.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys2x, ~pll_lckd | (por > 0)) - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk8x_wr_strb = Signal() - self.clk8x_rd_strb = Signal() - - # sdram_full - self.specials += Instance("BUFPLL", name="sdram_full_bufpll", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys2x.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk8x_wr_strb) - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk8x_rd_strb.eq(self.clk8x_wr_strb), - ] - # sdram_half - self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) - clk_sdram_half_shifted = Signal() - self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) - - output_clk = Signal() - clk = platform.request("ddram_clock") - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=output_clk) - self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) - - # Peripheral clock - 50MHz - # ------------------------------------------------------------------------------ - # The peripheral clock is kept separate from the system clock to allow - # the system clock to be increased in the future. - dcm_base50_locked = Signal() - self.specials += [ - Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", - p_CLKIN_PERIOD=10.0, - p_CLKFX_MULTIPLY=2, - p_CLKFX_DIVIDE=4, - p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE - p_CLKFXDV_DIVIDE=2, - p_SPREAD_SPECTRUM="NONE", - p_STARTUP_WAIT="FALSE", - - i_CLKIN=clk100a, - o_CLKFX=self.cd_base50.clk, - o_LOCKED=dcm_base50_locked, - i_FREEZEDCM=0, - i_RST=ResetSignal(), - ), - AsyncResetSynchronizer(self.cd_base50, - self.cd_sys.rst | ~dcm_base50_locked) - ] - platform.add_period_constraint(self.cd_base50.clk, 20) - - # Encoder clock - 66 MHz - # ------------------------------------------------------------------------------ - self.specials += Instance("BUFG", name="encoder_bufg", i_I=unbuf_encoder, o_O=self.cd_encoder.clk) - self.specials += AsyncResetSynchronizer(self.cd_encoder, self.cd_sys.rst) - - class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "front_panel", - "ddrphy", - "info", - "fx2_reset", - "fx2_hack", - "tofe", - "opsis_i2c", - "uart", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - "emulator_ram": 0x50000000, # (default shadow @0xd0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + "emulator_ram": 0x50000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = 50*1000000 + sys_clk_freq = 50*1000000 if 'expansion' in kwargs: tofe_board_name = kwargs.get('expansion') @@ -243,65 +69,102 @@ def __init__(self, platform, **kwargs): else: tofe_board_name = None - SoCSDRAM.__init__(self, platform, clk_freq, with_uart=False, **kwargs) - - self.submodules.crg = _CRG(platform, clk_freq) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) + # disable uart + kwargs['with_uart'] = False - self.submodules.info = info.Info(platform, self.__class__.__name__) + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) - self.submodules.opsis_i2c = opsis_i2c.OpsisI2C(platform) + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + # Add specialized uart --------------------------------------------------------------------- self.submodules.suart = shared_uart.SharedUART(self.clk_freq, 115200) self.suart.add_uart_pads(platform.request('fx2_serial')) self.submodules.uart = self.suart.uart + self.add_csr("uart") + self.add_interrupt("uart") + + # DDR3 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT41J128M16(sys_clk_freq, "1:4") + self.submodules.ddrphy = s6ddrphy.S6QuarterRateDDRPHY( + platform.request("ddram"), + rd_bitslip = 0, + wr_bitslip = 4, + dqs_ddr_alignment="C0") + self.add_csr("ddrphy") + controller_settings = ControllerSettings( + with_bandwidth=True) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk8x_wr_strb.eq(self.crg.clk8x_wr_strb), + self.ddrphy.clk8x_rd_strb.eq(self.crg.clk8x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ + # info module + self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + # control and status module + #self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + # opsis specific i2c module + self.submodules.opsis_i2c = opsis_i2c.OpsisI2C(platform) + self.add_csr("opsis_i2c") + # front panel (ATX) module + self.submodules.front_panel = FrontPanelGPIO(platform, sys_clk_freq) + self.comb += self.crg.reset.eq(self.front_panel.reset) + self.add_csr("front_panel") + + # Expansion boards ------------------------------------------------------------------------- + if tofe_board_name: + if tofe_board_name == 'lowspeedio': + self.submodules.tofe = tofe.TOFEBoard(tofe_board_name)(platform, self.suart) + else: + self.submodules.tofe = tofe.TOFEBoard(tofe_board_name)(platform) + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ self.submodules.spiflash = spi_flash.SpiFlash( platform.request("spiflash4x"), dummy=platform.spiflash_read_dummy_bits, - div=platform.spiflash_clock_div) + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) - self.register_mem("spiflash", self.mem_map["spiflash"], - self.spiflash.bus, size=platform.spiflash_total_size) - - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) + self.add_memory_region( + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - # front panel (ATX) - self.submodules.front_panel = FrontPanelGPIO(platform, clk_freq) - self.comb += self.crg.reset.eq(self.front_panel.reset) - - # sdram - sdram_module = MT41J128M16(self.clk_freq, "1:4") - self.submodules.ddrphy = s6ddrphy.S6QuarterRateDDRPHY( - platform.request("ddram"), - rd_bitslip=0, - wr_bitslip=4, - dqs_ddr_alignment="C0") - controller_settings = ControllerSettings(with_bandwidth=True) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings) - self.comb += [ - self.ddrphy.clk8x_wr_strb.eq(self.crg.clk8x_wr_strb), - self.ddrphy.clk8x_rd_strb.eq(self.crg.clk8x_rd_strb), - ] - - if tofe_board_name: - if tofe_board_name == 'lowspeedio': - self.submodules.tofe = tofe.TOFEBoard(tofe_board_name)(platform, self.suart) - else: - self.submodules.tofe = tofe.TOFEBoard(tofe_board_name)(platform) - - self.add_interrupt("uart") + # Support for soft-emulation for full Linux support ---------------------------------------- + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) SoC = BaseSoC diff --git a/targets/opsis/crg.py b/targets/opsis/crg.py new file mode 100644 index 000000000..3482a17e6 --- /dev/null +++ b/targets/opsis/crg.py @@ -0,0 +1,168 @@ +# Support for Numato Opsis - https://opsis.hdmi2usb.tv + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer +from migen.genlib.misc import WaitTimer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sys2x = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + # Clock domain for peripherals (such as HDMI output). + self.clock_domains.cd_base50 = ClockDomain() + self.clock_domains.cd_encoder = ClockDomain() + + self.reset = Signal() + + # Input 100MHz clock + f0 = 100*1000000 + clk100 = platform.request("clk100") + clk100a = Signal() + # Input 100MHz clock (buffered) + self.specials += Instance("IBUFG", i_I=clk100, o_O=clk100a) + clk100b = Signal() + self.specials += Instance( + "BUFIO2", p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk100a, o_DIVCLK=clk100b) + + f = Fraction(int(clk_freq), int(f0)) + n, m = f.denominator, f.numerator + assert f0/n*m == clk_freq + p = 8 + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_encoder = Signal() + unbuf_sys = Signal() + unbuf_sys2x = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=1, + # Input Clocks (100MHz) + i_CLKIN1=clk100b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0., + # (400MHz) ddr3 wr/rd full clock + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//8, + # ( 66MHz) encoder + o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=6, + # (200MHz) sdram_half - ddr3 dqs adr ctrl off-chip + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=230., p_CLKOUT2_DIVIDE=p//4, + # (200MHz) off-chip ddr - ddr3 half clock + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=210., p_CLKOUT3_DIVIDE=p//4, + # (100MHz) sys2x - 2x system clock + o_CLKOUT4=unbuf_sys2x, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//2, + # ( 50MHz) periph / sys - system clock + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, + ) + + + # power on reset? + reset = ~platform.request("cpu_reset") | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - 50MHz + self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + # sys2x + self.specials += Instance("BUFG", name="sys2x_bufg", i_I=unbuf_sys2x, o_O=self.cd_sys2x.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys2x, ~pll_lckd | (por > 0)) + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk8x_wr_strb = Signal() + self.clk8x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys2x.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk8x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk8x_rd_strb.eq(self.clk8x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) + + output_clk = Signal() + clk = platform.request("ddram_clock") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=output_clk) + self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) + + # Peripheral clock - 50MHz + # ------------------------------------------------------------------------------ + # The peripheral clock is kept separate from the system clock to allow + # the system clock to be increased in the future. + dcm_base50_locked = Signal() + self.specials += [ + Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", + p_CLKIN_PERIOD=10.0, + p_CLKFX_MULTIPLY=2, + p_CLKFX_DIVIDE=4, + p_CLKFX_MD_MAX=0.5, # CLKFX_MULTIPLY/CLKFX_DIVIDE + p_CLKFXDV_DIVIDE=2, + p_SPREAD_SPECTRUM="NONE", + p_STARTUP_WAIT="FALSE", + + i_CLKIN=clk100a, + o_CLKFX=self.cd_base50.clk, + o_LOCKED=dcm_base50_locked, + i_FREEZEDCM=0, + i_RST=ResetSignal(), + ), + AsyncResetSynchronizer(self.cd_base50, + self.cd_sys.rst | ~dcm_base50_locked) + ] + platform.add_period_constraint(self.cd_base50.clk, 20) + + # Encoder clock - 66 MHz + # ------------------------------------------------------------------------------ + self.specials += Instance("BUFG", name="encoder_bufg", i_I=unbuf_encoder, o_O=self.cd_encoder.clk) + self.specials += AsyncResetSynchronizer(self.cd_encoder, self.cd_sys.rst) diff --git a/targets/opsis/encoder.py b/targets/opsis/encoder.py index 641c4f0c9..573b92b6a 100644 --- a/targets/opsis/encoder.py +++ b/targets/opsis/encoder.py @@ -5,26 +5,20 @@ from gateware.encoder import EncoderDMAReader, EncoderBuffer, Encoder from gateware.streamer import USBStreamer -from targets.utils import csr_map_update from targets.opsis.net import SoC as BaseSoC class EncoderSoC(BaseSoC): - csr_peripherals = ( - "encoder_reader", - "encoder", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - mem_map = { - "encoder": 0xd0000000 - } - mem_map.update(BaseSoC.mem_map) + mem_map = {**BaseSoC.mem_map, **{ + "encoder": 0xd0000000, + }} def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) encoder_port = self.sdram.crossbar.get_port() self.submodules.encoder_reader = EncoderDMAReader(encoder_port) + self.add_csr("encoder_reader") encoder_cdc = stream.AsyncFIFO([("data", 128)], 4) encoder_cdc = ClockDomainsRenamer({"write": "sys", "read": "encoder"})(encoder_cdc) @@ -32,6 +26,7 @@ def __init__(self, platform, *args, **kwargs): encoder = Encoder(platform) encoder_streamer = USBStreamer(platform, platform.request("fx2")) self.submodules += encoder_cdc, encoder_buffer, encoder, encoder_streamer + self.add_csr("encoder") self.comb += [ self.encoder_reader.source.connect(encoder_cdc.sink), diff --git a/targets/opsis/hdmi2usb.py b/targets/opsis/hdmi2usb.py index c7376c88f..1ffe48f50 100644 --- a/targets/opsis/hdmi2usb.py +++ b/targets/opsis/hdmi2usb.py @@ -5,26 +5,20 @@ from gateware.encoder import EncoderDMAReader, EncoderBuffer, Encoder from gateware.streamer import USBStreamer -from targets.utils import csr_map_update from targets.opsis.video import SoC as BaseSoC class HDMI2USBSoC(BaseSoC): - csr_peripherals = ( - "encoder_reader", - "encoder", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - mem_map = { - "encoder": 0xd0000000 - } - mem_map.update(BaseSoC.mem_map) + mem_map = {**BaseSoC.mem_map, **{ + "encoder": 0xd0000000, + }} def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) encoder_port = self.sdram.crossbar.get_port() self.submodules.encoder_reader = EncoderDMAReader(encoder_port) + self.add_csr("encoder_reader") encoder_cdc = stream.AsyncFIFO([("data", 128)], 4) encoder_cdc = ClockDomainsRenamer({"write": "sys", "read": "encoder"})(encoder_cdc) @@ -32,6 +26,7 @@ def __init__(self, platform, *args, **kwargs): encoder = Encoder(platform) encoder_streamer = USBStreamer(platform, platform.request("fx2")) self.submodules += encoder_cdc, encoder_buffer, encoder, encoder_streamer + self.add_csr("encoder") self.comb += [ self.encoder_reader.source.connect(encoder_cdc.sink), diff --git a/targets/opsis/net.py b/targets/opsis/net.py index 759746f86..7c829a2d7 100644 --- a/targets/opsis/net.py +++ b/targets/opsis/net.py @@ -1,25 +1,16 @@ -from litex.soc.integration.soc_core import mem_decoder from litex.soc.integration.soc_sdram import * from liteeth.core.mac import LiteEthMAC from gateware.s6rgmii import LiteEthPHYRGMII -from targets.utils import csr_map_update -from targets.opsis.base import SoC as BaseSoC +from .base import BaseSoC class NetSoC(BaseSoC): - csr_peripherals = ( - "ethphy", - "ethmac", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - - mem_map = { - "ethmac": 0xb0000000 - } - mem_map.update(BaseSoC.mem_map) + mem_map = {**BaseSoC.mem_map, **{ + "ethmac": 0xb0000000, + }} def __init__(self, platform, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. @@ -28,15 +19,25 @@ def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) + # Ethernet --------------------------------------------------------------------------------- + # Ethernet PHY self.submodules.ethphy = LiteEthPHYRGMII( platform.request("eth_clocks"), platform.request("eth")) - self.platform.add_source("gateware/rgmii_if.vhd") - self.submodules.ethmac = LiteEthMAC( - phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) - self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) - self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") + self.add_csr("ethphy") + # Ethernet MAC + ethmac_win_size = 0x2000 + self.submodules.ethmac = LiteEthMAC( + phy = self.ethphy, + dw = 32, + interface = "wishbone", + endianness = self.cpu.endianness) + self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus, ethmac_win_size) + self.add_memory_region("ethmac", self.mem_map["ethmac"], ethmac_win_size, type="io") + self.add_csr("ethmac") + self.add_interrupt("ethmac") + # timing constraints self.ethphy.crg.cd_eth_rx.clk.attr.add("keep") self.ethphy.crg.cd_eth_tx.clk.attr.add("keep") #self.platform.add_period_constraint(self.crg.cd_sys.clk, 10.0) @@ -47,7 +48,6 @@ def __init__(self, platform, *args, **kwargs): self.ethphy.crg.cd_eth_rx.clk) # self.ethphy.crg.cd_eth_tx.clk) - self.add_interrupt("ethmac") def configure_iprange(self, iprange): iprange = [int(x) for x in iprange.split(".")] diff --git a/targets/opsis/video.py b/targets/opsis/video.py index 7f7268934..3e00d0e10 100644 --- a/targets/opsis/video.py +++ b/targets/opsis/video.py @@ -4,23 +4,11 @@ from gateware import freq_measurement from gateware import i2c -from targets.utils import csr_map_update, period_ns +from targets.utils import period_ns from targets.opsis.net import NetSoC as BaseSoC class VideoSoC(BaseSoC): - csr_peripherals = ( - "hdmi_out0", - "hdmi_out1", - "hdmi_in0", - "hdmi_in0_freq", - "hdmi_in0_edid_mem", - "hdmi_in1", - "hdmi_in1_freq", - "hdmi_in1_edid_mem", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) @@ -40,9 +28,13 @@ def __init__(self, platform, *args, **kwargs): self.sdram.crossbar.get_port(mode="write"), fifo_depth=512, ) + self.add_csr("hdmi_in0") + self.add_csr("hdmi_in0_edid_mem") + self.add_interrupt("hdmi_in0") self.submodules.hdmi_in0_freq = freq_measurement.FrequencyMeasurement( self.hdmi_in0.clocking.clk_input, measure_period=self.clk_freq) + self.add_csr("hdmi_in0_freq") # hdmi in 1 hdmi_in1_pads = platform.request("hdmi_in", 1) @@ -52,11 +44,13 @@ def __init__(self, platform, *args, **kwargs): self.sdram.crossbar.get_port(mode="write"), fifo_depth=512, ) + self.add_csr("hdmi_in1") + self.add_csr("hdmi_in1_edid_mem") + self.add_interrupt("hdmi_in1") self.submodules.hdmi_in1_freq = freq_measurement.FrequencyMeasurement( self.hdmi_in1.clocking.clk_input, measure_period=self.clk_freq) - - + self.add_csr("hdmi_in1_freq") # hdmi out 0 hdmi_out0_pads = platform.request("hdmi_out", 0) @@ -75,6 +69,7 @@ def __init__(self, platform, *args, **kwargs): mode=mode, fifo_depth=4096, ) + self.add_csr("hdmi_out0") self.hdmi_out0.submodules.i2c = i2c.I2C(hdmi_out0_pads) @@ -96,6 +91,7 @@ def __init__(self, platform, *args, **kwargs): fifo_depth=4096, external_clocking=self.hdmi_out0.driver.clocking, ) + self.add_csr("hdmi_out1") self.hdmi_out1.submodules.i2c = i2c.I2C(hdmi_out1_pads) @@ -123,8 +119,5 @@ def __init__(self, platform, *args, **kwargs): for name, value in sorted(self.platform.hdmi_infos.items()): self.add_constant(name, value) - self.add_interrupt("hdmi_in0") - self.add_interrupt("hdmi_in1") - SoC = VideoSoC From 3b5e784492acd230c5a6a407e749dc4d3b58a97b Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:56:58 +0100 Subject: [PATCH 083/153] pano_logic_g2: Cleanup and modernize. --- targets/pano_logic_g2/base.py | 214 +++++++++------------------------- targets/pano_logic_g2/crg.py | 119 +++++++++++++++++++ 2 files changed, 176 insertions(+), 157 deletions(-) create mode 100755 targets/pano_logic_g2/crg.py diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index b253ffc88..41895bb78 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -1,189 +1,89 @@ # Support for the Pano Logic Zero Client G2 from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from litex.soc.interconnect import wishbone from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * +from litex.soc.interconnect import wishbone from litedram.modules import MT47H32M16 from litedram.phy import s6ddrphy from litedram.core import ControllerSettings -from gateware import info from gateware import cas +from gateware import info +from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - - self.reset = Signal() - - f0 = int(125e6) - - clk125 = platform.request(platform.default_clk_name) - clk125a = Signal() - - self.specials += Instance("IBUFG", i_I=clk125, o_O=clk125a) - - clk125b = Signal() - - self.specials += Instance( - "BUFIO2", p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk125a, o_DIVCLK=clk125b) - - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_encoder = Signal() - unbuf_sys = Signal() - unbuf_unused = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=1, - # Input Clocks (125MHz) - i_CLKIN1=clk125b, - p_CLKIN1_PERIOD=platform.default_clk_period, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - # (1000MHz) vco - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=8, p_CLKFBOUT_PHASE=0., - # (200MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=5, - # (100MHz) unused - o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=10, - # (100MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=10, - # (100MHz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=10, - # (100MHz) unused - o_CLKOUT4=unbuf_unused, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=10, - # ( 50MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=20, - ) - - # power on reset? - reset = ~platform.request("cpu_reset") | self.reset - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - # System clock - 50MHz - self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance("BUFPLL", name="sdram_full_bufpll", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb) - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - # sdram_half - self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) - clk_sdram_half_shifted = Signal() - self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) - - output_clk = Signal() - clk = platform.request("ddram_clock_b") - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=output_clk) - self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) +from .crg import _CRG + +from targets.utils import dict_set_max class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "ddrphy", - "info", - "cas", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "emulator_ram": 0x50000000, # (default shadow @0xd0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = int(50e6) - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - - self.submodules.crg = _CRG(platform) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) - + sys_clk_freq = int(50e6) + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR2 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT47H32M16(sys_clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram_b"), + memtype = sdram_module.memtype, + rd_bitslip = 0, + wr_bitslip = 4, + dqs_ddr_alignment="C0") + self.add_csr("ddrphy") + controller_settings = ControllerSettings( + with_bandwidth=True) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ + # info module self.submodules.info = info.Info(platform, self.__class__.__name__) - self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) - + self.add_csr("info") + # control and status module + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # ?????? gmii_rst_n = platform.request("gmii_rst_n") - self.comb += [ gmii_rst_n.eq(1) ] + + # Support for soft-emulation for full Linux support ---------------------------------------- if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": size = 0x4000 self.submodules.emulator_ram = wishbone.SRAM(size) self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - # sdram - sdram_module = MT47H32M16(self.clk_freq, "1:2") - self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( - platform.request("ddram_b"), - sdram_module.memtype, - rd_bitslip=0, - wr_bitslip=4, - dqs_ddr_alignment="C0") - controller_settings = ControllerSettings(with_bandwidth=True) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings) - self.comb += [ - self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), - self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), - ] - SoC = BaseSoC diff --git a/targets/pano_logic_g2/crg.py b/targets/pano_logic_g2/crg.py new file mode 100755 index 000000000..3e914a58d --- /dev/null +++ b/targets/pano_logic_g2/crg.py @@ -0,0 +1,119 @@ +# Support for the Pano Logic Zero Client G2 + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + + self.reset = Signal() + + f0 = int(125e6) + + clk125 = platform.request(platform.default_clk_name) + clk125a = Signal() + + self.specials += Instance("IBUFG", i_I=clk125, o_O=clk125a) + + clk125b = Signal() + + self.specials += Instance( + "BUFIO2", p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk125a, o_DIVCLK=clk125b) + + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_encoder = Signal() + unbuf_sys = Signal() + unbuf_unused = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=1, + # Input Clocks (125MHz) + i_CLKIN1=clk125b, + p_CLKIN1_PERIOD=platform.default_clk_period, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + # (1000MHz) vco + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=8, p_CLKFBOUT_PHASE=0., + # (200MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=5, + # (100MHz) unused + o_CLKOUT1=unbuf_encoder, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=10, + # (100MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=10, + # (100MHz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=10, + # (100MHz) unused + o_CLKOUT4=unbuf_unused, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=10, + # ( 50MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=20, + ) + + # power on reset? + reset = ~platform.request("cpu_reset") | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - 50MHz + self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) + + output_clk = Signal() + clk = platform.request("ddram_clock_b") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=output_clk) + self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) From c7f3a804026dfa2e9616cd2ab4337373e6379325 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:58:00 +0100 Subject: [PATCH 084/153] pipistrello: Cleanup and modernize. --- targets/pipistrello/base.py | 268 ++++++++++-------------------------- targets/pipistrello/crg.py | 160 +++++++++++++++++++++ 2 files changed, 231 insertions(+), 197 deletions(-) create mode 100644 targets/pipistrello/crg.py diff --git a/targets/pipistrello/base.py b/targets/pipistrello/base.py index e6eb0c804..d32e2acbb 100644 --- a/targets/pipistrello/base.py +++ b/targets/pipistrello/base.py @@ -1,11 +1,12 @@ # Support for the Pipistrello - http://pipistrello.saanlima.com/ + from fractions import Fraction from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * +from litex.soc.interconnect import wishbone from litedram.modules import MT46H32M16 from litedram.phy import s6ddrphy @@ -15,220 +16,93 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - # Clock domain for peripherals (such as HDMI output). - self.clock_domains.cd_base50 = ClockDomain() - - self.reset = Signal() - - # Input 50MHz clock - f0 = 50*1000000 - clk50 = platform.request("clk50") - clk50a = Signal() - # Input 50MHz clock (buffered) - self.specials += Instance("IBUFG", i_I=clk50, o_O=clk50a) - clk50b = Signal() - self.specials += Instance( - "BUFIO2", p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk50a, o_DIVCLK=clk50b) - - p = 12 - f = Fraction(clk_freq*p, f0) - n, d = f.numerator, f.denominator - assert 19e6 <= f0/d <= 500e6 # pfd - assert 400e6 <= f0*n/d <= 1080e6 # vco - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_unused = Signal() - unbuf_sys = Signal() - unbuf_periph = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=d, - # Input Clocks (50MHz) - i_CLKIN1=clk50b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., - # (333MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, - # unused? - o_CLKOUT1=unbuf_unused, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=15, - # (166MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, - # (166MHz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=p//2, - # ( 50MHz) periph - o_CLKOUT4=unbuf_periph, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=20, - # ( 83MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, - ) - - - # power on reset? - reset = platform.request("user_btn") | self.reset - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - # System clock - 75MHz - self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance("BUFPLL", name="sdram_full_bufpll", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb) - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - # sdram_half - self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) - clk_sdram_half_shifted = Signal() - self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) - clk = platform.request("ddram_clock") - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.p) - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted, - o_Q=clk.n) - - # Peripheral clock - 50MHz - # ------------------------------------------------------------------------------ - # The peripheral clock is kept separate from the system clock to allow - # the system clock to be increased in the future. - dcm_base50_locked = Signal() - self.specials += [ - Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", - p_CLKIN_PERIOD=20.0, - p_CLKFX_MULTIPLY=2, - p_CLKFX_DIVIDE=2, - p_CLKFX_MD_MAX=1.0, # CLKFX_MULTIPLY/CLKFX_DIVIDE - p_CLKFXDV_DIVIDE=2, - p_SPREAD_SPECTRUM="NONE", - p_STARTUP_WAIT="FALSE", - - i_CLKIN=clk50a, - o_CLKFX=self.cd_base50.clk, - o_LOCKED=dcm_base50_locked, - i_FREEZEDCM=0, - i_RST=ResetSignal(), - ), - AsyncResetSynchronizer(self.cd_base50, - self.cd_sys.rst | ~dcm_base50_locked) - ] - platform.add_period_constraint(self.cd_base50.clk, 20) +from targets.utils import dict_set_max +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "front_panel", - "ddrphy", - "info", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) - + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) - clk_freq = (83 + Fraction(1, 3))*1000*1000 - - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - - self.submodules.crg = _CRG(platform, clk_freq) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) - + sys_clk_freq = (83 + Fraction(1, 3))*1000*1000 + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR2 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT46H32M16(sys_clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + rd_bitslip = 1, + wr_bitslip = 3, + dqs_ddr_alignment="C1") + self.add_csr("ddrphy") + controller_settings = ControllerSettings( + with_bandwidth=True) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ + # info module self.submodules.info = info.Info(platform, self.__class__.__name__) - + self.add_csr("info") + # control and status module + #self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ self.submodules.spiflash = spi_flash.SpiFlash( platform.request("spiflash4x"), dummy=platform.spiflash_read_dummy_bits, - div=platform.spiflash_clock_div) + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) - self.register_mem("spiflash", self.mem_map["spiflash"], - self.spiflash.bus, size=platform.spiflash_total_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) + self.add_memory_region( + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - # sdram - sdram_module = MT46H32M16(self.clk_freq, "1:2") - self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( - platform.request("ddram"), - sdram_module.memtype, - rd_bitslip=1, - wr_bitslip=3, - dqs_ddr_alignment="C1") - controller_settings = ControllerSettings(with_bandwidth=True) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings) - self.comb += [ - self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), - self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), - ] + + # Support for soft-emulation for full Linux support ---------------------------------------- + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) SoC = BaseSoC diff --git a/targets/pipistrello/crg.py b/targets/pipistrello/crg.py new file mode 100644 index 000000000..daffd3eb9 --- /dev/null +++ b/targets/pipistrello/crg.py @@ -0,0 +1,160 @@ +# Support for the Pipistrello - http://pipistrello.saanlima.com/ + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + # Clock domain for peripherals (such as HDMI output). + self.clock_domains.cd_base50 = ClockDomain() + + self.reset = Signal() + + # Input 50MHz clock + f0 = 50*1000000 + clk50 = platform.request("clk50") + clk50a = Signal() + # Input 50MHz clock (buffered) + self.specials += Instance("IBUFG", i_I=clk50, o_O=clk50a) + clk50b = Signal() + self.specials += Instance( + "BUFIO2", p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk50a, o_DIVCLK=clk50b) + + p = 12 + f = Fraction(clk_freq*p, f0) + n, d = f.numerator, f.denominator + assert 19e6 <= f0/d <= 500e6 # pfd + assert 400e6 <= f0*n/d <= 1080e6 # vco + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_unused = Signal() + unbuf_sys = Signal() + unbuf_periph = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=d, + # Input Clocks (50MHz) + i_CLKIN1=clk50b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., + # (333MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, + # unused? + o_CLKOUT1=unbuf_unused, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=15, + # (166MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, + # (166MHz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=p//2, + # ( 50MHz) periph + o_CLKOUT4=unbuf_periph, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=20, + # ( 83MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, + ) + + + # power on reset? + reset = platform.request("user_btn") | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - 75MHz + self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", name="sdram_half_a_bufpll", i_I=unbuf_sdram_half_a, o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", name="sdram_half_b_bufpll", i_I=unbuf_sdram_half_b, o_O=clk_sdram_half_shifted) + clk = platform.request("ddram_clock") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.p) + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted, + o_Q=clk.n) + + # Peripheral clock - 50MHz + # ------------------------------------------------------------------------------ + # The peripheral clock is kept separate from the system clock to allow + # the system clock to be increased in the future. + dcm_base50_locked = Signal() + self.specials += [ + Instance("DCM_CLKGEN", name="crg_periph_dcm_clkgen", + p_CLKIN_PERIOD=20.0, + p_CLKFX_MULTIPLY=2, + p_CLKFX_DIVIDE=2, + p_CLKFX_MD_MAX=1.0, # CLKFX_MULTIPLY/CLKFX_DIVIDE + p_CLKFXDV_DIVIDE=2, + p_SPREAD_SPECTRUM="NONE", + p_STARTUP_WAIT="FALSE", + + i_CLKIN=clk50a, + o_CLKFX=self.cd_base50.clk, + o_LOCKED=dcm_base50_locked, + i_FREEZEDCM=0, + i_RST=ResetSignal(), + ), + AsyncResetSynchronizer(self.cd_base50, + self.cd_sys.rst | ~dcm_base50_locked) + ] + platform.add_period_constraint(self.cd_base50.clk, 20) From 4eda01910e84853db22748964e178bc05bbf44f3 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:58:19 +0100 Subject: [PATCH 085/153] saturn: Cleanup and modernize. --- targets/saturn/base.py | 275 ++++++++++------------------------------- targets/saturn/crg.py | 168 +++++++++++++++++++++++++ 2 files changed, 236 insertions(+), 207 deletions(-) create mode 100644 targets/saturn/crg.py diff --git a/targets/saturn/base.py b/targets/saturn/base.py index 25e6ed44a..ec16a1683 100644 --- a/targets/saturn/base.py +++ b/targets/saturn/base.py @@ -1,227 +1,88 @@ # Support for the Numato Saturn (http://numato.com/product/saturn-spartan-6-fpga-development-board-with-ddr-sdram) - -from fractions import Fraction - from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer - -from litex.build.generic_platform import * from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * +from litex.soc.interconnect import wishbone from litedram.modules import MT46H32M16 from litedram.phy import s6ddrphy from litedram.core import ControllerSettings -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - - # Input 100MHz clock - f0 = Fraction(100, 1)*1000000 - clk100 = platform.request("clk100") - clk100a = Signal() - # Input 100MHz clock (buffered) - self.specials += Instance( - "IBUFG", - i_I=clk100, - o_O=clk100a - ) - - clk100b = Signal() - - self.specials += Instance( - "BUFIO2", - p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk100a, - o_DIVCLK=clk100b - ) - - #PLL parameters - f = Fraction(10, 1) - n, d = f.numerator, f.denominator - p = 8 - - assert f0*n/d/p/4 == clk_freq - assert 19e6 <= f0/d <= 500e6 # pfd - assert 400e6 <= f0*n/d <= 1000e6 # vco - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_unused_a = Signal() - unbuf_unused_b = Signal() - unbuf_sys = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=d, - # Input Clocks (100MHz) - i_CLKIN1=clk100b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., - # Outputs - # (125 MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p, - # (125 MHz) unused - o_CLKOUT1=unbuf_unused_a, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p, - # (62.5 MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=(p*2), - # (62.5 MHz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=(p*2), - # (31.25 MHz) unused - o_CLKOUT4=unbuf_unused_b, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=(p*4), - # (31.25 MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=(p*4), - ) - - #power on reset? - reset_pin = [("reset", 0, Pins("P2:0")), ] - platform.add_extension(reset_pin) - reset = platform.request("reset") - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - #System clock - self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance( - "BUFPLL", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, - i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb - ) - - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - - # sdram_half - self.specials += Instance( - "BUFG", - i_I=unbuf_sdram_half_a, - o_O=self.cd_sdram_half.clk - ) - - clk_sdram_half_shifted = Signal() - self.specials += Instance( - "BUFG", - i_I=unbuf_sdram_half_b, - o_O=clk_sdram_half_shifted - ) - - clk = platform.request("ddram_clock") - self.specials += Instance( - "ODDR2", - p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.p - ) - - self.specials += Instance( - "ODDR2", - p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.n - ) - -class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "ddrphy", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - # FIXME: Add spiflash - #mem_map = { - # "spiflash": 0x20000000, # (default shadow @0xa0000000) - #} - #mem_map.update(SoCSDRAM.mem_map) - - def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) - dict_set_max(kwargs, 'integrated_sram_size', 0x4000) +from targets.utils import dict_set_max +#from gateware import cas +from gateware import info +from gateware import spi_flash - clk_freq = (31 + Fraction(1, 4))*1000*1000 +from fractions import Fraction - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) +from .crg import _CRG - self.submodules.crg = _CRG(platform, clk_freq) - # sdram - sdram_module = MT46H32M16(self.clk_freq, "1:2") - self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( - platform.request("ddram"), - sdram_module.memtype, - rd_bitslip=2, - wr_bitslip=3, - dqs_ddr_alignment="C1" - ) +class BaseSoC(SoCSDRAM): + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} - controller_settings = ControllerSettings( - with_bandwidth=True - ) + def __init__(self, platform, **kwargs): + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_sram_size', 0x4000) - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings - ) + sys_clk_freq = (31 + Fraction(1, 4))*1000*1000 + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + + + # DDR2 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT46H32M16(sys_clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + rd_bitslip = 2, + wr_bitslip = 3, + dqs_ddr_alignment="C1") + self.add_csr("ddrphy") + controller_settings = ControllerSettings( + with_bandwidth=True) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ + # info module + self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + # control and status module + #self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ + # TODO: Add SPI Flash support here. + + # Support for soft-emulation for full Linux support ---------------------------------------- + if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": + size = 0x4000 + self.submodules.emulator_ram = wishbone.SRAM(size) + self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - self.comb += [ - self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), - self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), - ] SoC = BaseSoC diff --git a/targets/saturn/crg.py b/targets/saturn/crg.py new file mode 100644 index 000000000..94f54ec02 --- /dev/null +++ b/targets/saturn/crg.py @@ -0,0 +1,168 @@ +# Support for the Numato Saturn (http://numato.com/product/saturn-spartan-6-fpga-development-board-with-ddr-sdram) + +from fractions import Fraction + +from litex.build.generic_platform import * + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + + # Input 100MHz clock + f0 = Fraction(100, 1)*1000000 + clk100 = platform.request("clk100") + clk100a = Signal() + # Input 100MHz clock (buffered) + self.specials += Instance( + "IBUFG", + i_I=clk100, + o_O=clk100a + ) + + clk100b = Signal() + + self.specials += Instance( + "BUFIO2", + p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk100a, + o_DIVCLK=clk100b + ) + + #PLL parameters + f = Fraction(10, 1) + n, d = f.numerator, f.denominator + p = 8 + + assert f0*n/d/p/4 == clk_freq + assert 19e6 <= f0/d <= 500e6 # pfd + assert 400e6 <= f0*n/d <= 1000e6 # vco + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_unused_a = Signal() + unbuf_unused_b = Signal() + unbuf_sys = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=d, + # Input Clocks (100MHz) + i_CLKIN1=clk100b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., + # Outputs + # (125 MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p, + # (125 MHz) unused + o_CLKOUT1=unbuf_unused_a, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p, + # (62.5 MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=(p*2), + # (62.5 MHz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=(p*2), + # (31.25 MHz) unused + o_CLKOUT4=unbuf_unused_b, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=(p*4), + # (31.25 MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=(p*4), + ) + + #power on reset? + reset_pin = [("reset", 0, Pins("P2:0")), ] + platform.add_extension(reset_pin) + reset = platform.request("reset") + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + #System clock + self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance( + "BUFPLL", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, + i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb + ) + + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + + # sdram_half + self.specials += Instance( + "BUFG", + i_I=unbuf_sdram_half_a, + o_O=self.cd_sdram_half.clk + ) + + clk_sdram_half_shifted = Signal() + self.specials += Instance( + "BUFG", + i_I=unbuf_sdram_half_b, + o_O=clk_sdram_half_shifted + ) + + clk = platform.request("ddram_clock") + self.specials += Instance( + "ODDR2", + p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.p + ) + + self.specials += Instance( + "ODDR2", + p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.n + ) From d7b2460baa4d0e1eeb8d96778408a4f954e38175 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 16:58:52 +0100 Subject: [PATCH 086/153] waxwing: Cleanup and modernize. --- targets/waxwing/base.py | 263 +++++++++------------------------------- targets/waxwing/crg.py | 164 +++++++++++++++++++++++++ targets/waxwing/net.py | 173 +------------------------- 3 files changed, 228 insertions(+), 372 deletions(-) create mode 100644 targets/waxwing/crg.py diff --git a/targets/waxwing/base.py b/targets/waxwing/base.py index b645c2ac5..598e1d3b9 100644 --- a/targets/waxwing/base.py +++ b/targets/waxwing/base.py @@ -3,222 +3,79 @@ from fractions import Fraction from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer - -from litex.build.generic_platform import * from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * +from litex.soc.interconnect import wishbone from litedram.modules import MT46H32M16 from litedram.phy import s6ddrphy from litedram.core import ControllerSettings -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - - # Input 100MHz clock - f0 = Fraction(100, 1)*1000000 - clk100 = platform.request("clk100") - clk100a = Signal() - # Input 100MHz clock (buffered) - self.specials += Instance( - "IBUFG", - i_I=clk100, - o_O=clk100a - ) - - clk100b = Signal() - - self.specials += Instance( - "BUFIO2", - p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk100a, - o_DIVCLK=clk100b - ) - - #PLL parameters - f = Fraction(10, 1) - n, d = f.numerator, f.denominator - p = 8 - - assert f0*n/d/p/4 == clk_freq - assert 19e6 <= f0/d <= 500e6 # pfd - assert 400e6 <= f0*n/d <= 1000e6 # vco - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_unused_a = Signal() - unbuf_unused_b = Signal() - unbuf_sys = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=d, - # Input Clocks (100MHz) - i_CLKIN1=clk100b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., - # Outputs - # (125 MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p, - # (125 MHz) unused - o_CLKOUT1=unbuf_unused_a, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p, - # (62.5 MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=(p*2), - # (62.5 MHz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=(p*2), - # (31.25 MHz) unused - o_CLKOUT4=unbuf_unused_b, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=(p*4), - # (31.25 MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=(p*4), - ) - - #power on reset? - reset = ~platform.request("user_btn", 0) - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - #System clock - self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance( - "BUFPLL", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, - i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb - ) - - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - - # sdram_half - self.specials += Instance( - "BUFG", - i_I=unbuf_sdram_half_a, - o_O=self.cd_sdram_half.clk - ) - - clk_sdram_half_shifted = Signal() - self.specials += Instance( - "BUFG", - i_I=unbuf_sdram_half_b, - o_O=clk_sdram_half_shifted - ) - - clk = platform.request("ddram_clock") - self.specials += Instance( - "ODDR2", - p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.p - ) - - self.specials += Instance( - "ODDR2", - p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.n - ) +from targets.utils import dict_set_max -class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "ddrphy", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) +#from gateware import cas +from gateware import info +from gateware import spi_flash + +from .crg import _CRG - # FIXME: Add spiflash - #mem_map = { - # "spiflash": 0x20000000, # (default shadow @0xa0000000) - #} - #mem_map.update(SoCSDRAM.mem_map) + +class BaseSoC(SoCSDRAM): + mem_map = {**SoCSDRAM.mem_map, **{ + 'spiflash': 0x20000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) - clk_freq = (31 + Fraction(1, 4))*1000*1000 - - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) - - self.submodules.crg = _CRG(platform, clk_freq) - - # sdram - sdram_module = MT46H32M16(self.clk_freq, "1:2") - self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( - platform.request("ddram"), - sdram_module.memtype, - rd_bitslip=2, - wr_bitslip=3, - dqs_ddr_alignment="C1" - ) - - controller_settings = ControllerSettings( - with_bandwidth=True - ) - - self.register_sdram(self.ddrphy, - sdram_module.geom_settings, - sdram_module.timing_settings, - controller_settings=controller_settings - ) - - self.comb += [ - self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), - self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), - ] - + sys_clk_freq = (31 + Fraction(1, 4))*1000*1000 + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) + + # DDR2 SDRAM ------------------------------------------------------------------------------- + if True: + sdram_module = MT46H32M16(sys_clk_freq, "1:2") + self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( + platform.request("ddram"), + memtype = sdram_module.memtype, + rd_bitslip = 2, + wr_bitslip = 3, + dqs_ddr_alignment="C1") + self.add_csr("ddrphy") + controller_settings = ControllerSettings( + with_bandwidth=True) + self.register_sdram( + self.ddrphy, + geom_settings = sdram_module.geom_settings, + timing_settings = sdram_module.timing_settings, + controller_settings=controller_settings) + self.comb += [ + self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), + self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb), + ] + + # Basic peripherals ------------------------------------------------------------------------ + # info module + self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + # control and status module + #self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") + + # Add debug interface if the CPU has one --------------------------------------------------- + if hasattr(self.cpu, "debug_bus"): + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) + + # Memory mapped SPI Flash ------------------------------------------------------------------ + # TODO: Add SPI flash. SoC = BaseSoC diff --git a/targets/waxwing/crg.py b/targets/waxwing/crg.py new file mode 100644 index 000000000..781da6f23 --- /dev/null +++ b/targets/waxwing/crg.py @@ -0,0 +1,164 @@ +# Support for the Numato Saturn (http://numato.com/product/saturn-spartan-6-fpga-development-board-with-ddr-sdram) + +from fractions import Fraction + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + + # Input 100MHz clock + f0 = Fraction(100, 1)*1000000 + clk100 = platform.request("clk100") + clk100a = Signal() + # Input 100MHz clock (buffered) + self.specials += Instance( + "IBUFG", + i_I=clk100, + o_O=clk100a + ) + + clk100b = Signal() + + self.specials += Instance( + "BUFIO2", + p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", + i_I=clk100a, + o_DIVCLK=clk100b + ) + + #PLL parameters + f = Fraction(10, 1) + n, d = f.numerator, f.denominator + p = 8 + + assert f0*n/d/p/4 == clk_freq + assert 19e6 <= f0/d <= 500e6 # pfd + assert 400e6 <= f0*n/d <= 1000e6 # vco + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_unused_a = Signal() + unbuf_unused_b = Signal() + unbuf_sys = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=d, + # Input Clocks (100MHz) + i_CLKIN1=clk100b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., + # Outputs + # (125 MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p, + # (125 MHz) unused + o_CLKOUT1=unbuf_unused_a, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p, + # (62.5 MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=(p*2), + # (62.5 MHz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=(p*2), + # (31.25 MHz) unused + o_CLKOUT4=unbuf_unused_b, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=(p*4), + # (31.25 MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=(p*4), + ) + + #power on reset? + reset = ~platform.request("user_btn", 0) + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + #System clock + self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance( + "BUFPLL", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, + i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb + ) + + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + + # sdram_half + self.specials += Instance( + "BUFG", + i_I=unbuf_sdram_half_a, + o_O=self.cd_sdram_half.clk + ) + + clk_sdram_half_shifted = Signal() + self.specials += Instance( + "BUFG", + i_I=unbuf_sdram_half_b, + o_O=clk_sdram_half_shifted + ) + + clk = platform.request("ddram_clock") + self.specials += Instance( + "ODDR2", + p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.p + ) + + self.specials += Instance( + "ODDR2", + p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=clk.n + ) diff --git a/targets/waxwing/net.py b/targets/waxwing/net.py index eb60f7914..20d7d5bdb 100755 --- a/targets/waxwing/net.py +++ b/targets/waxwing/net.py @@ -24,180 +24,15 @@ from litex.soc.interconnect import wishbone -# CRG ---------------------------------------------------------------------------------------------- +from .crg import _CRG -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - self.clock_domains.cd_eth = ClockDomain() - - # Input 100MHz clock - f0 = Fraction(100, 1)*1000000 - clk100 = platform.request("clk100") - clk100a = Signal() - # Input 100MHz clock (buffered) - self.specials += Instance( - "IBUFG", - i_I=clk100, - o_O=clk100a - ) - - clk100b = Signal() - - self.specials += Instance( - "BUFIO2", - p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE", - i_I=clk100a, - o_DIVCLK=clk100b - ) - - #PLL parameters - f = Fraction(10, 1) - n, d = f.numerator, f.denominator - p = 8 - - assert f0*n/d/p/4 == clk_freq - assert 19e6 <= f0/d <= 500e6 # pfd - assert 400e6 <= f0*n/d <= 1000e6 # vco - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_unused_a = Signal() - unbuf_eth = Signal() - unbuf_sys = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=d, - # Input Clocks (100MHz) - i_CLKIN1=clk100b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0., - # Outputs - # (125 MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p, - # (125 MHz) unused - o_CLKOUT1=unbuf_unused_a, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p, - # (62.5 MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=(p*2), - # (62.5 MHz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=270., p_CLKOUT3_DIVIDE=(p*2), - # (25.00 MHz) eth - o_CLKOUT4=unbuf_eth, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=(p*5), - # (31.25 MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=(p*4), - ) - - #power on reset? - reset = ~platform.request("user_btn", 0) - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - #System clock - self.specials += Instance("BUFG", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance( - "BUFPLL", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, - i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb - ) - - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - - # ethernet - self.specials += Instance( - "BUFG", - i_I=unbuf_eth, - o_O=self.cd_eth.clk - ) - - # sdram_half - self.specials += Instance( - "BUFG", - i_I=unbuf_sdram_half_a, - o_O=self.cd_sdram_half.clk - ) - - clk_sdram_half_shifted = Signal() - self.specials += Instance( - "BUFG", - i_I=unbuf_sdram_half_b, - o_O=clk_sdram_half_shifted - ) - - clk = platform.request("ddram_clock") - self.specials += Instance( - "ODDR2", - p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.p - ) - - self.specials += Instance( - "ODDR2", - p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=clk.n - ) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCSDRAM): - mem_map = { + mem_map = {**SoCSDRAM.mem_map, **{ "emulator_ram": 0x50000000, # (default shadow @0xd0000000) - } - mem_map.update(SoCSDRAM.mem_map) + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) @@ -214,7 +49,7 @@ def __init__(self, platform, **kwargs): self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) # sdram - if not self.integrated_main_ram_size: + if not self.integrated_main_ram_size: sdram_module = MT46H32M16(clk_freq, "1:2") self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( platform.request("ddram"), From 8f8c1b8b45dc55e5d48f8b02924463f07803a581 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Tue, 31 Mar 2020 09:14:57 +0200 Subject: [PATCH 087/153] ice40_hx8k_b_evn: Cleanup and modernize. --- targets/ice40_hx8k_b_evn/base.py | 176 ++++++++++++++++++++----------- targets/ice40_hx8k_b_evn/crg.py | 30 ++++++ 2 files changed, 142 insertions(+), 64 deletions(-) create mode 100644 targets/ice40_hx8k_b_evn/crg.py diff --git a/targets/ice40_hx8k_b_evn/base.py b/targets/ice40_hx8k_b_evn/base.py index d7ac350c3..062c2f1f1 100644 --- a/targets/ice40_hx8k_b_evn/base.py +++ b/targets/ice40_hx8k_b_evn/base.py @@ -1,110 +1,158 @@ +#!/usr/bin/env python3 import sys import struct import os.path import argparse from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from litex.build.generic_platform import Pins, Subsignal, IOStandard from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * +from litex.soc.cores.cpu.vexriscv.core import VexRiscv from gateware import cas +from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max +from targets.utils import dict_set_max, platform_toolchain_extend, round_up_to_4 +from .crg import _CRG -class _CRG(Module): - def __init__(self, platform): - clk12 = platform.request("clk12") - - self.clock_domains.cd_sys = ClockDomain() - self.reset = Signal() - - # FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr - # fixes. - self.comb += self.cd_sys.clk.eq(clk12) - - # POR reset logic- POR generated from sys clk, POR logic feeds sys clk - # reset. - self.clock_domains.cd_por = ClockDomain() - reset_delay = Signal(12, reset=4095) - self.comb += [ - self.cd_por.clk.eq(self.cd_sys.clk), - self.cd_sys.rst.eq(reset_delay != 0) - ] - self.sync.por += \ - If(reset_delay != 0, - reset_delay.eq(reset_delay - 1) - ) - self.specials += AsyncResetSynchronizer(self.cd_por, self.reset) +from litex.soc.cores.uart import UARTWishboneBridge class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "cas", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + mem_map = {**SoCCore.mem_map, **{ + 'spiflash': 0x20000000, + 'vexriscv_debug': 0xf00f0000, + 'sram': 0, + }} + del mem_map['rom'] def __init__(self, platform, **kwargs): + bios_size = 0x8000 + spiflash_base = self.mem_map['spiflash'] + spiflash_bios_base = spiflash_base + platform.gateware_size + # Leave a grace area- possible one-by-off bug in add_memory_region? + # Possible fix: addr < origin + length - 1 + spiflash_user_base = spiflash_base + platform.gateware_size + bios_size + spiflash_user_size = platform.spiflash_total_size - round_up_to_4(platform.gateware_size + bios_size) + print(""" + Flash start: {:08x} +Gateware size: {:08x} + + BIOS start: {:08x} + BIOS size: {:08x} + BIOS end: {:08x} + + User start: {:08x} + User size: {:08x} + User end: {:08x} + + Flash end: {:08x} +""".format( + spiflash_base, + platform.gateware_size, + + spiflash_bios_base, + bios_size, + spiflash_bios_base+bios_size, + + spiflash_user_base, + spiflash_user_size, + spiflash_user_base+spiflash_user_size, + + spiflash_base + platform.spiflash_total_size, +)) + + kwargs['cpu_reset_address'] = spiflash_bios_base + dict_set_max(kwargs, 'integrated_sram_size', 0x2800) # disable ROM, it'll be added later kwargs['integrated_rom_size'] = 0x0 - # FIXME: Force either lite or minimal variants of CPUs; full is too big. - clk_freq = int(12e6) + kwargs['uart_name'] = 'crossover' + + sys_clk_freq = int(12e6) + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, **kwargs) + + #if isinstance(self.cpu, VexRiscv): + # self.cpu.use_external_variant("gateware/cpu/VexRiscv_Fomu_Debug.v") - kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size - SoCCore.__init__(self, platform, clk_freq, **kwargs) + self.submodules.uart_bridge = UARTWishboneBridge(platform.request("serial"), sys_clk_freq, baudrate=115200) + self.add_wb_master(self.uart_bridge.wishbone) - self.submodules.crg = _CRG(platform) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) + if isinstance(self.cpu, VexRiscv) and "debug" in self.cpu.variant: + self.register_mem( + name="vexriscv_debug", + address=0xf00f0000, + interface=self.cpu.debug_bus, + size=0x100) - # Control and Status - self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) - # SPI flash peripheral + # Basic peripherals ------------------------------------------------------------------------ + self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + #self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + #self.add_csr("cas") + + # Memory mapped SPI Flash ------------------------------------------------------------------ self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, - div=platform.spiflash_clock_div) + div=platform.spiflash_clock_div, + endianness='little') #self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) - self.register_mem("spiflash", self.mem_map["spiflash"], - self.spiflash.bus, size=platform.spiflash_total_size) - - bios_size = 0x8000 + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.register_mem( + name="spiflash", + address=spiflash_base, + interface=self.spiflash.bus, + size=platform.spiflash_total_size) + + # BIOS is running from flash self.add_constant("ROM_DISABLE", 1) self.add_memory_region( - "rom", kwargs['cpu_reset_address'], bios_size, + name="rom", + origin=spiflash_bios_base, + length=bios_size, type="cached+linker") - self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + + self.flash_boot_address = spiflash_user_base + self.add_constant("FLASH_BOOT_ADDRESS", spiflash_user_base) + + # Make the LEDs flash ---------------------------------------------------------------------- + cnt = Signal(32) + self.sync += [ + cnt.eq(cnt + 1), + ] + self.comb += [ + self.platform.request("user_led").eq(cnt[31]), + self.platform.request("user_led").eq(cnt[30]), + self.platform.request("user_led").eq(cnt[29]), + self.platform.request("user_led").eq(cnt[28]), + self.platform.request("user_led").eq(cnt[27]), + self.platform.request("user_led").eq(cnt[26]), + self.platform.request("user_led").eq(cnt[25]), + ] # We don't have a DRAM, so use the remaining SPI flash for user # program. - self.add_memory_region("user_flash", - self.flash_boot_address, - # Leave a grace area- possible one-by-off bug in add_memory_region? - # Possible fix: addr < origin + length - 1 - platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100, + self.add_memory_region( + name="user_flash", + origin=spiflash_user_base, + length=spiflash_user_size, type="cached+linker") - # Disable final deep-sleep power down so firmware words are loaded - # onto softcore's address bus. - platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin" - platform.toolchain.nextpnr_build_template[1] += " --placer heap" - platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" + platform_toolchain_extend(platform, "nextpnr-ice40", "--placer heap") SoC = BaseSoC diff --git a/targets/ice40_hx8k_b_evn/crg.py b/targets/ice40_hx8k_b_evn/crg.py new file mode 100644 index 000000000..a223f8e78 --- /dev/null +++ b/targets/ice40_hx8k_b_evn/crg.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + clk12 = platform.request("clk12") + + self.clock_domains.cd_sys = ClockDomain() + self.reset = Signal() + + # FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr + # fixes. + self.comb += self.cd_sys.clk.eq(clk12) + + # POR reset logic- POR generated from sys clk, POR logic feeds sys clk + # reset. + self.clock_domains.cd_por = ClockDomain() + reset_delay = Signal(12, reset=4095) + self.comb += [ + self.cd_por.clk.eq(self.cd_sys.clk), + self.cd_sys.rst.eq(reset_delay != 0) + ] + self.sync.por += \ + If(reset_delay != 0, + reset_delay.eq(reset_delay - 1) + ) + self.specials += AsyncResetSynchronizer(self.cd_por, self.reset) From f9256448574e7f688ef1e6e5276cdb82e91777bb Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Tue, 31 Mar 2020 09:14:57 +0200 Subject: [PATCH 088/153] ice40_up5k_b_evn: Cleanup and modernize. --- targets/ice40_up5k_b_evn/base.py | 21 +++++---------------- targets/ice40_up5k_b_evn/bridge.py | 10 +++------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/targets/ice40_up5k_b_evn/base.py b/targets/ice40_up5k_b_evn/base.py index 058cb0813..1c9af3e79 100644 --- a/targets/ice40_up5k_b_evn/base.py +++ b/targets/ice40_up5k_b_evn/base.py @@ -14,7 +14,6 @@ from gateware import ice40 from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max import platforms.ice40_up5k_b_evn as up5k @@ -57,16 +56,9 @@ def __init__(self, platform): class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "cas", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + mem_map = {**SoCCore.mem_map, **{ + "spiflash": 0x20000000, + }} def __init__(self, platform, **kwargs): # disable SRAM, it'll be added later @@ -88,12 +80,14 @@ def __init__(self, platform, **kwargs): # Control and Status self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + self.add_csr("cas") # SPI flash peripheral self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, div=platform.spiflash_clock_div) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.register_mem("spiflash", self.mem_map["spiflash"], @@ -121,10 +115,5 @@ def __init__(self, platform, **kwargs): platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100, type="cached+linker") - # Disable final deep-sleep power down so firmware words are loaded - # onto softcore's address bus. - platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin" - platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" - SoC = BaseSoC diff --git a/targets/ice40_up5k_b_evn/bridge.py b/targets/ice40_up5k_b_evn/bridge.py index 081479a1b..296728483 100644 --- a/targets/ice40_up5k_b_evn/bridge.py +++ b/targets/ice40_up5k_b_evn/bridge.py @@ -4,17 +4,10 @@ from litescope import LiteScopeAnalyzer from litescope import LiteScopeIO -from targets.utils import csr_map_update from targets.ice40_up5k_b_evn.base import BaseSoC class BridgeSoC(BaseSoC): - csr_peripherals = ( - "analyzer", - "io", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): kwargs['cpu_type'] = None BaseSoC.__init__(self, platform, *args, with_uart=False, **kwargs) @@ -22,5 +15,8 @@ def __init__(self, platform, *args, **kwargs): self.add_cpu_or_bridge(UARTWishboneBridge(platform.request("serial"), self.clk_freq, baudrate=115200)) self.add_wb_master(self.cpu_or_bridge.wishbone) + self.add_csr("analyzer") + self.add_csr("io") + SoC = BridgeSoC From f4ca02c1fa5fc6d5724c780a1b7dd7579634a254 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 17:02:27 +0100 Subject: [PATCH 089/153] netv2: Cleanup and modernize. --- targets/netv2/base.py | 30 +++++++++++------------------- targets/netv2/hdmi2pcie.py | 26 ++++++++++---------------- targets/netv2/net.py | 20 ++++++++------------ 3 files changed, 29 insertions(+), 47 deletions(-) diff --git a/targets/netv2/base.py b/targets/netv2/base.py index efe5f1ad5..d16017623 100755 --- a/targets/netv2/base.py +++ b/targets/netv2/base.py @@ -14,7 +14,7 @@ from gateware import cas from gateware import info -from targets.utils import csr_map_update, period_ns, dict_set_max +from targets.utils import period_ns, dict_set_max class _CRG(Module): @@ -93,25 +93,14 @@ def __init__(self, platform): class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "ddrphy", - "info", - "cas", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - SoCSDRAM.mem_map = { - "rom": 0x00000000, - "sram": 0x10000000, - "main_ram": 0x40000000, - "csr": 0xe0000000, - } - - mem_map = { - "spiflash": 0x20000000, + mem_map = {**SoCSDRAM.mem_map, **{ + "rom": 0x00000000, + "sram": 0x10000000, + "main_ram": 0x40000000, + "csr": 0xe0000000, + "spiflash": 0x20000000, "emulator_ram": 0x50000000, - } - mem_map.update(SoCSDRAM.mem_map) + }} def __init__(self, platform, csr_data_width=8, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) @@ -126,7 +115,9 @@ def __init__(self, platform, csr_data_width=8, **kwargs): # Basic peripherals self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + self.add_csr("cas") if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": size = 0x4000 @@ -139,6 +130,7 @@ def __init__(self, platform, csr_data_width=8, **kwargs): sdram_module = K4B2G1646F(self.clk_freq, "1:4") self.submodules.ddrphy = a7ddrphy.A7DDRPHY( platform.request("ddram")) + self.add_csr("ddrphy") controller_settings = ControllerSettings( with_bandwidth=True, cmd_buffer_depth=8, diff --git a/targets/netv2/hdmi2pcie.py b/targets/netv2/hdmi2pcie.py index b77c05970..998f74950 100644 --- a/targets/netv2/hdmi2pcie.py +++ b/targets/netv2/hdmi2pcie.py @@ -13,7 +13,8 @@ from litevideo.input import HDMIIn from litevideo.output import VideoOut -from targets.utils import period_ns, csr_map_update +from targets.utils import period_ns + class WishboneEndianSwap(Module): def __init__(self, wb_if): @@ -50,19 +51,6 @@ def __init__(self, wb_if): class HDMI2PCIeSoC(BaseSoC): - csr_peripherals = [ - "pcie_phy", - "pcie_dma0", - "pcie_dma1", - "pcie_msi", - - "hdmi_out0", - "hdmi_in0", - "hdmi_in0_freq", - "hdmi_in0_edid_mem", - ] - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, csr_data_width=32, *args, **kwargs) @@ -70,6 +58,7 @@ def __init__(self, platform, *args, **kwargs): # pcie phy self.submodules.pcie_phy = S7PCIEPHY(platform, platform.request("pcie_x1"), bar0_size=32*1024*1024) + self.add_csr("pcie_phy") platform.add_false_path_constraints( self.crg.cd_sys.clk, self.pcie_phy.cd_pcie.clk) @@ -84,9 +73,11 @@ def __init__(self, platform, *args, **kwargs): # pcie dma self.submodules.pcie_dma0 = LitePCIeDMA(self.pcie_phy, self.pcie_endpoint, with_loopback=True) + self.add_csr("pcie_dma0") # pcie msi self.submodules.pcie_msi = LitePCIeMSI() + self.add_csr("pcie_msi") self.comb += self.pcie_msi.source.connect(self.pcie_phy.msi) self.interrupts = { "PCIE_DMA0_WRITER": self.pcie_dma0.writer.irq, @@ -99,12 +90,16 @@ def __init__(self, platform, *args, **kwargs): # hdmi in 0 hdmi_in0_pads = platform.request("hdmi_in", 0) self.submodules.hdmi_in0_freq = FreqMeter(period=sys_clk_freq) + self.add_csr("hdmi_in0_freq") self.submodules.hdmi_in0 = HDMIIn( hdmi_in0_pads, self.sdram.crossbar.get_port(mode="write"), fifo_depth=1024, device="xc7", split_mmcm=True) + self.add_csr("hdmi_in0") + self.add_csr("hdmi_in0_edid_mem") + self.add_interrupt("hdmi_in0") self.comb += self.hdmi_in0_freq.clk.eq(self.hdmi_in0.clocking.cd_pix.clk), for clk in [self.hdmi_in0.clocking.cd_pix.clk, self.hdmi_in0.clocking.cd_pix1p25x.clk, @@ -120,6 +115,7 @@ def __init__(self, platform, *args, **kwargs): hdmi_out0_dram_port, "ycbcr422", fifo_depth=4096) + self.add_csr("hdmi_out0") for clk in [self.hdmi_out0.driver.clocking.cd_pix.clk, self.hdmi_out0.driver.clocking.cd_pix5x.clk]: self.platform.add_false_path_constraints(self.crg.cd_sys.clk, clk) @@ -127,7 +123,5 @@ def __init__(self, platform, *args, **kwargs): for name, value in sorted(self.platform.hdmi_infos.items()): self.add_constant(name, value) - self.add_interrupt("hdmi_in0") - SoC = HDMI2PCIeSoC diff --git a/targets/netv2/net.py b/targets/netv2/net.py index 05c6a5656..0d3a4d5d2 100755 --- a/targets/netv2/net.py +++ b/targets/netv2/net.py @@ -4,21 +4,14 @@ from liteeth.core.mac import LiteEthMAC from liteeth.phy.rmii import LiteEthPHYRMII -from targets.utils import csr_map_update, dict_set_max +from targets.utils import dict_set_max from targets.netv2.base import SoC as BaseSoC class NetSoC(BaseSoC): - csr_peripherals = ( - "ethphy", - "ethmac", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - - mem_map = { - "ethmac": 0xb0000000 - } - mem_map.update(BaseSoC.mem_map) + mem_map = {**BaseSoC.mem_map, **{ + "ethmac": 0xb0000000, + }} def __init__(self, platform, *args, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x10000) @@ -28,8 +21,12 @@ def __init__(self, platform, *args, **kwargs): self.submodules.ethphy = LiteEthPHYRMII( platform.request("eth_clocks"), platform.request("eth")) + self.add_csr("ethphy") self.submodules.ethmac = LiteEthMAC( phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) + + self.add_csr("ethmac") + self.add_interrupt("ethmac") self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") @@ -42,7 +39,6 @@ def __init__(self, platform, *args, **kwargs): self.ethphy.crg.cd_eth_rx.clk, self.ethphy.crg.cd_eth_tx.clk) - self.add_interrupt("ethmac") SoC = NetSoC From 121399fc91a7fffc218be84fb283cdb43ecfd107 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Tue, 31 Mar 2020 09:14:58 +0200 Subject: [PATCH 090/153] icebreaker: Cleanup and modernize. --- targets/icebreaker/base.py | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/targets/icebreaker/base.py b/targets/icebreaker/base.py index 719a49c9d..c3ffcb815 100644 --- a/targets/icebreaker/base.py +++ b/targets/icebreaker/base.py @@ -15,7 +15,6 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max from platforms import icebreaker @@ -59,16 +58,9 @@ def __init__(self, platform): class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "cas", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + mem_map = {**SoCCore.mem_map, **{ + "spiflash": 0xa0000000, + }} def __init__(self, platform, **kwargs): # disable SRAM, it'll be added later @@ -92,6 +84,7 @@ def __init__(self, platform, **kwargs): # Control and Status self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + self.add_csr("cas") # SPI flash peripheral # TODO: Inferred tristate not currently supported by nextpnr; upgrade @@ -101,6 +94,7 @@ def __init__(self, platform, **kwargs): dummy=platform.spiflash_read_dummy_bits, div=platform.spiflash_clock_div, endianness=self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.register_mem("spiflash", self.mem_map["spiflash"], @@ -133,9 +127,5 @@ def __init__(self, platform, **kwargs): platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100, type="cached+linker") - # Disable final deep-sleep power down so firmware words are loaded - # onto softcore's address bus. - platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin" - platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" SoC = BaseSoC From 058f11dc047cfc3417d4d71b1025990c038100c1 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Tue, 31 Mar 2020 09:14:58 +0200 Subject: [PATCH 091/153] icefun: Cleanup and modernize. --- targets/icefun/base.py | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/targets/icefun/base.py b/targets/icefun/base.py index 30170403d..1f8f4f063 100644 --- a/targets/icefun/base.py +++ b/targets/icefun/base.py @@ -13,7 +13,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max +from targets.utils import dict_set_max class _CRG(Module): @@ -43,16 +43,9 @@ def __init__(self, platform): class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "cas", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + mem_map = {**SoCCore.mem_map, **{ + "spiflash": 0x20000000, + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_sram_size', 0x2800) @@ -72,12 +65,14 @@ def __init__(self, platform, **kwargs): # Control and Status self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + self.add_csr("cas") # SPI flash peripheral self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, div=platform.spiflash_clock_div) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.register_mem("spiflash", self.mem_map["spiflash"], @@ -100,10 +95,5 @@ def __init__(self, platform, **kwargs): platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100, type="cached+linker") - # Disable final deep-sleep power down so firmware words are loaded - # onto softcore's address bus. - platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin" - platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" - SoC = BaseSoC From 334bde994ff73fdc43ff5478a1ab7c174f16cd8a Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 17:03:05 +0100 Subject: [PATCH 092/153] neso: Cleanup and modernize. --- targets/neso/base.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/targets/neso/base.py b/targets/neso/base.py index 908e489f1..cf90635b4 100755 --- a/targets/neso/base.py +++ b/targets/neso/base.py @@ -13,7 +13,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, period_ns, dict_set_max +from targets.utils import period_ns, dict_set_max class _CRG(Module): @@ -84,17 +84,9 @@ def __init__(self, platform): class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "ddrphy", - "info", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + "spiflash": 0x20000000, + }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) @@ -109,6 +101,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): # Basic peripherals self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") # spi flash spiflash_pads = platform.request(spiflash) @@ -124,6 +117,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): spiflash_pads, dummy=spiflash_dummy[spiflash], div=2) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", 256) self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000) self.add_wb_slave(self.mem_map["spiflash"], self.spiflash.bus) @@ -135,6 +129,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): sdram_module = MT41K128M16(self.clk_freq, "1:4") self.submodules.ddrphy = a7ddrphy.A7DDRPHY( platform.request("ddram")) + self.add_csr("ddrphy") self.add_constant("READ_LEVELING_BITSLIP", 3) self.add_constant("READ_LEVELING_DELAY", 14) controller_settings = ControllerSettings( From 400f1948d12eb145535f18b0ba8f78ac02c28790 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Tue, 31 Mar 2020 09:14:58 +0200 Subject: [PATCH 093/153] tinyfpga_bx: Cleanup and modernize. --- targets/tinyfpga_bx/base.py | 54 ++-------- targets/tinyfpga_bx/crg.py | 28 ++++++ targets/tinyfpga_bx/internal.py | 170 ++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 45 deletions(-) create mode 100755 targets/tinyfpga_bx/crg.py create mode 100755 targets/tinyfpga_bx/internal.py diff --git a/targets/tinyfpga_bx/base.py b/targets/tinyfpga_bx/base.py index 703313127..5fad8c004 100755 --- a/targets/tinyfpga_bx/base.py +++ b/targets/tinyfpga_bx/base.py @@ -4,7 +4,6 @@ import argparse from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer from litex.build.generic_platform import Pins, Subsignal, IOStandard from litex.soc.integration.soc_core import * @@ -13,7 +12,8 @@ from gateware import cas from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max +from targets.utils import dict_set_max +from .crg import _CRG serial = [ @@ -24,48 +24,18 @@ ) ] -class _CRG(Module): - def __init__(self, platform): - clk16 = platform.request("clk16") - - self.clock_domains.cd_sys = ClockDomain() - self.reset = Signal() - - # FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr - # fixes. - self.comb += self.cd_sys.clk.eq(clk16) - - # POR reset logic- POR generated from sys clk, POR logic feeds sys clk - # reset. - self.clock_domains.cd_por = ClockDomain() - reset_delay = Signal(12, reset=4095) - self.comb += [ - self.cd_por.clk.eq(self.cd_sys.clk), - self.cd_sys.rst.eq(reset_delay != 0) - ] - self.sync.por += \ - If(reset_delay != 0, - reset_delay.eq(reset_delay - 1) - ) - self.specials += AsyncResetSynchronizer(self.cd_por, self.reset) - class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "cas", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { + mem_map = {**SoCCore.mem_map, **{ "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_sram_size', 0x2800) - # disable ROM, it'll be added later + # We save the ROM size passed in as the BIOS size, and then force the + # integrated ROM size to 0 to avoid integrated ROM. + bios_size = kwargs['integrated_rom_size'] kwargs['integrated_rom_size'] = 0x0 # FIXME: Force either lite or minimal variants of CPUs; full is too big. @@ -82,18 +52,19 @@ def __init__(self, platform, **kwargs): # Control and Status self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + self.add_csr("cas") # SPI flash peripheral self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, div=platform.spiflash_clock_div) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.register_mem("spiflash", self.mem_map["spiflash"], self.spiflash.bus, size=platform.spiflash_total_size) - bios_size = 0x8000 self.add_constant("ROM_DISABLE", 1) self.add_memory_region( "rom", kwargs['cpu_reset_address'], bios_size, @@ -113,12 +84,5 @@ def __init__(self, platform, **kwargs): # Disable USB activity until we switch to a USB UART. self.comb += [platform.request("usb").pullup.eq(0)] - # Arachne-pnr is unsupported- it has trouble routing this design - # on this particular board reliably. That said, annotate the build - # template anyway just in case. - # Disable final deep-sleep power down so firmware words are loaded - # onto softcore's address bus. - platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin" - platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" SoC = BaseSoC diff --git a/targets/tinyfpga_bx/crg.py b/targets/tinyfpga_bx/crg.py new file mode 100755 index 000000000..b939d1727 --- /dev/null +++ b/targets/tinyfpga_bx/crg.py @@ -0,0 +1,28 @@ +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +class _CRG(Module): + def __init__(self, platform): + clk16 = platform.request("clk16") + + self.clock_domains.cd_sys = ClockDomain() + self.reset = Signal() + + # FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr + # fixes. + self.comb += self.cd_sys.clk.eq(clk16) + + # POR reset logic- POR generated from sys clk, POR logic feeds sys clk + # reset. + self.clock_domains.cd_por = ClockDomain() + reset_delay = Signal(12, reset=4095) + self.comb += [ + self.cd_por.clk.eq(self.cd_sys.clk), + self.cd_sys.rst.eq(reset_delay != 0) + ] + self.sync.por += \ + If(reset_delay != 0, + reset_delay.eq(reset_delay - 1) + ) + self.specials += AsyncResetSynchronizer(self.cd_por, self.reset) + diff --git a/targets/tinyfpga_bx/internal.py b/targets/tinyfpga_bx/internal.py new file mode 100755 index 000000000..cb5dcc6d7 --- /dev/null +++ b/targets/tinyfpga_bx/internal.py @@ -0,0 +1,170 @@ +import sys +import struct +import os.path +import argparse + +from migen import * +from migen.genlib.resetsync import AsyncResetSynchronizer + +from litex.build.generic_platform import ConstraintError +from litex.build.generic_platform import Pins, Subsignal, IOStandard, Misc +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * + +from gateware import info +#from gateware import cas +from gateware import spi_flash + + +serial = [ + ("serial", 0, + Subsignal("rx", Pins("GPIO:0")), # Pin 1 - A2 - Silkscreen 1 + Subsignal("tx", Pins("GPIO:1")), # Pin 2 - A1 - Silkscreen 2 + IOStandard("LVCMOS33") + ) +] + +reset_button = [ + # Reset shorts these two pins together + # Pin 12 - Silkscreen 12 + ("reset", 0, Pins("GPIO:11"), IOStandard("LVCMOS33"), Misc("PullUp")), + # Pin 13 - Silkscreen 13 + ("reset_out", 0, Pins("GPIO:12"), IOStandard("LVCMOS33")), +] + + +class _CRG(Module): + def __init__(self, platform): + clk16 = platform.request("clk16") + + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_usb_48 = ClockDomain() #reset_less=True) + + self.reset = Signal() + + # Reset signal goes high to reset. + try: + self.reset_pin = platform.request("reset") + except ConstraintError: + assert False + self.reset_pin = Signal() + + # Drive reset_out a constant 1. + try: + reset_out = platform.request("reset_out") + self.comb += [ + reset_out.eq(0), + ] + except ConstraintError: + assert False + pass + + #self.platform.add_period_constraint(self.usb_48.clk, 1e9/48e9) + + # FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr + # fixes. + self.comb += self.cd_sys.clk.eq(clk16) + + # POR reset logic- POR generated from sys clk, POR logic feeds sys clk + # reset. + self.clock_domains.cd_por = ClockDomain() + reset_delay = Signal(12, reset=4095) + self.comb += [ + self.cd_por.clk.eq(self.cd_sys.clk), + self.cd_sys.rst.eq(reset_delay != 0), + platform.request("user_led").eq(self.reset_pin), + ] + self.sync.por += \ + If(reset_delay != 0, + reset_delay.eq(reset_delay - 1) + ) + self.specials += AsyncResetSynchronizer(self.cd_por, self.reset) + + self.specials += [ + Instance( + "SB_PLL40_CORE", + # Parameters + p_DIVR = 0, + p_DIVF = 0b0101111, + p_DIVQ = 0b100, + p_FILTER_RANGE = 1, + p_FEEDBACK_PATH = "SIMPLE", + p_DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED", + p_FDA_FEEDBACK = 0, + p_DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED", + p_FDA_RELATIVE = 0, + p_SHIFTREG_DIV_MODE = 0, + p_PLLOUT_SELECT = "GENCLK", + p_ENABLE_ICEGATE = 0, + # IO + i_REFERENCECLK = clk16, + o_PLLOUTCORE = self.cd_usb_48.clk, + #o_PLLOUTGLOBAL, + #i_EXTFEEDBACK, + #i_DYNAMICDELAY, + #o_LOCK, + i_BYPASS = 0, + i_RESETB = 1, + #i_LATCHINPUTVALUE, + #o_SDO, + #i_SDI, + ), + ] + + +class RAMSoC(SoCCore): + def __init__(self, platform, **kwargs): + + # The TinyFPGA BX has 128kbit of blockram == 16kbytes + # Each BRAM is 512bytes == 32 BRAM blocks + # Need 4 BRAM blocks for USB, leaving 28. + # - 8kbytes ROM - 16 x BRAMs + # - 4kbytes RAM - 8 x BRAMs + + kwargs['integrated_rom_size']=0 + kwargs['integrated_sram_size']=16*1024 + + # Disable BIOS + #kwargs['integrated_rom_init'] = [0] + + # FIXME: Force either lite or minimal variants of CPUs; full is too big. + if 'cpu_variant' not in kwargs: + kwargs['cpu_variant']='lite' + + platform.add_extension(serial) + platform.add_extension(reset_button) + clk_freq = int(16e6) + + # Extra 0x28000 is due to bootloader bitstream. + SoCCore.__init__(self, platform, clk_freq, **kwargs) + + self.submodules.crg = _CRG(platform) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) + + self.submodules.info = info.Info(platform, self.__class__.__name__) + self.add_csr("info") + + # Control and Status +# self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) +# self.add_csr("cas") + + # SPI flash peripheral + self.submodules.spiflash = spi_flash.SpiFlashSingle( + platform.request("spiflash"), + dummy=platform.spiflash_read_dummy_bits, + div=platform.spiflash_clock_div) + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.register_mem("spiflash", self.mem_map["spiflash"], + self.spiflash.bus, size=platform.spiflash_total_size) + + bios_size = 0x8000 + self.add_constant("ROM_DISABLE", 1) + self.add_memory_region("rom", kwargs['cpu_reset_address'], bios_size) + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size+platform.bootloader_size + + # Disable USB activity until we switch to a USB UART. + #self.comb += [platform.request("usb").pullup.eq(0)] + + +SoC = RAMSoC From ddf28b1d4f33047d202e65d7d6e67b7af30933bf Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 17:03:40 +0100 Subject: [PATCH 094/153] upduino_v1: Cleanup and modernize. --- targets/upduino_v1/base.py | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/targets/upduino_v1/base.py b/targets/upduino_v1/base.py index 68112068c..ab1766a53 100644 --- a/targets/upduino_v1/base.py +++ b/targets/upduino_v1/base.py @@ -15,7 +15,6 @@ from gateware import ice40 from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max import platforms.upduino_v1 as upduino @@ -42,16 +41,9 @@ def __init__(self, platform): class BaseSoC(SoCCore): - csr_peripherals = ( - "spiflash", - "cas", - ) - csr_map_update(SoCCore.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCCore.mem_map) + mem_map = {**SoCCore.mem_map, **{ + "spiflash": 0x20000000, + }} def __init__(self, platform, **kwargs): # disable SRAM, it'll be added later @@ -74,12 +66,14 @@ def __init__(self, platform, **kwargs): # Control and Status self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + self.add_csr("cas") # SPI flash peripheral self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, div=platform.spiflash_clock_div, endianness=self.cpu.endianness) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.register_mem("spiflash", self.mem_map["spiflash"], @@ -107,10 +101,5 @@ def __init__(self, platform, **kwargs): platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100, type="cached+linker") - # Disable final deep-sleep power down so firmware words are loaded - # onto softcore's address bus. - platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin" - platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin" - SoC = BaseSoC From a304465eb6020471bfba8253f350682fe4900ed8 Mon Sep 17 00:00:00 2001 From: Tim 'mithro' Ansell Date: Thu, 5 Mar 2020 17:04:49 +0100 Subject: [PATCH 095/153] sim: Cleanup and modernize. --- targets/sim/base.py | 12 +++--------- targets/sim/memtest.py | 9 ++------- targets/sim/net.py | 22 +++++----------------- targets/sim/video.py | 8 ++------ 4 files changed, 12 insertions(+), 39 deletions(-) diff --git a/targets/sim/base.py b/targets/sim/base.py index c16952e63..9d3477641 100644 --- a/targets/sim/base.py +++ b/targets/sim/base.py @@ -13,19 +13,13 @@ from gateware import firmware -from targets.utils import csr_map_update, dict_set_max +from targets.utils import dict_set_max class BaseSoC(SoCSDRAM): - csr_peripherals = ( - , - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { + mem_map = {**SoCSDRAM, **{ "firmware_ram": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) diff --git a/targets/sim/memtest.py b/targets/sim/memtest.py index 22c5e6f24..0d362d974 100644 --- a/targets/sim/memtest.py +++ b/targets/sim/memtest.py @@ -1,22 +1,16 @@ from litedram.frontend.bist import LiteDRAMBISTGenerator, LiteDRAMBISTChecker -from targets.utils import csr_map_update from targets.sim.net import NetSoC as BaseSoC class MemTestSoC(BaseSoC): - csr_peripherals = ( - "generator", - "checker", - ) - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, platform, *args, **kwargs): BaseSoC.__init__(self, platform, *args, **kwargs) self.submodules.generator = LiteDRAMBISTGenerator( self.sdram.crossbar.get_port(mode="write"), ) + self.add_csr("generator") #self.submodules.checker = LiteDRAMBISTChecker( # self.sdram.crossbar.get_port(mode="read", data_width=16), # clock_domain="hdmi_out1_pix", @@ -25,6 +19,7 @@ def __init__(self, platform, *args, **kwargs): self.sdram.crossbar.get_port(mode="read"), # cd="hdmi_out1_pix"), ) + self.add_csr("checker") SoC = MemTestSoC diff --git a/targets/sim/net.py b/targets/sim/net.py index b396a6b90..351eea87d 100644 --- a/targets/sim/net.py +++ b/targets/sim/net.py @@ -3,28 +3,13 @@ from liteeth.phy.model import LiteEthPHYModel from liteeth.core.mac import LiteEthMAC -from targets.utils import csr_map_update from targets.sim.base import BaseSoC class NetSoC(BaseSoC): -# FIXME: The sim seems to require ethphy at 18 and ethmac at 19!? -# csr_peripherals = ( -# "ethphy", -# "ethmac", -# ) -# csr_map_update(BaseSoC.csr_map, csr_peripherals) - - csr_map = { - "ethphy": 18, - "ethmac": 19, - } - csr_map.update(BaseSoC.csr_map) - - mem_map = { + mem_map = {**SoCSDRAM, **{ "ethmac": 0xb0000000 - } - mem_map.update(BaseSoC.mem_map) + }} def __init__(self, *args, **kwargs): # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. @@ -34,8 +19,11 @@ def __init__(self, *args, **kwargs): BaseSoC.__init__(self, *args, **kwargs) self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth")) + # FIXME: The sim seems to require ethphy at 18 and ethmac at 19!? + self.add_csr("ethphy", csr_id=18) self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone", endianness=self.cpu.endianness) self.add_wb_slave(self.mem_map["ethmac"], self.ethmac.bus) + self.add_csr("ethmac", csr_id=19) self.add_memory_region("ethmac", self.mem_map["ethmac"], 0x2000, type="io") self.add_interupt("ethmac") diff --git a/targets/sim/video.py b/targets/sim/video.py index fa92849f8..b0149020c 100644 --- a/targets/sim/video.py +++ b/targets/sim/video.py @@ -3,7 +3,6 @@ from litevideo.output.common import * from litevideo.output.core import VideoOutCore -from targets.utils import csr_map_update from targets.sim.net import NetSoC as BaseSoC @@ -22,14 +21,11 @@ def __init__(self, pads): class VideoSoC(BaseSoC): - csr_peripherals = { - "video_out": 20, - } - csr_map_update(BaseSoC.csr_map, csr_peripherals) - def __init__(self, *args, **kwargs): BaseSoC.__init__(self, *args, **kwargs) self.submodules.video_out = VideoOutCore(self.sdram.crossbar.get_port()) + # FIXME: The sim seems to require video_out CSR to be 20!? + self.add_csr("video_out", csr_id=20) self.submodules.vga = VGAModel(platform.request("vga")) self.comb += self.video_out.source.connect(self.vga.sink) From 6962bafaaead6345422b5ca0580fc75573396a52 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 6 Mar 2020 13:03:22 +0100 Subject: [PATCH 096/153] matrix_voice: Cleanup and modernize. --- targets/matrix_voice/base.py | 184 ++++------------------------------- targets/matrix_voice/crg.py | 141 +++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 164 deletions(-) create mode 100644 targets/matrix_voice/crg.py diff --git a/targets/matrix_voice/base.py b/targets/matrix_voice/base.py index c95615dcd..aab5240f4 100644 --- a/targets/matrix_voice/base.py +++ b/targets/matrix_voice/base.py @@ -5,12 +5,6 @@ # Copyright 2020 MATRIX Labs # License: BSD -from fractions import Fraction - -from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.genlib.misc import WaitTimer - from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * @@ -22,157 +16,15 @@ from gateware import info from gateware import spi_flash -from targets.utils import csr_map_update, dict_set_max - - -class _CRG(Module): - def __init__(self, platform, clk_freq): - # Clock domains for the system (soft CPU and related components run at). - self.clock_domains.cd_sys = ClockDomain() - # Clock domains for the DDR interface. - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - # Clock domain for peripherals (such as HDMI output). - self.clock_domains.cd_base50 = ClockDomain() - self.clock_domains.cd_encoder = ClockDomain() - - self.reset = Signal() - - # Input 50MHz clock - f0 = 50*1000*1000 - clk50 = platform.request("clk50") - clk50a = Signal() - # Input 50MHz clock (buffered) - self.specials += Instance( - "IBUFG", - i_I=clk50, - o_O=clk50a - ) - clk50b = Signal() - self.specials += Instance( - "BUFIO2", - p_DIVIDE=1, - p_DIVIDE_BYPASS="TRUE", - p_I_INVERT="FALSE", - i_I=clk50a, - o_DIVCLK=clk50b - ) - - # Unbuffered output signals from the PLL. They need to be buffered - # before feeding into the fabric. - unbuf_sdram_full = Signal() - unbuf_sdram_half_a = Signal() - unbuf_sdram_half_b = Signal() - unbuf_unused = Signal() - unbuf_sys = Signal() - unbuf_periph = Signal() - - # PLL signals - pll_lckd = Signal() - pll_fb = Signal() - self.specials.pll = Instance( - "PLL_ADV", - name="crg_pll_adv", - p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", - p_REF_JITTER=.01, - i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, - p_DIVCLK_DIVIDE=1, - # Input Clocks (50MHz) - i_CLKIN1=clk50b, - p_CLKIN1_PERIOD=1e9/f0, - i_CLKIN2=0, - p_CLKIN2_PERIOD=0., - i_CLKINSEL=1, - # Feedback - i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, - p_CLK_FEEDBACK="CLKFBOUT", - p_CLKFBOUT_MULT=18, p_CLKFBOUT_PHASE=0., - # (300MHz) sdram wr rd - o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, - p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=3, - # unused (available) - o_CLKOUT1=unbuf_unused, p_CLKOUT1_DUTY_CYCLE=.5, - p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=6, - # (150MHz) sdram_half - sdram dqs adr ctrl - o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, - p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=6, - # (150Hz) off-chip ddr - o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, - p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=6, - # ( 75MHz) periph - o_CLKOUT4=unbuf_periph, p_CLKOUT4_DUTY_CYCLE=.5, - p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=12, - # ( 75MHz) sysclk - o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, - p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=12, - ) - - - # power on reset - reset = ~platform.request("cpu_reset",0) | self.reset - self.clock_domains.cd_por = ClockDomain() - por = Signal(max=1 << 11, reset=(1 << 11) - 1) - self.sync.por += If(por != 0, por.eq(por - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, reset) - - # System clock - 75MHz - self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) - - - # SDRAM clocks - # ------------------------------------------------------------------------------ - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - # sdram_full - self.specials += Instance("BUFPLL", name="sdram_full_bufpll", - p_DIVIDE=4, - i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, - i_LOCKED=pll_lckd, - o_IOCLK=self.cd_sdram_full_wr.clk, - o_SERDESSTROBE=self.clk4x_wr_strb) - self.comb += [ - self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), - self.clk4x_rd_strb.eq(self.clk4x_wr_strb), - ] - # sdram_half - self.specials += Instance("BUFG", - name="sdram_half_a_bufpll", - i_I=unbuf_sdram_half_a, - o_O=self.cd_sdram_half.clk) - clk_sdram_half_shifted = Signal() - self.specials += Instance("BUFG", - name="sdram_half_b_bufpll", - i_I=unbuf_sdram_half_b, - o_O=clk_sdram_half_shifted) - - output_clk = Signal() - clk = platform.request("ddram_clock") - self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", - p_INIT=0, p_SRTYPE="SYNC", - i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, - i_C0=clk_sdram_half_shifted, - i_C1=~clk_sdram_half_shifted, - o_Q=output_clk) - self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) +from targets.utils import dict_set_max + +from .crg import _CRG class BaseSoC(SoCSDRAM): - csr_peripherals = ( - "spiflash", - "ddrphy", - "info", - "cas", - ) - csr_map_update(SoCSDRAM.csr_map, csr_peripherals) - - mem_map = { - "spiflash": 0x20000000, # (default shadow @0xa0000000) - } - mem_map.update(SoCSDRAM.mem_map) + mem_map = {**SoCSDRAM.mem_map, **{ + "spiflash": 0xa0000000 + }} def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) @@ -180,22 +32,26 @@ def __init__(self, platform, **kwargs): kwargs['uart_baudrate']=230400 - clk_freq = 75*1000*1000 - - SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) + sys_clk_freq = int(75*1000*1000) + # SoCSDRAM --------------------------------------------------------------------------------- + SoCSDRAM.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) - self.submodules.crg = _CRG(platform, clk_freq) - self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq) + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq) + self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/sys_clk_freq) - # Basic peripherals + # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) - self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) + self.add_csr("info") + self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + self.add_csr("cas") - # spi flash + # Memory mapped SPI Flash ------------------------------------------------------------------ self.submodules.spiflash = spi_flash.SpiFlashSingle( platform.request("spiflash"), dummy=platform.spiflash_read_dummy_bits, div=platform.spiflash_clock_div) + self.add_csr("spiflash") self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.register_mem("spiflash", self.mem_map["spiflash"], @@ -205,8 +61,8 @@ def __init__(self, platform, **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - # sdram - sdram_module = MT47H32M16(self.clk_freq, "1:2") + # SDRAM ------------------------------------------------------------------------------------ + sdram_module = MT47H32M16(self.sys_clk_freq, "1:2") self.submodules.ddrphy = s6ddrphy.S6HalfRateDDRPHY( platform.request("ddram"), sdram_module.memtype, diff --git a/targets/matrix_voice/crg.py b/targets/matrix_voice/crg.py new file mode 100644 index 000000000..ac9442fc7 --- /dev/null +++ b/targets/matrix_voice/crg.py @@ -0,0 +1,141 @@ +# Support for the MATRIX Voice + +from migen import * + +from migen.genlib.resetsync import AsyncResetSynchronizer + +# CRG ---------------------------------------------------------------------------------------------- + +class _CRG(Module): + def __init__(self, platform, sys_clk_freq): + # Clock domains for the system (soft CPU and related components run at). + self.clock_domains.cd_sys = ClockDomain() + # Clock domains for the DDR interface. + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + # Clock domain for peripherals (such as HDMI output). + self.clock_domains.cd_base50 = ClockDomain() + self.clock_domains.cd_encoder = ClockDomain() + + self.reset = Signal() + + # Input 50MHz clock + f0 = 50*1000*1000 + clk50 = platform.request("clk50") + clk50a = Signal() + # Input 50MHz clock (buffered) + self.specials += Instance( + "IBUFG", + i_I=clk50, + o_O=clk50a + ) + clk50b = Signal() + self.specials += Instance( + "BUFIO2", + p_DIVIDE=1, + p_DIVIDE_BYPASS="TRUE", + p_I_INVERT="FALSE", + i_I=clk50a, + o_DIVCLK=clk50b + ) + + # Unbuffered output signals from the PLL. They need to be buffered + # before feeding into the fabric. + unbuf_sdram_full = Signal() + unbuf_sdram_half_a = Signal() + unbuf_sdram_half_b = Signal() + unbuf_unused = Signal() + unbuf_sys = Signal() + unbuf_periph = Signal() + + # PLL signals + pll_lckd = Signal() + pll_fb = Signal() + self.specials.pll = Instance( + "PLL_ADV", + name="crg_pll_adv", + p_SIM_DEVICE="SPARTAN6", p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL", + p_REF_JITTER=.01, + i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0, + p_DIVCLK_DIVIDE=1, + # Input Clocks (50MHz) + i_CLKIN1=clk50b, + p_CLKIN1_PERIOD=1e9/f0, + i_CLKIN2=0, + p_CLKIN2_PERIOD=0., + i_CLKINSEL=1, + # Feedback + i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd, + p_CLK_FEEDBACK="CLKFBOUT", + p_CLKFBOUT_MULT=18, p_CLKFBOUT_PHASE=0., + # (300MHz) sdram wr rd + o_CLKOUT0=unbuf_sdram_full, p_CLKOUT0_DUTY_CYCLE=.5, + p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=3, + # unused (available) + o_CLKOUT1=unbuf_unused, p_CLKOUT1_DUTY_CYCLE=.5, + p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=6, + # (150MHz) sdram_half - sdram dqs adr ctrl + o_CLKOUT2=unbuf_sdram_half_a, p_CLKOUT2_DUTY_CYCLE=.5, + p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=6, + # (150Hz) off-chip ddr + o_CLKOUT3=unbuf_sdram_half_b, p_CLKOUT3_DUTY_CYCLE=.5, + p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=6, + # ( 75MHz) periph + o_CLKOUT4=unbuf_periph, p_CLKOUT4_DUTY_CYCLE=.5, + p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=12, + # ( 75MHz) sysclk + o_CLKOUT5=unbuf_sys, p_CLKOUT5_DUTY_CYCLE=.5, + p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=12, + ) + + + # power on reset + reset = ~platform.request("cpu_reset",0) | self.reset + self.clock_domains.cd_por = ClockDomain() + por = Signal(max=1 << 11, reset=(1 << 11) - 1) + self.sync.por += If(por != 0, por.eq(por - 1)) + self.specials += AsyncResetSynchronizer(self.cd_por, reset) + + # System clock - 75MHz + self.specials += Instance("BUFG", name="sys_bufg", i_I=unbuf_sys, o_O=self.cd_sys.clk) + self.comb += self.cd_por.clk.eq(self.cd_sys.clk) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0)) + + + # SDRAM clocks + # ------------------------------------------------------------------------------ + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + # sdram_full + self.specials += Instance("BUFPLL", name="sdram_full_bufpll", + p_DIVIDE=4, + i_PLLIN=unbuf_sdram_full, i_GCLK=self.cd_sys.clk, + i_LOCKED=pll_lckd, + o_IOCLK=self.cd_sdram_full_wr.clk, + o_SERDESSTROBE=self.clk4x_wr_strb) + self.comb += [ + self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk), + self.clk4x_rd_strb.eq(self.clk4x_wr_strb), + ] + # sdram_half + self.specials += Instance("BUFG", + name="sdram_half_a_bufpll", + i_I=unbuf_sdram_half_a, + o_O=self.cd_sdram_half.clk) + clk_sdram_half_shifted = Signal() + self.specials += Instance("BUFG", + name="sdram_half_b_bufpll", + i_I=unbuf_sdram_half_b, + o_O=clk_sdram_half_shifted) + + output_clk = Signal() + clk = platform.request("ddram_clock") + self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE", + p_INIT=0, p_SRTYPE="SYNC", + i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1, + i_C0=clk_sdram_half_shifted, + i_C1=~clk_sdram_half_shifted, + o_Q=output_clk) + self.specials += Instance("OBUFDS", i_I=output_clk, o_O=clk.p, o_OB=clk.n) From 6d8fc4e55693dd1ced3023feef97a9ae98f5c550 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 31 Mar 2020 08:53:39 +0200 Subject: [PATCH 097/153] sim: Add a fixme comment --- platforms/sim.py | 1 + 1 file changed, 1 insertion(+) diff --git a/platforms/sim.py b/platforms/sim.py index 713fb6a7b..7d0812a67 100644 --- a/platforms/sim.py +++ b/platforms/sim.py @@ -1,3 +1,4 @@ +# FIXME: it seems broken from litex.boards.platforms import sim from litex.boards.platforms.sim import * __all__ = ['SimPins', 'Platform'] From f30dcd18c9a609404bd2c453016039268e32edf0 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 31 Mar 2020 11:29:10 +0200 Subject: [PATCH 098/153] scripts: add Vivado to PATH 0b923aa in LiteX changes the way vendor tools are located and removes toolchain_path argument --- scripts/download-env.sh | 6 +++++- scripts/enter-env.sh | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/download-env.sh b/scripts/download-env.sh index ec11a5b0a..0399db4ef 100755 --- a/scripts/download-env.sh +++ b/scripts/download-env.sh @@ -317,6 +317,7 @@ case $PLATFORM_TOOLCHAIN in XILINX_SETTINGS_ISE='/opt/Xilinx/*/ISE_DS/settings64.sh' XILINX_SETTINGS_VIVADO='/opt/Xilinx/Vivado/*/settings64.sh' + XILINX_BINDIR='/opt/Xilinx/Vivado/*/bin' if [ -z "$XILINX_DIR" ]; then LOCAL_XILINX_DIR=$BUILD_DIR/Xilinx @@ -339,6 +340,7 @@ case $PLATFORM_TOOLCHAIN in shopt -s nullglob XILINX_SETTINGS_ISE=($XILINX_DIR/$XILINX_SETTINGS_ISE) XILINX_SETTINGS_VIVADO=($XILINX_DIR/$XILINX_SETTINGS_VIVADO) + XILINX_BINDIR=($XILINX_DIR/$XILINX_BINDIR) shopt -u nullglob # Tell user what we found... @@ -374,7 +376,9 @@ case $PLATFORM_TOOLCHAIN in export HAVE_FPGA_TOOLCHAIN=0 fi if [ $HAVE_XILINX_TOOLCHAIN -eq 1 ]; then - export MISOC_EXTRA_CMDLINE="-Ob toolchain_path $XILINX_DIR/opt/Xilinx/" + for P in ${XILINX_BINDIR[@]}; do + export PATH="$XILINX_DIR/$P:$PATH" + done fi # Detect a likely lack of license early, but just warn if it's missing diff --git a/scripts/enter-env.sh b/scripts/enter-env.sh index 9def212f2..e6c392272 100755 --- a/scripts/enter-env.sh +++ b/scripts/enter-env.sh @@ -240,6 +240,7 @@ case $PLATFORM_TOOLCHAIN in XILINX_SETTINGS_ISE='/opt/Xilinx/*/ISE_DS/settings64.sh' XILINX_SETTINGS_VIVADO='/opt/Xilinx/Vivado/*/settings64.sh' + XILINX_BINDIR='/opt/Xilinx/Vivado/*/bin' if [ -z "$XILINX_DIR" ]; then LOCAL_XILINX_DIR=$BUILD_DIR/Xilinx @@ -262,6 +263,7 @@ case $PLATFORM_TOOLCHAIN in shopt -s nullglob XILINX_SETTINGS_ISE=($XILINX_DIR/$XILINX_SETTINGS_ISE) XILINX_SETTINGS_VIVADO=($XILINX_DIR/$XILINX_SETTINGS_VIVADO) + XILINX_BINDIR=($XILINX_DIR/$XILINX_BINDIR) shopt -u nullglob # Tell user what we found... @@ -297,7 +299,9 @@ case $PLATFORM_TOOLCHAIN in export HAVE_FPGA_TOOLCHAIN=0 fi if [ $HAVE_XILINX_TOOLCHAIN -eq 1 ]; then - export MISOC_EXTRA_CMDLINE="-Ob toolchain_path $XILINX_DIR/opt/Xilinx/" + for P in ${XILINX_BINDIR[@]}; do + export PATH="$XILINX_DIR/$P:$PATH" + done fi # Detect a likely lack of license early, but just warn if it's missing From 243c1a747d0fbc6602ac503e9ca1713f2d11d30c Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 1 Apr 2020 14:43:09 +0200 Subject: [PATCH 099/153] test: fix imports of RemoteClient --- test/test_alignment.py | 2 +- test/test_analyzer.py | 2 +- test/test_ddr3.py | 2 +- test/test_delays.py | 2 +- test/test_dump.py | 2 +- test/test_etherbone.py | 2 +- test/test_hdmi_out.py | 2 +- test/test_leds.py | 2 +- test/test_sdram.py | 2 +- test/test_sdram_bist.py | 2 +- test/test_xadc.py | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test/test_alignment.py b/test/test_alignment.py index b530f8677..70546d88c 100644 --- a/test/test_alignment.py +++ b/test/test_alignment.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import time -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient from litescope.software.driver.analyzer import LiteScopeAnalyzerDriver wb = RemoteClient() diff --git a/test/test_analyzer.py b/test/test_analyzer.py index 9c6f1ac58..629f9ecb9 100755 --- a/test/test_analyzer.py +++ b/test/test_analyzer.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import time -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient from litescope.software.driver.analyzer import LiteScopeAnalyzerDriver wb = RemoteClient() diff --git a/test/test_ddr3.py b/test/test_ddr3.py index 616dadd16..778377cb7 100755 --- a/test/test_ddr3.py +++ b/test/test_ddr3.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient import time diff --git a/test/test_delays.py b/test/test_delays.py index c2f271381..20dc9287a 100644 --- a/test/test_delays.py +++ b/test/test_delays.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import time -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient from litescope.software.driver.analyzer import LiteScopeAnalyzerDriver wb = RemoteClient() diff --git a/test/test_dump.py b/test/test_dump.py index c4321a7b8..316eae02b 100755 --- a/test/test_dump.py +++ b/test/test_dump.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient rom_base = 0x00000000 dump_size = 0x8000 diff --git a/test/test_etherbone.py b/test/test_etherbone.py index a69c2a16c..8a9b34e87 100755 --- a/test/test_etherbone.py +++ b/test/test_etherbone.py @@ -4,7 +4,7 @@ import sys sys.path.append("../") -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient wb = RemoteClient("192.168.1.50", 1234) wb.open() diff --git a/test/test_hdmi_out.py b/test/test_hdmi_out.py index 10720ec96..6b0853a86 100644 --- a/test/test_hdmi_out.py +++ b/test/test_hdmi_out.py @@ -1,6 +1,6 @@ import time -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient wb = RemoteClient(debug=True) wb.open() diff --git a/test/test_leds.py b/test/test_leds.py index ad0b56f73..d2dd1e772 100755 --- a/test/test_leds.py +++ b/test/test_leds.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient import time diff --git a/test/test_sdram.py b/test/test_sdram.py index 632a1b03e..71ac6206b 100755 --- a/test/test_sdram.py +++ b/test/test_sdram.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient import time diff --git a/test/test_sdram_bist.py b/test/test_sdram_bist.py index 5022dafb3..65c7b707e 100755 --- a/test/test_sdram_bist.py +++ b/test/test_sdram_bist.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import time -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient from litescope.software.driver.analyzer import LiteScopeAnalyzerDriver wb = RemoteClient(debug=False) diff --git a/test/test_xadc.py b/test/test_xadc.py index bba0bf414..8a535fb47 100755 --- a/test/test_xadc.py +++ b/test/test_xadc.py @@ -1,4 +1,4 @@ -from litex.soc.tools.remote import RemoteClient +from litex.tools.litex_client import RemoteClient wb = RemoteClient("192.168.1.50", 1234, csr_data_width=8) wb.open() From e7355c07e835705663a54e675709037105d9b67e Mon Sep 17 00:00:00 2001 From: Ewen McNeill Date: Fri, 13 Mar 2020 21:16:22 +1300 Subject: [PATCH 100/153] make.py: region's (now) have a size, not a length --- make.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make.py b/make.py index 5b4892492..9530e7c32 100755 --- a/make.py +++ b/make.py @@ -93,7 +93,7 @@ def get_bios(builddir, filetype="flash"): def get_bios_maxsize(args, soc): for name, region in soc.mem_regions.items(): if name == 'rom': - return region.length + return region.size # FIXME: Hard coded value? return 0x8000 From abeeb9a8d097ad5bcaba348e8ea4f688fed78730 Mon Sep 17 00:00:00 2001 From: Ewen McNeill Date: Fri, 13 Mar 2020 21:21:25 +1300 Subject: [PATCH 101/153] tinyfpga: Makefile: fix auto-build none firmware override Now that the target Makefile is included *before* the IMAGE_FILE is redefined, if FIRMWARE has been changed we will be using an old version of IMAGE_FILE from the environment, and thus were inadvertently generating two rules to build the "none" firmware bundle if FIRMWARE=none. --- targets/tinyfpga_bx/Makefile.mk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/targets/tinyfpga_bx/Makefile.mk b/targets/tinyfpga_bx/Makefile.mk index d31195cb5..dd3123dd0 100644 --- a/targets/tinyfpga_bx/Makefile.mk +++ b/targets/tinyfpga_bx/Makefile.mk @@ -29,7 +29,13 @@ gateware-load-$(PLATFORM): # As with Mimasv2, if the user asks to flash the gateware only, the BIOS must # be sent as well (because the BIOS is too big to fit into the bitstream). +# +# We have to pre-calculate what the image file will end up being, as we are +# included before it has been defined (to get the default target), so we'll +# end up comparing with an empty string/older value from the environment. +# GATEWARE_BIOS_FILE = $(TARGET_BUILD_DIR)/image-gateware+bios+none.bin +IMAGE_FW_FILE = $(TARGET_BUILD_DIR)/image-gateware+bios+$(FIRMWARE).bin gateware-flash-$(PLATFORM): $(GATEWARE_BIOS_FILE) tinyprog $(PROG_EXTRA_ARGS) --program-image $(GATEWARE_BIOS_FILE) @@ -38,7 +44,7 @@ gateware-flash-$(PLATFORM): $(GATEWARE_BIOS_FILE) # already built a image-gateware+bios+none.bin, we call make recursively # to build one here, with the FIRMWARE=none override. # -ifneq ($(GATEWARE_BIOS_FILE),$(IMAGE_FILE)) +ifneq ($(GATEWARE_BIOS_FILE),$(IMAGE_FW_FILE)) $(GATEWARE_BIOS_FILE): $(GATEWARE_FILEBASE).bin $(BIOS_FILE) mkimage.py FIRMWARE=none make image endif From d9d9cf24393e5ea39808d25fb33a693ebdc7cbe4 Mon Sep 17 00:00:00 2001 From: Ewen McNeill Date: Fri, 13 Mar 2020 22:19:22 +1300 Subject: [PATCH 102/153] micropython: link to litex hw includes (Instead of relying on third_party/ports/fupy having a cached copy of the "hw" includes, which could get out of date; and was out of date after updating litex; modern litex has a different set of CSR routines.) --- scripts/build-micropython.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/build-micropython.sh b/scripts/build-micropython.sh index 5774cd8a0..39562053a 100755 --- a/scripts/build-micropython.sh +++ b/scripts/build-micropython.sh @@ -78,6 +78,13 @@ if [ ! -e "$TARGET_MPY_BUILD_DIR/generated" ]; then ln -s $(realpath $PWD/../../software/include/generated) generated ) fi + +if [ ! -e "$TARGET_MPY_BUILD_DIR/hw" ]; then + ( + cd $TARGET_MPY_BUILD_DIR + ln -s $(realpath $PWD/../../../../third_party/litex/litex/soc/software/include/hw) hw + ) +fi TARGET_MPY_BUILD_DIR="$(realpath $TARGET_BUILD_DIR/software/micropython)" # Build micropython From 421a402a68824dda81395c58675c1d55c21a0261 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 3 Apr 2020 11:02:18 +0200 Subject: [PATCH 103/153] micropython: temporarily change the fork The new fork containt a commit removing an outdated `hw` directory generated by LiteX. --- scripts/build-micropython.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-micropython.sh b/scripts/build-micropython.sh index 39562053a..52a1f214a 100755 --- a/scripts/build-micropython.sh +++ b/scripts/build-micropython.sh @@ -48,7 +48,7 @@ MPY_SRC_DIR=$TOP_DIR/third_party/micropython if [ ! -d "$MPY_SRC_DIR" ]; then ( cd $(dirname $MPY_SRC_DIR) - git clone https://github.com/fupy/micropython.git + git clone -b modern-litex https://github.com/ewenmcneill/fupy-micropython.git micropython cd $MPY_SRC_DIR git submodule update --init ) From 9bcc7d015d2730ba24247505af93b4cebffd1903 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 6 Apr 2020 12:30:34 +0200 Subject: [PATCH 104/153] nexys_video: disable CAS as it conclicts with cpu_reset --- targets/nexys_video/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/targets/nexys_video/base.py b/targets/nexys_video/base.py index 7b85defa3..73244f8f2 100755 --- a/targets/nexys_video/base.py +++ b/targets/nexys_video/base.py @@ -10,7 +10,7 @@ from litedram.phy import s7ddrphy from litedram.core import ControllerSettings -from gateware import cas +# from gateware import cas from gateware import info from gateware import oled from gateware import spi_flash @@ -81,8 +81,8 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): # Basic peripherals ------------------------------------------------------------------------ self.submodules.info = info.Info(platform, self.__class__.__name__) self.add_csr("info") - self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) - self.add_csr("cas") + # self.submodules.cas = cas.ControlAndStatus(platform, sys_clk_freq) + # self.add_csr("cas") self.submodules.oled = oled.OLED(platform.request("oled")) self.add_csr("oled") From 2060fbcbb696fcf4ff8bc8895992ad2617f5e5e9 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 7 Apr 2020 08:48:52 +0200 Subject: [PATCH 105/153] micropython: use fupy/micropython fork This reverts commit 421a402a68824dda81395c58675c1d55c21a0261 as the current fupy/micropython no more contains the problematic `hw` directory. --- scripts/build-micropython.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-micropython.sh b/scripts/build-micropython.sh index 52a1f214a..39562053a 100755 --- a/scripts/build-micropython.sh +++ b/scripts/build-micropython.sh @@ -48,7 +48,7 @@ MPY_SRC_DIR=$TOP_DIR/third_party/micropython if [ ! -d "$MPY_SRC_DIR" ]; then ( cd $(dirname $MPY_SRC_DIR) - git clone -b modern-litex https://github.com/ewenmcneill/fupy-micropython.git micropython + git clone https://github.com/fupy/micropython.git cd $MPY_SRC_DIR git submodule update --init ) From 5af7e16c0936fcc191428e32e5e69ee8ae23e10d Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 8 Apr 2020 09:13:26 +0200 Subject: [PATCH 106/153] Update litex-renode submodule --- third_party/litex-renode | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/litex-renode b/third_party/litex-renode index 2ed761f4c..7da392963 160000 --- a/third_party/litex-renode +++ b/third_party/litex-renode @@ -1 +1 @@ -Subproject commit 2ed761f4c138f0237a7dca8d8dd45cea0b3c24d1 +Subproject commit 7da392963878842f93f09a7a218c1052ae5e45d6 From 4cd37cb493daa69bbb758ac4eb467ffc21a07629 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 17 Feb 2020 15:20:29 +0100 Subject: [PATCH 107/153] targets: Define offsets of Linux binaries in flash --- targets/arty/base.py | 4 ++-- targets/atlys/base.py | 4 ++-- targets/ice40_hx8k_b_evn/base.py | 4 ++-- targets/ice40_up5k_b_evn/base.py | 3 ++- targets/icebreaker/base.py | 3 ++- targets/icefun/base.py | 4 ++-- targets/mimasv2/base.py | 4 ++-- targets/minispartan6/base.py | 4 ++-- targets/opsis/base.py | 4 ++-- targets/pipistrello/base.py | 4 ++-- targets/sim/base.py | 4 ++-- targets/tinyfpga_bx/base.py | 4 ++-- targets/upduino_v1/base.py | 3 ++- targets/utils.py | 8 ++++++++ 14 files changed, 34 insertions(+), 23 deletions(-) diff --git a/targets/arty/base.py b/targets/arty/base.py index 568b49bec..db63e3932 100755 --- a/targets/arty/base.py +++ b/targets/arty/base.py @@ -12,7 +12,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import period_ns, dict_set_max +from targets.utils import period_ns, dict_set_max, define_flash_constants from .crg import _CRG @@ -93,7 +93,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # Support for soft-emulation for full Linux support ---------------------------------------- if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": diff --git a/targets/atlys/base.py b/targets/atlys/base.py index 3049282fc..140f3d885 100644 --- a/targets/atlys/base.py +++ b/targets/atlys/base.py @@ -14,7 +14,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants from .crg import _CRG @@ -94,7 +94,7 @@ def __init__(self, platform, **kwargs): bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # Support for soft-emulation for full Linux support ---------------------------------------- if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": diff --git a/targets/ice40_hx8k_b_evn/base.py b/targets/ice40_hx8k_b_evn/base.py index 062c2f1f1..6702459e8 100644 --- a/targets/ice40_hx8k_b_evn/base.py +++ b/targets/ice40_hx8k_b_evn/base.py @@ -14,7 +14,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import dict_set_max, platform_toolchain_extend, round_up_to_4 +from targets.utils import dict_set_max, platform_toolchain_extend, round_up_to_4, define_flash_constants from .crg import _CRG @@ -127,7 +127,7 @@ def __init__(self, platform, **kwargs): type="cached+linker") self.flash_boot_address = spiflash_user_base - self.add_constant("FLASH_BOOT_ADDRESS", spiflash_user_base) + define_flash_constants(self) # Make the LEDs flash ---------------------------------------------------------------------- cnt = Signal(32) diff --git a/targets/ice40_up5k_b_evn/base.py b/targets/ice40_up5k_b_evn/base.py index 1c9af3e79..d3b7c48ac 100644 --- a/targets/ice40_up5k_b_evn/base.py +++ b/targets/ice40_up5k_b_evn/base.py @@ -14,6 +14,7 @@ from gateware import ice40 from gateware import spi_flash +from targets.utils import define_flash_constants import platforms.ice40_up5k_b_evn as up5k @@ -99,7 +100,7 @@ def __init__(self, platform, **kwargs): "rom", kwargs['cpu_reset_address'], bios_size, type="cached+linker") self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # SPRAM- UP5K has single port RAM, might as well use it as SRAM to # free up scarce block RAM. diff --git a/targets/icebreaker/base.py b/targets/icebreaker/base.py index c3ffcb815..bc86a0852 100644 --- a/targets/icebreaker/base.py +++ b/targets/icebreaker/base.py @@ -15,6 +15,7 @@ from gateware import cas from gateware import spi_flash +from targets.utils import define_flash_constants from platforms import icebreaker @@ -111,7 +112,7 @@ def __init__(self, platform, **kwargs): "rom", kwargs['cpu_reset_address'], bios_size, type="cached+linker") self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # SPRAM- UP5K has single port RAM, might as well use it as SRAM to # free up scarce block RAM. diff --git a/targets/icefun/base.py b/targets/icefun/base.py index 1f8f4f063..64b793b89 100644 --- a/targets/icefun/base.py +++ b/targets/icefun/base.py @@ -13,7 +13,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants class _CRG(Module): @@ -84,7 +84,7 @@ def __init__(self, platform, **kwargs): "rom", kwargs['cpu_reset_address'], bios_size, type="cached+linker") self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # We don't have a DRAM, so use the remaining SPI flash for user # program. diff --git a/targets/mimasv2/base.py b/targets/mimasv2/base.py index c9ea4e784..67a38971b 100644 --- a/targets/mimasv2/base.py +++ b/targets/mimasv2/base.py @@ -16,7 +16,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants from .crg import _CRG @@ -105,7 +105,7 @@ def __init__(self, platform, **kwargs): "rom", kwargs['cpu_reset_address'], bios_size, type="cached+linker") self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) SoC = BaseSoC diff --git a/targets/minispartan6/base.py b/targets/minispartan6/base.py index 062c446be..7e0ebe4c9 100755 --- a/targets/minispartan6/base.py +++ b/targets/minispartan6/base.py @@ -12,7 +12,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants from .crg import _CRG @@ -87,7 +87,7 @@ def __init__(self, platform, **kwargs): "rom", kwargs['cpu_reset_address'], bios_size, type="cached+linker") self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) SoC = BaseSoC diff --git a/targets/opsis/base.py b/targets/opsis/base.py index 6db5dd7a1..fddb2b5d5 100644 --- a/targets/opsis/base.py +++ b/targets/opsis/base.py @@ -23,7 +23,7 @@ from .crg import _CRG -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants class FrontPanelGPIO(Module, AutoCSR): @@ -158,7 +158,7 @@ def __init__(self, platform, **kwargs): bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # Support for soft-emulation for full Linux support ---------------------------------------- if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": diff --git a/targets/pipistrello/base.py b/targets/pipistrello/base.py index d32e2acbb..14d04377d 100644 --- a/targets/pipistrello/base.py +++ b/targets/pipistrello/base.py @@ -16,7 +16,7 @@ from gateware import info from gateware import spi_flash -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants from .crg import _CRG @@ -96,7 +96,7 @@ def __init__(self, platform, **kwargs): bios_size = 0x8000 self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # Support for soft-emulation for full Linux support ---------------------------------------- if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": diff --git a/targets/sim/base.py b/targets/sim/base.py index 9d3477641..d8c8accd2 100644 --- a/targets/sim/base.py +++ b/targets/sim/base.py @@ -13,7 +13,7 @@ from gateware import firmware -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants class BaseSoC(SoCSDRAM): @@ -42,7 +42,7 @@ def __init__(self, platform, **kwargs): self.submodules.firmware_ram = firmware.FirmwareROM(firmware_ram_size, firmware_filename) self.register_mem("firmware_ram", self.mem_map["firmware_ram"], self.firmware_ram.bus, firmware_ram_size) self.flash_boot_address = self.mem_map["firmware_ram"] - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # sdram sdram_module = IS42S16160(self.clk_freq, "1:1") diff --git a/targets/tinyfpga_bx/base.py b/targets/tinyfpga_bx/base.py index 5fad8c004..7a3596164 100755 --- a/targets/tinyfpga_bx/base.py +++ b/targets/tinyfpga_bx/base.py @@ -12,7 +12,7 @@ from gateware import cas from gateware import spi_flash -from targets.utils import dict_set_max +from targets.utils import dict_set_max, define_flash_constants from .crg import _CRG @@ -70,7 +70,7 @@ def __init__(self, platform, **kwargs): "rom", kwargs['cpu_reset_address'], bios_size, type="cached+linker") self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size+platform.bootloader_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # We don't have a DRAM, so use the remaining SPI flash for user # program. diff --git a/targets/upduino_v1/base.py b/targets/upduino_v1/base.py index ab1766a53..24ce06a82 100644 --- a/targets/upduino_v1/base.py +++ b/targets/upduino_v1/base.py @@ -15,6 +15,7 @@ from gateware import ice40 from gateware import spi_flash +from targets.utils import define_flash_constants import platforms.upduino_v1 as upduino @@ -85,7 +86,7 @@ def __init__(self, platform, **kwargs): "rom", kwargs['cpu_reset_address'], bios_size, type="cached+linker") self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size - self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + define_flash_constants(self) # SPRAM- UP5K has single port RAM, might as well use it as SRAM to # free up scarce block RAM. diff --git a/targets/utils.py b/targets/utils.py index bd2b39557..e6bbcbfe9 100755 --- a/targets/utils.py +++ b/targets/utils.py @@ -139,6 +139,14 @@ def platform_toolchain_extend(platform, cmdname, argument): bt.clear() bt.extend(_platform_toolchain_cmd_join(cmds)) +def define_flash_constants(soc): + soc.add_constant("FLASH_BOOT_ADDRESS", soc.flash_boot_address) + if soc.cpu_variant == "linux": + soc.add_constant("KERNEL_IMAGE_FLASH_OFFSET", 0x00000000) + soc.add_constant("ROOTFS_IMAGE_FLASH_OFFSET", 0x00500000) + soc.add_constant("DEVICE_TREE_IMAGE_FLASH_OFFSET", 0x00D00000) + soc.add_constant("EMULATOR_IMAGE_FLASH_OFFSET", 0x00D80000) + if __name__ == "__main__": import doctest From e72f7c4511a366c0a46d1430d1af8a9f3a2f01b2 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 5 Feb 2020 10:32:34 +0100 Subject: [PATCH 108/153] build-renode: Allow to boot Linux from flash --- scripts/build-renode.sh | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/scripts/build-renode.sh b/scripts/build-renode.sh index 0220cf3f7..e2663a0ea 100755 --- a/scripts/build-renode.sh +++ b/scripts/build-renode.sh @@ -39,6 +39,7 @@ case $CPU in ;; esac +LITEX_RENODE="$TOP_DIR/third_party/litex-renode" LITEX_CONFIG_FILE="$TARGET_BUILD_DIR/test/csr.csv" if [ ! -f "$LITEX_CONFIG_FILE" ]; then make firmware @@ -75,12 +76,25 @@ RENODE_RESC="$RENODE_SCRIPTS_DIR/litex_buildenv.resc" RENODE_REPL="$RENODE_SCRIPTS_DIR/litex_buildenv.repl" mkdir -p $RENODE_SCRIPTS_DIR -python $TOP_DIR/third_party/litex-renode/generate-renode-scripts.py $LITEX_CONFIG_FILE \ - --repl "$RENODE_REPL" \ - --resc "$RENODE_RESC" \ - --bios-binary "$TARGET_BUILD_DIR/software/bios/bios.bin" \ - --firmware-binary "$TARGET_BUILD_DIR/software/$FIRMWARE/firmware.bin" \ - --configure-network ${TAP_INTERFACE:-""} + +if [ "$FIRMWARE" == "linux" ]; then + python $LITEX_RENODE/generate-renode-scripts.py $LITEX_CONFIG_FILE \ + --repl "$RENODE_REPL" \ + --resc "$RENODE_RESC" \ + --bios-binary "$TARGET_BUILD_DIR/software/bios/bios.bin" \ + --flash-binary "$TARGET_BUILD_DIR/software/linux/firmware.bin:kernel_image_flash_offset" \ + --flash-binary "$TARGET_BUILD_DIR/software/linux/riscv32-rootfs.cpio:rootfs_image_flash_offset"\ + --flash-binary "$TARGET_BUILD_DIR/software/linux/rv32.dtb:device_tree_image_flash_offset" \ + --flash-binary "$TARGET_BUILD_DIR/emulator/emulator.bin:emulator_image_flash_offset" \ + --configure-network ${TAP_INTERFACE:-""} +else + python $LITEX_RENODE/generate-renode-scripts.py $LITEX_CONFIG_FILE \ + --repl "$RENODE_REPL" \ + --resc "$RENODE_RESC" \ + --bios-binary "$TARGET_BUILD_DIR/software/bios/bios.bin" \ + --firmware-binary "$TARGET_BUILD_DIR/software/$FIRMWARE/firmware.bin" \ + --configure-network ${TAP_INTERFACE:-""} +fi # 1. include the generated script # 2. set additional parameters From 2deb4c0dbc42329ed865a5837d76e330766fab30 Mon Sep 17 00:00:00 2001 From: Karol Gugala Date: Sun, 12 Apr 2020 18:00:14 +0200 Subject: [PATCH 109/153] targets: arty: fix TF target Signed-off-by: Karol Gugala --- targets/arty/tf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/arty/tf.py b/targets/arty/tf.py index ba74b0b5e..b83d76494 100755 --- a/targets/arty/tf.py +++ b/targets/arty/tf.py @@ -3,6 +3,8 @@ from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer +from litex.build.generic_platform import * + from litex.soc.cores.bitbang import I2CMaster from targets.arty.base import BaseSoC From 9000652d70800cc71c069310eede66689cf080c4 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Tue, 14 Apr 2020 05:36:02 -0700 Subject: [PATCH 110/153] Add emulator_ram to fix CPU_VARIANT=linux build for pano_logic_g2. (builds and runs BIOS, I haven't been able to get Linux to run yet) --- targets/pano_logic_g2/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index 41895bb78..b5f816757 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -20,6 +20,7 @@ class BaseSoC(SoCSDRAM): mem_map = {**SoCSDRAM.mem_map, **{ 'spiflash': 0x20000000, + 'emulator_ram': 0x50000000, }} def __init__(self, platform, **kwargs): From e7afafa47cdf10ba8b935d9cd7e313f2b52f64d5 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Sat, 18 Apr 2020 11:22:48 -0700 Subject: [PATCH 111/153] Pano: Add support for specifing alternate UART connection via "-Op uart_connection hdmi" --- platforms/pano_logic_g2.py | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) mode change 100644 => 100755 platforms/pano_logic_g2.py diff --git a/platforms/pano_logic_g2.py b/platforms/pano_logic_g2.py old mode 100644 new mode 100755 index bffbc3c2b..a7bdb038b --- a/platforms/pano_logic_g2.py +++ b/platforms/pano_logic_g2.py @@ -21,13 +21,6 @@ # NET "osc_clk" LOC = Y13 | IOSTANDARD = LVCMOS33; ("clk125", 0, Pins("Y13"), IOStandard("LVCMOS33")), - # NET "DDC1_SCK" LOC = C14 | IOSTANDARD = LVCMOS33; - # NET "DDC1_SDA" LOC = C17 | IOSTANDARD = LVCMOS33; - ("serial", 0, - Subsignal("tx", Pins("C14"), IOStandard("LVCMOS33")), - Subsignal("rx", Pins("C17"), IOStandard("LVCMOS33")) - ), - # NET "GMII_RST_N" LOC = R11 | IOSTANDARD = LVCMOS33; ("gmii_rst_n", 0, Pins("R11"), IOStandard("LVCMOS33")), @@ -165,6 +158,22 @@ ), ] +_hdmi_serial = ( + # NET "DDC2_SCK" LOC = AA21 | IOSTANDARD = LVCMOS33; # Display data channel clock + # NET "DDC2_SDA" LOC = AB19 | IOSTANDARD = LVCMOS33; # Display data channel data + "serial", 0, + Subsignal("tx", Pins("AB19"), IOStandard("LVCMOS33")), + Subsignal("rx", Pins("AA21"), IOStandard("LVCMOS33")) +) + +_dvi_serial = ( + # NET "DDC1_SCK" LOC = C14 | IOSTANDARD = LVCMOS33; + # NET "DDC1_SDA" LOC = C17 | IOSTANDARD = LVCMOS33; + "serial", 0, + Subsignal("tx", Pins("C14"), IOStandard("LVCMOS33")), + Subsignal("rx", Pins("C17"), IOStandard("LVCMOS33")) +) + # Platform ----------------------------------------------------------------------------------------- class Platform(XilinxPlatform): @@ -172,7 +181,14 @@ class Platform(XilinxPlatform): default_clk_name = "clk125" default_clk_period = 1e9/125e6 - def __init__(self, programmer="impact", device="xc6slx150"): + def __init__(self, programmer="impact", device="xc6slx150", uart_connection="dvi"): + if uart_connection == 'dvi': + _io.append(_dvi_serial) + elif uart_connection == 'hdmi': + _io.append(_hdmi_serial) + else: + raise ValueError("Unsupported uart_connection \"{}\", available \"dvi\", \"hdmi\"".format(uart_connection)) + XilinxPlatform.__init__(self, device+"-2-fgg484", _io) self.programmer = programmer From e9ae48899ca7a056e796f32e7d8c4063e015a447 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Fri, 17 Apr 2020 18:29:43 -0700 Subject: [PATCH 112/153] Added SPI flash support. Successfully boots Linux from flash. --- platforms/pano_logic_g2.py | 19 +++++++++++++++++++ targets/pano_logic_g2/base.py | 27 ++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/platforms/pano_logic_g2.py b/platforms/pano_logic_g2.py index a7bdb038b..d25936215 100755 --- a/platforms/pano_logic_g2.py +++ b/platforms/pano_logic_g2.py @@ -156,6 +156,14 @@ # NET "DDR2B_ODT" LOC = J6 | IOSTANDARD = LVCMOS18; Subsignal("odt", Pins("J6"), IOStandard("SSTL18_II")), ), + ## onBoard SPI Flash + ("spiflash", 0, + Subsignal("cs_n", Pins("T5"), IOStandard("LVCMOS33")), + Subsignal("clk", Pins("Y21"), IOStandard("LVCMOS33")), + Subsignal("mosi", Pins("AB20"), IOStandard("LVCMOS33")), + Subsignal("miso", Pins("AA20"), IOStandard("LVCMOS33")) + ), + ] _hdmi_serial = ( @@ -181,6 +189,17 @@ class Platform(XilinxPlatform): default_clk_name = "clk125" default_clk_period = 1e9/125e6 + # actual .bit file size rounded up to next flash erase boundary + gateware_size = 0x420000 + + # Micron M25P128 + spiflash_model = "m25p128" + spiflash_read_dummy_bits = 8 + spiflash_clock_div = 4 + spiflash_total_size = int((128/8)*1024*1024) # 128Mbit/16Mbyte + spiflash_page_size = 256 + spiflash_sector_size = 0x20000 + def __init__(self, programmer="impact", device="xc6slx150", uart_connection="dvi"): if uart_connection == 'dvi': _io.append(_dvi_serial) diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index b5f816757..998044a67 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -73,7 +73,32 @@ def __init__(self, platform, **kwargs): interface=self.cpu.debug_bus, size=0x100) - # ?????? + # Memory mapped SPI Flash ------------------------------------------------------------------ + self.submodules.spiflash = spi_flash.SpiFlash( + platform.request("spiflash"), + dummy=platform.spiflash_read_dummy_bits, + div=platform.spiflash_clock_div, + endianness=self.cpu.endianness) + self.add_csr("spiflash") + self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) + self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) + self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) + self.add_wb_slave( + self.mem_map["spiflash"], + self.spiflash.bus, + platform.spiflash_total_size) + self.add_memory_region( + "spiflash", + self.mem_map["spiflash"], + platform.spiflash_total_size) + self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size + self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + self.add_constant("DEVICE_TREE_IMAGE_FLASH_OFFSET",0x00000000) + self.add_constant("EMULATOR_IMAGE_FLASH_OFFSET",0x20000) + self.add_constant("KERNEL_IMAGE_FLASH_OFFSET",0x40000) + self.add_constant("ROOTFS_IMAGE_FLASH_OFFSET",0x5c0000) + + # Take Ethernet Phy out of reset for SYSCLK of 125 Mhz gmii_rst_n = platform.request("gmii_rst_n") self.comb += [ gmii_rst_n.eq(1) From a00292e2b73027b615503802f6a985d294969a75 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 15 Apr 2020 09:44:38 +0200 Subject: [PATCH 113/153] Updating submodules. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * litedram changed from b06e946 to de55a8e * de55a8e - test/test_bandwidth: review, cleanup, fix typo. * 907ef73 - test/test_wishbone: add comments/cleanup. * 02fd39c - test/test_fifo: add comments. * 14edb5b - test/test_dma: add comments. * 97e214b - test/test_bist: add comments, fix a typo. * c55136c - test/test_bist: enable test_bist_csr_cdc (now passing with refactored CDC). * 92e34d4 - frontend/bist: simplify and fix CDC using AsyncFIFO. * 378c441 - frontend/bist: rename run/ready to run_cascade_in/run_cascade_out. * 829dee6 - frontend/bist: remove run/ready CSR. * b399ae2 - test/benchmark: default value of run is 1, no need to drive it. * 7c5e1e7 - frontend/bist: remove wrong comment and don't increment ticks when waiting. * 4dbb5b1 - test/run_benchmarks: fix syntax. * 966ebcb - test: cleanup/uniformize things between tests. * 0efd619 - test/test_adaption: review, add some comments. * 38b78fc - test/run_benchmarks: review, minor styles changes. * 962dcd7 - phy/model: review/cleanup DFITimingsChecker. * 64c2be5 - README: switch to markdown. * 835825b - Merge pull request #179 from antmicro/jboc/docs |\ | * dbac83f - core: add missing docstrings | * 1f246cb - core/crossbar: remove dead code * | 969943e - Merge pull request #178 from antmicro/jboc/unit-tests-crossbar |\ \ | * | 8a0bcb3 - test: add core.crossbar tests | * | e74a2e6 - test: fix missing cases in bankmachine test * | | 06965b7 - phy/gensdrphy: simplify using SDRTristate, change SDROutput/SDRInput to single-bit. * | | 9d20642 - litex.build: update from migen.genlib.io litex.build.io. * | | b9f4d99 - phy/gensdrphy: use SDRInput, SDROutput to allow infered or instantiated IO regs. |/ / * | 36d62d5 - Merge pull request #177 from antmicro/jboc/unit-tests-bankmachine |\ \ | * | 7b8b68a - test: add core.bankmachine tests | |/ * | 492b9fa - Merge pull request #175 from antmicro/jboc/unit-tests-bandwidth |\ \ | * | f0496b2 - core/bandwidth: avoid missing a command | * | c03bed8 - test: add core.bandwidth.Bandwidth tests * | | cc7621d - Merge pull request #173 from antmicro/jboc/unit-tests |\| | | * | a62e59b - test: skip _CommandChooser tests from Issue #174 | * | 00fcdf6 - test: split core.multiplexer tests into separate files | * | f619bed - test: clean up the code of core.multiplexer | * | 1dd4227 - test: add core.multiplexer.Multiplexer tests | * | ea93246 - test: add comments to core.multiplexer._Steerer tests | * | 26ce993 - test: add core.multiplexer._Steerer tests | * | f36b5a4 - test: add core.multiplexer._CommandChooser tests | * | a1b1abe - test: use TestCase.subTest for more verbose error messages | / * / e7cd6a7 - .travis.yml: udpate to keep it similar with others .travis.yml files. |/ * 0c3a610 - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * a98f51e - dfii: use reset_less on datapath/configuration CSRStorages. * 96b273c - common/BitSlip: use reset_less on intermediate signal. * liteeth changed from fb47853 to 705003e * 705003e - README: switch to markdown. * 92c3048 - examples: use CRG from litex.build. * 3bd807c - litex.build: update from migen.genlib.io litex.build.io. * 6ec7038 - .travis.yml: fix git clone error. * 47a2e5b - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * ab55304 - mac/sram: use reset_less on datapath/configuration CSRStorages. * liteiclink changed from 370855d to 6fdd020 * 6fdd020 - README: switch to markdown. * c4edb7e - litex.build: update from migen.genlib.io litex.build.io. * 1dcea14 - .travis.yml: fix git clone error. * e6ab98a - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * litepcie changed from 5b7e7cd to 586ef78 * 586ef78 - README: switch to markdown. * 3e24df2 - README: add Xilinx Ultrascale support. * 81b3e13 - examples: add KCU105 example. (PCIe gen2 X4). * 32d64e4 - phy: add initial Ultrascale PHY (gen2 X4). * bb7a1e0 - phy/xilinx_us_x4: adaptations on packets to expose/receive standardized TLPs. * 1f28c9f - phy: add xilinx_us_x4. * a65aab9 - examples/kc705: cleanup, enable bridge and generate csr.csv. * 0748af1 - litepcie/common: update import. * 6bcafc4 - .travis.yml: fix git clone error. * fde0c62 - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * 3dd6185 - soc/cores: use reset_less on datapath/configuration CSRStorages. * 2a1c2e7 - phy: use reset_less on id/max_request_size/max_payload_size. * litesata changed from 1e3573b to 2e5c5b1 * 2e5c5b1 - README: switch to markdown. * 71e0210 - .travis.yml: fix git clone error. * e3a980e - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * litescope changed from b3d1e69 to 54488c0 * 54488c0 - README: switch to markdown. * 72277ff - examples: use CRG from litex.build. * a05312d - litex.build: update from migen.genlib.io litex.build.io. * 5701c52 - .travis.yml: fix git clone error. * 47819e8 - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * litevideo changed from 49d8126 to 41f3014 * 41f3014 - README: switch to markdown. * 6958c21 - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * litex changed from 536ae0e6 to 2d018826 * 2d018826 - setup.py/install_requires: add requests. * 5e149ced - build/generic_programmer: add automatic search/download of flash_proxy in repositories if not available locally. * a298a9e5 - Merge pull request #467 from antmicro/region_type_fix |\ | * 77a05b78 - soc_core: Fix region type generation |/ * d44fe18b - stream/AsyncFIFO: add default depth (useful when used for CDC). * ded10c89 - build/sim/core/Makefile: add -p to mkdir modules. * c323e94c - Merge pull request #464 from mithro/litex-sim-fixes |\ | * 97d0c525 - Remove trailing whitespace. | * 5a0bb6ee - litex_sim: Rework Makefiles to put output files in gateware directory. | * a0658421 - litex_sim: Better error messages on failure to load module. * | a8bf0216 - litex_setup: raise exception on update if repository has been been initialized. * | 4fe31f07 - cores: add External Memory Interface (EMIF) Wishbone bridge. * | 44746870 - Merge pull request #462 from ironsteel/trellis-12k |\ \ | |/ |/| | * c57e438d - boards/targets/ulx3s.py: Update --device option help message | * f4b345ec - build/lattice/trellis.py: Add 12k device |/ * d0d2f282 - README: LiteDRAM moved to travis-ci.com as others repositories. * b95e0a19 - altera/common: add DDROutput, DDRInput, SDROutput, SDRInput. * 40f43efc - targets: use DDROutput on sdram_clock and similar configuration for all SDRAM targets. * 292d6b75 - build/xilinx/common: add Spartan6 specialized DDRInput, SDROutput, SDRInput and SDRTristate. * 88dc5158 - build/io: add SDR Tristate (with infered version) and remove multi-bits support on SDRIO. * fdadbd86 - build/lattice/common: remove multi-bits support on SDRInput/Output. * 8159b65b - litex/build/io: also import CRG (since using DifferentialInput). * 79913e86 - litex.build: update from migen.genlib.io litex.build.io. * 8e014f76 - litex/build: move io.py from litex/gen and re-import DifferentialInput/Output, DDRInput/Output contributed to Migen. * 2e270cf2 - platforms/versa_ecp5: remove Lattice Programmer (no longer used since we can now use OpenOCD). * deebc49a - boards/platforms: cosmetic cleanups. * 3c0ba8ae - boards/plarforms/ulx3s: cleanup, fix user_leds, add spisdcard, add PULLMODE/DRIVE on SDRAM pins. * 6c429c99 - build/lattice: add ECP5 implementation for SDRInput/SDROutput. * 72c8d590 - litex/gen: add io with SDRInput/SDROutput (if not overrided, register is supposed to be infered). * 8f57321f - tools/litex_sim: remove LiteSPI support for now since breaking Travis-CI of others sub-projects. * 9afd017a - tools/litex_term: increase workaround delay for usb_fifo. (validated on Minispartan6 and MimasA7). * fdfede22 - Merge pull request #459 from mithro/travis-fix |\ | * cb7e3099 - travis: Run Windows build but allow it to fail. | * 43242012 - travis: Use litex_setup.py from the checked out code. |/ * 30f5faf9 - Merge pull request #458 from david-sawatzke/add_triple |\ | * d69b4443 - Add riscv64-none-elf triple |/ * 14bf8b81 - soc/cores/clock: add Max10PLL. * 2470ef50 - soc/cores/clock: add Cyclone10LPPLL. * f8d6d0fd - soc/cores/clock/CycloneVPLL: fix typos. * 970c8de4 - soc/cores/clock: rename Altera to Intel. * 383fcd36 - soc/cores/clock: add CycloneVPLL. * ab4906ea - targets/de0nano: use CycloneIVPLL, remove 50MHz limitation. * 0f17547c - soc/cores/clock: add initial AlteraClocking/CycloneIV support. * 3575d03f - .travis.yml: disable windows test (failing for now). * 2ca853fd - README.md: update RISCV toolchain installation. * d770bfbf - .travis.yml: remove Python3.5 test. * bc26af0d - Merge pull request #451 from mithro/multi-os |\ | * 3305a65b - Enable testing on multiple Python versions. | * 6bd5eae4 - Enable CI for Windows and Mac. * | 30d25ffe - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * | 3f1159fa - litex_setup: reorganize a bit, add separators/comments. * | 926f961b - .travis.yml: revert full url for litex_setup.py. * | 447e8d94 - Merge pull request #452 from mithro/riscv-download |\| | * 9e324d9e - Remove symlinking step. | * 7f0ecddf - Use shutil.unpack_archive. | * a1dd8fc8 - Ignore SSL errors on CI. | * 2b2aff12 - Improve the path messages a little. | * 141644d1 - Make travis use litex_setup.py for GCC download. | * 6adabae7 - Adding SiFive RISC-V toolchain downloading to litex_setup.py | * 59b7db63 - Fix alignments. |/ * e408fb8f - Merge pull request #450 from mithro/litex-setup-fix |\ | * d781bf20 - Run `litex_setup.py` outside the git clone directory. | * dd59dac5 - litex_setup: Use subprocess so failures are noticed. |/ * 0f352cd6 - soc/cores: use reset_less on datapath/configuration CSRStorages. * a67ab418 - interconnect/csr: add reset_less parameter. * 05b1b778 - interconnect/csr, wishbone: use reset_less on datapath signals. * b95965de - cores/code_8b10b: set reset_less to True on datapath signals. * a35df4f7 - stream: set reset_less to True on datapath signals. * cf1c5d99 - Merge pull request #448 from kessam/patch-1 |\ | * fb532f5e - Fix timing constraints |/ * 60431083 - soc/cores/clock/ECP5PLL: add CLKI_DIV support. * 27f00851 - Merge pull request #447 from antmicro/spi-xip |\ | * 81be74a7 - targets: netv2: add LiteSPI | * 946cb164 - platform: netv2: update SPI flash pinout | * 31fceb0a - litex_sim: add LiteSPI | * ff04869c - litex_setup: add litespi core * | 91981b96 - soc/cores/uart: use reset_less on accumulator, reg, bitcount to reduce. * | 87160059 - soc/cores/spi_flash: add ECP5SPIFlash (non-memory-mapped). * | e3445f6c - Merge pull request #444 from ilya-epifanov/openocd-jtag-programmer |\ \ | * | 351551a0 - Added openocd jtagspi programmer, to be used with ECP5-EVN board * | | aeb9411a - Merge pull request #441 from gsomlo/gls-spisdcard-fixes |\ \ \ | * | | 8473ed56 - software/bios: add spisdcardboot() to boot_sequence() | * | | e9054ef6 - software/libbase/spisdcard: add delay to goidle loop | * | | c6b6dee2 - software/bios: factor out busy_wait() function | * | | 540218b2 - software/libbase/spisdcard: fix width of address parameter |/ / / * | | 2e48ab56 - soc/cores/spi: make dynamic clk divider optional (can be enabled with add_clk_divider method) and only use it in add_spi_sdcard. * | | 86eec1a4 - Merge pull request #439 from antmicro/fix-compiler-rt |\ \ \ | |_|/ |/| | | * | 5fa2cc66 - Update removed llvm compiler-rt repo |/ / * | 4abb3715 - targets/add_constant: avoid specifying value when value is None (=default). * | 73b43475 - software/libbase/spisdcard: add USE_SPISDCARD_RECLOCKING define to easily disable reclocking. * | b509df8b - integration/soc/add_uart: add USB CDC support (with ValentyUSB core). * | 76872a7a - tools/litex_sim: simplify using uart_name=sim. * | 09a3ce0e - integration/soc/add_uart: add Model/Sim. * | 3f43c6a2 - integration/soc/add_uart: cleanup. |/ * 5bcf730c - build/tools: add replace_in_file function. * ffe83ef0 - tools/litex_term: use 64 bytes as default payload_lengh (work for all confniguration) and add small delay between frames for FT245 FIFO. * 8f2e3692 - bios/boot: update comments. * 1746b57a - Merge pull request #437 from feliks-montez/bugfix/fix-serialboot-frames |\ | * ebdc38fc - flush rx buffer when bad crc and fix frame payload length * | c154d8d2 - test/test_targets: remove versa_ecp3. * | 8d999081 - boards/targets: update SDRAM to use new GENSDRPHY and new ECP5PLL phase support. * | 3eb08c7d - boards/platforms: remove versa_ecp3 (ECP3 no longer supported). * | eb641695 - build/lattice/diamond: remove ECP3 support. (ECP3 is not used and no longer interesting now that ECP5 has an open-source toolchain). * | bba5f182 - cores/clock/ECP5PLL: add phase support. * | 0123ccc8 - build/lattice/common: change LatticeECPXDDROutputImpl from ECP3 to ECP5. * | 5a402264 - Fix off-by-one error on almost full condition for prefetch |/ * d62ef38c - soc/doc/csr: allow CSRField.reset to be a Migen Constant. * 4adac90d - cpu/vexriscv/mem_map_linux: move main_ram to allow up to 1GB. * 63ab2ba4 - software/bios/boot/linux: move emulator.bin to main_ram and allow defining custom ram offsets. * d9984754 - targets: remove Etherbone imports. * 3b04efbc - targets: switch to add_etherbone method. * 5ad7a3b7 - integration/soc: add add_etherbone method. * d6b0819e - integration/soc/add_ethernet: add name parameter (defaults to ethmac). * 930679ef - targets: always use sys_clk_freq on SDRAM modules. * ae6ef923 - targets: fix typos in previous changes. * c547b2cc - Merge pull request #436 from rob-ng15/master |\ | * 2bf31a31 - Reclock spi sdcard access after initialisation * | 011773af - Merge pull request #435 from enjoy-digital/spi_master_clk_divider |\ \ | |/ |/| | * 61c9e54a - soc/core/spi: add Clk Divider CSR (defaults to sys_clk_freq/spi_clk_freq). * | f03d862c - targets: switch to add_ethernet method instead of EthernetSoC. * | 4e9a8ffe - targets: switch to SoCCore/add_sdram instead of SoCSDRAM. |/ * dd7718b4 - targets/arty: use new ISERDESE2 MEMORY mode. * fca52d11 - Merge branch 'master' of http://github.com/enjoy-digital/litex |\ | * 0f356648 - Merge pull request #434 from rob-ng15/master | |\ | | * f3c23377 - Use to provide structure sizes | | * c2ebbcbf - Use for structure sizes | |/ * / ccf73639 - integration/soc: add add_spi_flash method to add SPI Flash support to the SoC. |/ * ec3e0686 - targets/nexys4ddr: use LiteXSoC's add_spi_sdcard method. * d276036f - integration/soc: add add_spi_sdcard method to add SPI mode SDCard support to the SoC. * 60445709 - Merge pull request #433 from gsomlo/gls-rocket-spisdcard |\ | * b960d7c5 - targets/nexys4ddr: add '--with-spi-sdcard' build option | * 7a7b8905 - platforms/nexys4ddr: add spisdcard pins. | * af4de03f - targets/nexys4ddr: make sdcard reset conditional | * a33916bc - software/libbase/spisdcard: fix 4-byte FAT fields on 64-bit CPUs | * 1f90abea - bios: make SPI SDCard boot configs other than linux-on-litex-vexriscv | * c2938dc9 - bios/boot.c: cosmetic: re-indent spisdcardboot() for consistency * | fbadfa17 - Merge pull request #432 from esden/csr-doc-fix-int |\ \ | |/ |/| | * 27988672 - Don't let python convert lane number to float. |/ * dd07a0ad - Merge pull request #431 from antmicro/hybrid-mac |\ | * 96a265a4 - litex_sim: add support for hybrid mac * 37f25ed3 - software/libbase/bios: rename spi.c/h to spisdcard.h, also rename functions. * 93925634 - software/bios/main: revert USDDRPHY_DEBUG (merge issue with SPI SD CARD PR). * 8fe9e72f - Merge pull request #429 from rob-ng15/master |\ | * 27720409 - SPI hardware bitbanging from SD CARD | * d45dda73 - SPI hardware bitbanging from SD CARD | * 50b6db6a - SPI hardware bitbanging from SD CARD * | 9e1cd842 - Merge pull request #430 from gsomlo/gls-sdclk-stub |\ \ | * | b2103f4a - bios/sdcard: provide sdclk_set_clk() stub for clocker-less targets |/ / * / e8651629 - platforms/kcu105: fix pcie tx0 p/n swap. |/ * 2c4b8963 - soc/cores/clock: make sure specific clkoutn_divide_range is only used as a fallback solution. * litex-boards changed from a7fbe0a to cb95962 * cb95962 - targets/ulx3s and colorlight_5a_75b: cleanup USB ACM addition and only keep USB ACM changes. * 4b4f2f9 - Merge pull request #67 from mubes/ecp5_usb |\ | * f79a010 - Addition of flash for colorlight board | * 389e8aa - Addition of USB ACM for ECP5 |/ * a12faae - targets/colorlight_5a_75b: increase sys_ps phase (fixes memtest). * 52c9648 - arty_s7: fix copyrights, rename to arty_s7, various minor changes to make it similar to others targets. * 0cee59c - Merge pull request #65 from Fatsie/artys7 |\ | * bbb1ded - Added Arty S7 board |/ * 188d4a4 - targets: use DDROutput on sdram_clock and similar configuration for all SDRAM targets. * ca197af - targets/simple: use CRG from litex.build. * b8a648d - litex.build: update from migen.genlib.io litex.build.io. * 4d7135f - platforms/versa_ecp5: remove LatticeProgrammer (no longer used since we can now use OpenOCD). * 2cf3c3e - platforms: cosmetic cleanups. * df5de88 - platforms/ulx3s: cleanup, fix user_leds, add PULLMODE/DRIVE constraints on SDRAM. * 467b14a - colorlight_5a_75b: minor comment changes. * 7157b40 - Merge pull request #64 from david-sawatzke/improve_colorlight_v6.1 |\ | * 15a27d4 - targets/colorlight_5a_75b: Change baudrate to work on v6.1 | * 4fc9df8 - colorlight_5a_75b/v6.1: Add eth_clock & serial pins | * 4ddde31 - colorlight_5a_75b/v6.1: Fix bank activate pin |/ * a80737e - test/test_targets: fix typo. * 9b3f16a - Merge pull request #62 from ilya-epifanov/ecp5-evn-button1-and-spi-flash-ios |\ | * a43072a - ECP5-EVN board: Added BUTTON_1 and SPI flash pins to IOs * db67dff - targets/de10lite: use Max10PLL, remove 50MHz limitation. * 9fe9821 - test/test_targets: add c10lprefkit. * 8ccab03 - targets/c10lprefkit: use Cyclone10LPPLL, remove 50MHz limitation. * 4cdc121 - targets/de10nano: use CycloneVPLL, remove 50MHz limitation. * 2d8a4ef - targets/de1_soc: use CycloneVPLL, remove 50MHz limitation. * cec4cbb - targets/de2_115: use CycloneIVPLL, remove 50MHz limitation. * 1fac607 - targets/de0nano: use CycloneIVPLL, remove 50MHz limitation. * 5f629c2 - targets/vcu118: fix clk500 typo. * d7b9212 - .travis.yml: fix git clone error. * 5e1da47 - setup.py: simplify, switch to Python3.6+ (using python_requires), remove version. * migen changed from 0.6.dev-335-g3f9809b to 0.6.dev-337-g19d5eae * 19d5eae - zc706: fix user_led I/O standards * 21fea57 - zc706: fix indentation/style Full submodule status -- 3a6108a75be356a3dc53760d22782f1323248b6b edid-decode (remotes/origin/HEAD) 3a06aa84b62ad24467fb0d2c6ceddf565e9ea447 flash_proxies (remotes/origin/HEAD) de55a8e17046ffd6bf68d1c0d606088abdb37950 litedram (remotes/origin/HEAD) 705003e5231436de9a276e8f834564c6fbe90a1e liteeth (remotes/origin/HEAD) 6fdd02058fba29008c90b162e0ef707dce15ebeb liteiclink (remotes/origin/HEAD) 586ef787946512087a64fb60b79bdafe39aee6d0 litepcie (remotes/origin/HEAD) 2e5c5b12d52f695f4560ca7dd08b4170d7568715 litesata (remotes/origin/HEAD) 54488c0f4d6e9e953f1a0de3d578915a5e4ccddf litescope (remotes/origin/HEAD) 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 liteusb (heads/master) 41f30143075ece3fff5c33a332ed067d1837cbb3 litevideo (remotes/origin/HEAD) 2d018826532e486b94615c6b9cee4f16a924dba2 litex (remotes/origin/HEAD) cb959628506e61cae2d7be05276bba8f42138cfb litex-boards (remotes/origin/HEAD) 7da392963878842f93f09a7a218c1052ae5e45d6 litex-renode (realign_memory.0~2) 19d5eae29b9ff57ea11540252f79ad1a9526ff3a migen (0.6.dev-337-g19d5eae) 8f5a253b22cd4ebcd56304a3662f4c70e3b34ed5 nmigen (v0.1-69-g8f5a253) --- third_party/litedram | 2 +- third_party/liteeth | 2 +- third_party/liteiclink | 2 +- third_party/litepcie | 2 +- third_party/litesata | 2 +- third_party/litescope | 2 +- third_party/litevideo | 2 +- third_party/litex | 2 +- third_party/litex-boards | 2 +- third_party/migen | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/third_party/litedram b/third_party/litedram index b06e946d0..de55a8e17 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit b06e946d09807f3ab9b2e72f9c599851ab8221b4 +Subproject commit de55a8e17046ffd6bf68d1c0d606088abdb37950 diff --git a/third_party/liteeth b/third_party/liteeth index fb478537e..705003e52 160000 --- a/third_party/liteeth +++ b/third_party/liteeth @@ -1 +1 @@ -Subproject commit fb478537e7d45512567b9b35b5a69c536cb588b2 +Subproject commit 705003e5231436de9a276e8f834564c6fbe90a1e diff --git a/third_party/liteiclink b/third_party/liteiclink index 370855d8e..6fdd02058 160000 --- a/third_party/liteiclink +++ b/third_party/liteiclink @@ -1 +1 @@ -Subproject commit 370855d8edceda29b60a6df3cf35d5fc8602812d +Subproject commit 6fdd02058fba29008c90b162e0ef707dce15ebeb diff --git a/third_party/litepcie b/third_party/litepcie index 5b7e7cde0..586ef7879 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit 5b7e7cde0814e1c8337f60f6bc7b3a20d5518136 +Subproject commit 586ef787946512087a64fb60b79bdafe39aee6d0 diff --git a/third_party/litesata b/third_party/litesata index 1e3573b07..2e5c5b12d 160000 --- a/third_party/litesata +++ b/third_party/litesata @@ -1 +1 @@ -Subproject commit 1e3573b07d382eac50ef764fd839009bf90cb8ce +Subproject commit 2e5c5b12d52f695f4560ca7dd08b4170d7568715 diff --git a/third_party/litescope b/third_party/litescope index b3d1e6938..54488c0f4 160000 --- a/third_party/litescope +++ b/third_party/litescope @@ -1 +1 @@ -Subproject commit b3d1e6938f42045ade1fcb10aa2498722a4ea041 +Subproject commit 54488c0f4d6e9e953f1a0de3d578915a5e4ccddf diff --git a/third_party/litevideo b/third_party/litevideo index 49d812694..41f301430 160000 --- a/third_party/litevideo +++ b/third_party/litevideo @@ -1 +1 @@ -Subproject commit 49d812694951a924617d8e429d72c0d4da96372a +Subproject commit 41f30143075ece3fff5c33a332ed067d1837cbb3 diff --git a/third_party/litex b/third_party/litex index 536ae0e61..2d0188265 160000 --- a/third_party/litex +++ b/third_party/litex @@ -1 +1 @@ -Subproject commit 536ae0e619e3d9820f4e9ff8f33dc2829bc68398 +Subproject commit 2d018826532e486b94615c6b9cee4f16a924dba2 diff --git a/third_party/litex-boards b/third_party/litex-boards index a7fbe0a72..cb9596285 160000 --- a/third_party/litex-boards +++ b/third_party/litex-boards @@ -1 +1 @@ -Subproject commit a7fbe0a724a1b2fd788699def52c89a05cd556e5 +Subproject commit cb959628506e61cae2d7be05276bba8f42138cfb diff --git a/third_party/migen b/third_party/migen index 3f9809b0e..19d5eae29 160000 --- a/third_party/migen +++ b/third_party/migen @@ -1 +1 @@ -Subproject commit 3f9809b0ea62b26f6c99f1b5221b22f8255bc1f6 +Subproject commit 19d5eae29b9ff57ea11540252f79ad1a9526ff3a From 4ebc207d39a92b8ffcca5bfdcea1c9b6054c96b9 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 12 Feb 2020 16:18:53 +0100 Subject: [PATCH 114/153] env: Add Renode test dependencies --- scripts/download-env.sh | 26 ++++++++++++++++++++++++++ scripts/enter-env.sh | 10 ++++++++++ 2 files changed, 36 insertions(+) diff --git a/scripts/download-env.sh b/scripts/download-env.sh index 0399db4ef..855e8c18e 100755 --- a/scripts/download-env.sh +++ b/scripts/download-env.sh @@ -631,6 +631,32 @@ if [ "$FIRMWARE" = "zephyr" ]; then check_version cmake $CMAKE_VERSION fi +echo +echo "Installing psutil (python module)" +pip install psutil +check_import psutil + +echo +echo "Installing pyyaml (python module)" +pip install pyyaml +check_import yaml + +echo +echo "Installing requests (python module)" +pip install requests +check_import requests + +echo +echo "Installing netifaces (python module)" +pip install netifaces +check_import netifaces + + +echo +echo "Installing robotframework (python module)" +pip install robotframework==3.0.4 +check_import robot + # git commands echo "" echo "Updating git config" diff --git a/scripts/enter-env.sh b/scripts/enter-env.sh index e6c392272..fea96839b 100755 --- a/scripts/enter-env.sh +++ b/scripts/enter-env.sh @@ -544,6 +544,16 @@ if [ "$FIRMWARE" = "zephyr" ]; then check_import packaging || return 1 fi +check_import psutil || return 1 + +check_import yaml || return 1 + +check_import requests || return 1 + +check_import netifaces || return 1 + +check_import robot || return 1 + # git commands echo "" echo "Updating git config" From b6c85b820d5ce565cb2382a08b10e7169c347fa8 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 12 Feb 2020 16:29:57 +0100 Subject: [PATCH 115/153] ci: Add Renode tests --- .travis/build.sh | 9 ++ scripts/test-renode.sh | 106 ++++++++++++++++++++++++ tests/renode/BIOS.robot | 23 +++++ tests/renode/Firmware-firmware.robot | 28 +++++++ tests/renode/Firmware-linux.robot | 29 +++++++ tests/renode/Firmware-micropython.robot | 24 ++++++ tests/renode/Firmware-zephyr.robot | 27 ++++++ tests/renode/README.md | 72 ++++++++++++++++ 8 files changed, 318 insertions(+) create mode 100755 scripts/test-renode.sh create mode 100644 tests/renode/BIOS.robot create mode 100644 tests/renode/Firmware-firmware.robot create mode 100644 tests/renode/Firmware-linux.robot create mode 100644 tests/renode/Firmware-micropython.robot create mode 100644 tests/renode/Firmware-zephyr.robot create mode 100644 tests/renode/README.md diff --git a/.travis/build.sh b/.travis/build.sh index 9a5fa4e6a..aa07dccf1 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -241,6 +241,15 @@ function build() { done fi + + echo "" + echo "" + echo "" + echo "- test in Renode ($TITLE)" + echo "---------------------------------------------" + ./scripts/test-renode.sh || exit 1 + echo "=============================================" + # Save the resulting binaries into the prebuilt repo. The gateware # should always exist, but others might not. if [ -d "$PREBUILT_DIR" ]; then diff --git a/scripts/test-renode.sh b/scripts/test-renode.sh new file mode 100755 index 000000000..8f8261ea0 --- /dev/null +++ b/scripts/test-renode.sh @@ -0,0 +1,106 @@ +#!/bin/bash + +SCRIPT_SRC=$(realpath ${BASH_SOURCE[0]}) +SCRIPT_DIR=$(dirname $SCRIPT_SRC) +TOP_DIR=$(realpath $SCRIPT_DIR/..) +if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then + echo "You must run this script, rather then try to source it." + echo "$SCRIPT_SRC" + exit 1 +fi + +source $SCRIPT_DIR/build-common.sh + +init + +case $CPU in + vexriscv) + CPU_TYPE="VexRiscv" + ;; + picorv32) + CPU_TYPE="PicoRV32" + ;; + *) + echo "Simulating the current configuration is not supported in Renode yet - skipping the test" + exit 0 + ;; +esac + +if [ "$PLATFORM" == "mimas_a7" ] || [ "$PLATFORM" == "netv2" ] || [ "$PLATFORM" == "pano_logic_g2" ]; then + # the test load binaries into the flash to avoid using netboot on CI server + echo "$PLATFORM platform does not have flash memory - skipping the test" + exit 0 +fi + +if [ "$FIRMWARE" == "zephyr" ]; then + if [ "$PLATFORM" == "icebreaker" ]; then + # running Zephyr firmware directly from flash is not supported at the moment + # as it requires to enable XIP and include flash section in the DTS; + # TODO: add this in the future + echo "Running $FIRMWARE directly from flash is currently not supported - skipping the test" + exit 0 + fi +fi + +# Download prebuilt renode Release with new terminal tester support +conda install -c antmicro/label/test -c conda-forge renode=v1.8.2_with_new_terminal_tester +RENODE_BIN=$CONDA_PREFIX/bin/renode + +LITEX_CONFIG_FILE="$TARGET_BUILD_DIR/test/csr.csv" +if [ ! -f "$LITEX_CONFIG_FILE" ]; then + make firmware +fi + +RENODE_SCRIPTS_DIR="$TOP_DIR/$TARGET_BUILD_DIR/renode" +RENODE_RESC="$RENODE_SCRIPTS_DIR/litex_buildenv.resc" +RENODE_REPL="$RENODE_SCRIPTS_DIR/litex_buildenv.repl" + +mkdir -p $RENODE_SCRIPTS_DIR + +if [ "$FIRMWARE" == "linux" ]; then + python $TOP_DIR/third_party/litex-renode/generate-renode-scripts.py $LITEX_CONFIG_FILE \ + --repl "$RENODE_REPL" \ + --resc "$RENODE_RESC" \ + --bios-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/bios/bios.bin" \ + --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/linux/arch/riscv/boot/Image:kernel_image_flash_offset" \ + --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/linux/riscv32-rootfs.cpio:rootfs_image_flash_offset"\ + --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/linux/rv32.dtb:device_tree_image_flash_offset" \ + --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/emulator/emulator.bin:emulator_image_flash_offset" + +else + python $TOP_DIR/third_party/litex-renode/generate-renode-scripts.py $LITEX_CONFIG_FILE \ + --repl "$RENODE_REPL" \ + --resc "$RENODE_RESC" \ + --bios-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/bios/bios.bin" \ + --firmware-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/$FIRMWARE/firmware.bin" +fi + +OPT_RENODE_LOCATION=$TOP_DIR/build/conda/opt/renode +TESTS_LOCATION=$TOP_DIR/tests/renode + +cd $OPT_RENODE_LOCATION + +if [ "$FIRMWARE" == "stub" ]; then + # do not test the stub firmware + python tests/run_tests.py \ + --variable LITEX_SCRIPT:"$RENODE_RESC" \ + --variable CPU_TYPE:"$CPU_TYPE" \ + --robot-framework-remote-server-full-directory $OPT_RENODE_LOCATION/bin \ + $TESTS_LOCATION/BIOS.robot \ + || FAILED=1 +else + python tests/run_tests.py \ + --variable LITEX_SCRIPT:"$RENODE_RESC" \ + --variable CPU_TYPE:"$CPU_TYPE" \ + --robot-framework-remote-server-full-directory $OPT_RENODE_LOCATION/bin \ + $TESTS_LOCATION/BIOS.robot \ + $TESTS_LOCATION/Firmware-$FIRMWARE.robot \ + || FAILED=1 +fi + +if [ "$FAILED" == "1" ]; then + echo "+++ output +++" + cat tests/tests/robot_output.xml + exit 1 +fi + diff --git a/tests/renode/BIOS.robot b/tests/renode/BIOS.robot new file mode 100644 index 000000000..d71a289ee --- /dev/null +++ b/tests/renode/BIOS.robot @@ -0,0 +1,23 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Resource ${RENODEKEYWORDS} + +*** Test Cases *** +BIOS boots + [Documentation] Runs LiteX BIOS and verifies if the configuration info is printed on UART + + # the path to the resc file is passed by the test-renode.sh script + Execute Command include @${LITEX_SCRIPT} + + Create Terminal Tester sysbus.uart timeout=120 + + Start Emulation + + Wait For Line On Uart BIOS built on + Wait For Line On Uart BIOS CRC passed + + # CPU_TYPE variable is passed by the test-renode.sh script + Wait For Line On Uart CPU:\\s* ${CPU_TYPE} @ [0-9]+MHz treatAsRegex=true + diff --git a/tests/renode/Firmware-firmware.robot b/tests/renode/Firmware-firmware.robot new file mode 100644 index 000000000..1c7f9f6d6 --- /dev/null +++ b/tests/renode/Firmware-firmware.robot @@ -0,0 +1,28 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Resource ${RENODEKEYWORDS} + +*** Test Cases *** +Print help + [Documentation] Runs HDMI2USB Firmware and verifies if the user interface is responsive + + # the path to the resc file is passed by the test-renode.sh script + Execute Command include @${LITEX_SCRIPT} + + Create Terminal Tester sysbus.uart timeout=120 + + Start Emulation + + Wait For Line On Uart HDMI2USB firmware booting... + Wait For Prompt On Uart H2U${SPACE} + + Write line To Uart help + Wait For Line On Uart Available commands: + Wait For Line On Uart status commands + Wait For Line On Uart video_matrix commands + Wait For Line On Uart video_mode commands + Wait For Line On Uart change heartbeat status + Wait For Line On Uart debug commands + diff --git a/tests/renode/Firmware-linux.robot b/tests/renode/Firmware-linux.robot new file mode 100644 index 000000000..e18c20885 --- /dev/null +++ b/tests/renode/Firmware-linux.robot @@ -0,0 +1,29 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Resource ${RENODEKEYWORDS} + +*** Test Cases *** +Boot + [Documentation] Runs Linux and verifies that the shell is responsive + + # the path to the resc file is passed by the test-renode.sh script + Execute Command include @${LITEX_SCRIPT} + + Create Terminal Tester sysbus.uart timeout=120 + + Start Emulation + + Wait For Line On Uart Linux version 5.0.0 + Wait For Line On Uart Welcome to Buildroot + + Wait For Prompt On Uart buildroot login: + Write Line To Uart root + + Wait For Line On Uart login[48]: root login on 'hvc0' + Wait For Prompt On Uart \# + + Write Line To Uart ls / + Wait For Line On Uart etc + diff --git a/tests/renode/Firmware-micropython.robot b/tests/renode/Firmware-micropython.robot new file mode 100644 index 000000000..217b3bf61 --- /dev/null +++ b/tests/renode/Firmware-micropython.robot @@ -0,0 +1,24 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Resource ${RENODEKEYWORDS} + +*** Test Cases *** +Print help and version + [Documentation] Runs Micropython REPL and verifies if it is responsive + + # the path to the resc file is passed by the test-renode.sh script + Execute Command include @${LITEX_SCRIPT} + + Create Terminal Tester sysbus.uart timeout=120 + + Start Emulation + + Wait For Line On Uart MicroPython + Wait For Prompt On Uart >>> + + Write Line To Uart 2 + 3 + Wait For Line On Uart 5 + Wait For Prompt On Uart >>> + diff --git a/tests/renode/Firmware-zephyr.robot b/tests/renode/Firmware-zephyr.robot new file mode 100644 index 000000000..a1c43e0e5 --- /dev/null +++ b/tests/renode/Firmware-zephyr.robot @@ -0,0 +1,27 @@ +*** Settings *** +Suite Setup Setup +Suite Teardown Teardown +Test Setup Reset Emulation +Resource ${RENODEKEYWORDS} + +*** Test Cases *** +Print help and version + [Documentation] Runs Zephyr's shell sample and verifies if it is responsive + + # the path to the resc file is passed by the test-renode.sh script + Execute Command include @${LITEX_SCRIPT} + + Create Terminal Tester sysbus.uart timeout=240 + + Start Emulation + + Wait For Prompt On Uart uart:~$ + Write Line To Uart help + Wait For Line On Uart Please refer to shell documentation for more details. + + Wait For Prompt On Uart uart:~$ + Write Line To Uart version + Wait For Line On Uart Zephyr version + Wait For Prompt On Uart uart:~$ + + diff --git a/tests/renode/README.md b/tests/renode/README.md new file mode 100644 index 000000000..5e09a8314 --- /dev/null +++ b/tests/renode/README.md @@ -0,0 +1,72 @@ +# Testing LiteX Build Environment in Renode + +LiteX Build Environment comes with a set of test suites +verifying if the firmware runs correctly. + +The tests are written in Robot Framework +and are intended to be run using Renode simulator. + +They are located in `tests/renode` directory. +Each `.robot` file targets a selected firmware. + +The `scripts/test-renode.sh` script +is responsible for preparing the environment +and running the appropriate test suites +based on the current LiteX Build Environment +configuration. + +## CI integration + +Tests are run automatically in Travis CI. + +## Running tests manually + +In order to run tests locally execute +all the commands necessary to build the +firmware and then `scripts/test-renode.sh`, e.g.: + +``` bash +$ export CPU=vexriscv; export PLATFORM=arty; export FIRMWARE=micropython +$ ./scripts/download-env.sh +... +$ . ./scripts/enter-env.sh +... +$ ./scripts/build-micropython.sh +... +$ ./scripts/test-renode.sh +``` + +This will generate Renode platform/script, +select robot test suite targeting MicroPython +and run the test. + +## Tests results + +In the output of `scripts/test-renode.sh` you should find the following lines: + +``` +Preparing suites +Starting suites +Running tests/renode/BIOS.robot ++++++ Starting test 'BIOS.BIOS boots' ++++++ Finished test 'BIOS.BIOS boots' in 1.38 seconds with status OK +Finished tests/renode/BIOS.robot in 3.936288833618164 seconds +Running tests/renode/Firmware-micropython.robot ++++++ Starting test 'Firmware-micropython.Print help and version' ++++++ Finished test 'Firmware-micropython.Print help and version' in 52.33 seconds with status OK +Finished tests/renode/Firmware-micropython.robot in 52.60649251937866 seconds +Cleaning up suites +Aggregating all robot results +Output: build/conda/opt/renode/tests/tests/robot_output.xml +Log: build/conda/opt/renode/tests/tests/log.html +Report: build/conda/opt/renode/tests/tests/report.html +Tests finished successfully :) +``` + +As mentioned in the log, Robot Framework will generate +`robot_output.xml` with the details of the test execution +together with two human readable `html` files: `log` and `report`. + +In case of test failure, the script will print the content +of the `robot_output.xml` file to the standard output. +You should grep for `FAIL` or inspect the `log.html` file. From 224285859b857b0b72f5c1bc7d146c8a4e7ff9bc Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Wed, 12 Feb 2020 16:05:40 +0100 Subject: [PATCH 116/153] ci: Add micropython test --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 7ded96ae5..33d403c63 100644 --- a/.travis.yml +++ b/.travis.yml @@ -128,6 +128,7 @@ env: # MicroPython Targets #-------------------------------------------- # FIXME: Add some here + - C=vexriscv TC="vivado" P=arty T="base" F=micropython #-------------------------------------------- # Linux Targets #-------------------------------------------- From 26eddb77a014cbc633220d801a7d35d092cf7979 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Sat, 18 Apr 2020 14:53:29 +0200 Subject: [PATCH 117/153] build-linux: Fix running Linux 4adac90d in LiteX changed main_ram address for VexRiscv from 0xc0000000 to 0x40000000. This requires updating the DT file and building the VexRiscv emulator with different parameters. --- scripts/build-linux.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 56dcaf572..895c8e73c 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -71,7 +71,7 @@ elif [ ${CPU} = vexriscv ]; then ROOTFS_LOCATION="https://antmicro.com/projects/renode/litex-buildenv/" ROOTFS=${ARCH}32-rootfs.cpio ROOTFS_MD5="c3a88ff90fbd05dd6dc5773a8202d47f" - DTB_MD5="390c3ac4468810d4daa78379eb38dc1b" + DTB_MD5="2dc79321d1c5d4de45fbcb866ce816b1" CONFIG_MD5="fed2b661016e1b4aad16f17103839dba" else echo "Linux is only supported on mor1kx or vexriscv at the moment." @@ -169,11 +169,9 @@ if [ ${CPU} = vexriscv ]; then fi source $SCRIPT_DIR/build-common.sh - EMULATOR_RAM_BASE_ADDRESS=$(parse_generated_header "mem.h" EMULATOR_RAM_BASE) RAM_BASE_ADDRESS=$(parse_generated_header "mem.h" MAIN_RAM_BASE) # get rid of 'L' suffix RAM_BASE_ADDRESS=${RAM_BASE_ADDRESS::-1} - EMULATOR_RAM_BASE_ADDRESS=${EMULATOR_RAM_BASE_ADDRESS::-1} # this is a temp fix for building the emulator cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv @@ -182,7 +180,7 @@ if [ ${CPU} = vexriscv ]; then cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv/src/main/c/emulator # offsets are hardcoded in BIOS - export CFLAGS="-DDTB=$((RAM_BASE_ADDRESS + 0x01000000)) -Wl,--defsym,__ram_origin=$EMULATOR_RAM_BASE_ADDRESS" + export CFLAGS="-DOS_CALL=$((RAM_BASE_ADDRESS + 0x0)) -DDTB=$((RAM_BASE_ADDRESS + 0x01000000)) -Wl,--defsym,__ram_origin=$((RAM_BASE_ADDRESS + 0x01100000))" export LITEX_GENERATED="$TOP_DIR/$TARGET_BUILD_DIR/software/include" export LITEX_BASE="$TOP_DIR/third_party/litex" export RISCV_BIN="${CPU_ARCH}-elf-newlib-" @@ -279,7 +277,7 @@ else fetch_file $ROOTFS_LOCATION/litex_vexriscv_linux.config $CONFIG_MD5 $TARGET_LINUX_BUILD_DIR/.config - fetch_file $ROOTFS_LOCATION/rv32.dtb $DTB_MD5 $TARGET_LINUX_BUILD_DIR/rv32.dtb + fetch_file $ROOTFS_LOCATION/$DTB_MD5-rv32.dtb $DTB_MD5 $TARGET_LINUX_BUILD_DIR/rv32.dtb KERNEL_BINARY=Image make O="$TARGET_LINUX_BUILD_DIR" olddefconfig From 78ee1e26d53add79eefdf349d9be57616bfc843d Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 20 Apr 2020 13:31:12 +0200 Subject: [PATCH 118/153] targets: Remove unused emulator_ram memory segment After updating to the newer LiteX, emulator binary is located in the main ram and does not need a separate memory segment. x --- targets/arty/base.py | 7 ------- targets/atlys/base.py | 6 ------ targets/mimas_a7/base.py | 6 ------ targets/netv2/base.py | 6 ------ targets/opsis/base.py | 7 ------- targets/pano_logic_g2/base.py | 8 -------- targets/pipistrello/base.py | 6 ------ targets/saturn/base.py | 6 ------ targets/waxwing/net.py | 9 --------- 9 files changed, 61 deletions(-) diff --git a/targets/arty/base.py b/targets/arty/base.py index db63e3932..3950a92f8 100755 --- a/targets/arty/base.py +++ b/targets/arty/base.py @@ -18,7 +18,6 @@ class BaseSoC(SoCSDRAM): mem_map = {**SoCSDRAM.mem_map, **{ - 'emulator_ram': 0x20000000, 'spiflash': 0xd0000000 }} @@ -95,11 +94,5 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size define_flash_constants(self) - # Support for soft-emulation for full Linux support ---------------------------------------- - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - SoC = BaseSoC diff --git a/targets/atlys/base.py b/targets/atlys/base.py index 140f3d885..af3f60bef 100644 --- a/targets/atlys/base.py +++ b/targets/atlys/base.py @@ -96,11 +96,5 @@ def __init__(self, platform, **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size define_flash_constants(self) - # Support for soft-emulation for full Linux support ---------------------------------------- - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - SoC = BaseSoC diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index d7dddcd84..2fa0fead0 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -100,11 +100,5 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) - # Support for soft-emulation for full Linux support ---------------------------------------- - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - SoC = BaseSoC diff --git a/targets/netv2/base.py b/targets/netv2/base.py index d16017623..94abeb14d 100755 --- a/targets/netv2/base.py +++ b/targets/netv2/base.py @@ -99,7 +99,6 @@ class BaseSoC(SoCSDRAM): "main_ram": 0x40000000, "csr": 0xe0000000, "spiflash": 0x20000000, - "emulator_ram": 0x50000000, }} def __init__(self, platform, csr_data_width=8, **kwargs): @@ -119,11 +118,6 @@ def __init__(self, platform, csr_data_width=8, **kwargs): self.submodules.cas = cas.ControlAndStatus(platform, clk_freq) self.add_csr("cas") - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - bios_size = 0x8000 # sdram diff --git a/targets/opsis/base.py b/targets/opsis/base.py index fddb2b5d5..1e88b3917 100644 --- a/targets/opsis/base.py +++ b/targets/opsis/base.py @@ -54,7 +54,6 @@ def __init__(self, platform, clk_freq): class BaseSoC(SoCSDRAM): mem_map = {**SoCSDRAM.mem_map, **{ 'spiflash': 0x20000000, - "emulator_ram": 0x50000000, }} def __init__(self, platform, **kwargs): @@ -160,11 +159,5 @@ def __init__(self, platform, **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size define_flash_constants(self) - # Support for soft-emulation for full Linux support ---------------------------------------- - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - SoC = BaseSoC diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index b5f816757..1cdee6b56 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -20,7 +20,6 @@ class BaseSoC(SoCSDRAM): mem_map = {**SoCSDRAM.mem_map, **{ 'spiflash': 0x20000000, - 'emulator_ram': 0x50000000, }} def __init__(self, platform, **kwargs): @@ -80,11 +79,4 @@ def __init__(self, platform, **kwargs): ] - # Support for soft-emulation for full Linux support ---------------------------------------- - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - - SoC = BaseSoC diff --git a/targets/pipistrello/base.py b/targets/pipistrello/base.py index 14d04377d..29e179ff6 100644 --- a/targets/pipistrello/base.py +++ b/targets/pipistrello/base.py @@ -98,11 +98,5 @@ def __init__(self, platform, **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size define_flash_constants(self) - # Support for soft-emulation for full Linux support ---------------------------------------- - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - SoC = BaseSoC diff --git a/targets/saturn/base.py b/targets/saturn/base.py index ec16a1683..88acd576c 100644 --- a/targets/saturn/base.py +++ b/targets/saturn/base.py @@ -78,11 +78,5 @@ def __init__(self, platform, **kwargs): # Memory mapped SPI Flash ------------------------------------------------------------------ # TODO: Add SPI Flash support here. - # Support for soft-emulation for full Linux support ---------------------------------------- - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - SoC = BaseSoC diff --git a/targets/waxwing/net.py b/targets/waxwing/net.py index 20d7d5bdb..92f368be5 100755 --- a/targets/waxwing/net.py +++ b/targets/waxwing/net.py @@ -30,10 +30,6 @@ # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCSDRAM): - mem_map = {**SoCSDRAM.mem_map, **{ - "emulator_ram": 0x50000000, # (default shadow @0xd0000000) - }} - def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) @@ -43,11 +39,6 @@ def __init__(self, platform, **kwargs): self.submodules.crg = _CRG(platform, clk_freq) - if self.cpu_type == "vexriscv" and self.cpu_variant == "linux": - size = 0x4000 - self.submodules.emulator_ram = wishbone.SRAM(size) - self.register_mem("emulator_ram", self.mem_map["emulator_ram"], self.emulator_ram.bus, size) - # sdram if not self.integrated_main_ram_size: sdram_module = MT46H32M16(clk_freq, "1:2") From d3d2d0de695c9ca1ca8f9947500d7fe8ead10eba Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 20 Apr 2020 13:41:59 +0200 Subject: [PATCH 119/153] arty: Change SPI Flash mapping to 0x20000000 --- targets/arty/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/arty/base.py b/targets/arty/base.py index 3950a92f8..da8cbaa78 100755 --- a/targets/arty/base.py +++ b/targets/arty/base.py @@ -18,7 +18,7 @@ class BaseSoC(SoCSDRAM): mem_map = {**SoCSDRAM.mem_map, **{ - 'spiflash': 0xd0000000 + 'spiflash': 0x20000000 }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): From 233ea61476883b0ad5c519cd227cf2838c6954b7 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 20 Apr 2020 09:15:12 +0200 Subject: [PATCH 120/153] test-renode: Temporarily disable platforms not supported in Renode --- scripts/test-renode.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/test-renode.sh b/scripts/test-renode.sh index 8f8261ea0..f5f06005c 100755 --- a/scripts/test-renode.sh +++ b/scripts/test-renode.sh @@ -32,6 +32,12 @@ if [ "$PLATFORM" == "mimas_a7" ] || [ "$PLATFORM" == "netv2" ] || [ "$PLATFORM" exit 0 fi +if [ "$PLATFORM" == "ice40_hx8k_b_evn" ] || [ "$PLATFORM" == "tinyfpga_bx" ] || [ "$PLATFORM" == "icefun" ]; then + # TODO: remove after this is handled in Renode + echo "$PLATFORM has memory regions of size currently not supported in Renode - skipping the test" + exit 0 +fi + if [ "$FIRMWARE" == "zephyr" ]; then if [ "$PLATFORM" == "icebreaker" ]; then # running Zephyr firmware directly from flash is not supported at the moment From 92018c4ffc4bcc6fa85841d60f86d7a9155ce815 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Thu, 23 Apr 2020 07:48:35 -0700 Subject: [PATCH 121/153] Replaced add_wb_slave/add_memory_region with register_mem per review suggestion. --- targets/pano_logic_g2/base.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index c0cef8b52..01fc184f2 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -82,14 +82,8 @@ def __init__(self, platform, **kwargs): self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size) self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size) self.add_constant("SPIFLASH_TOTAL_SIZE", platform.spiflash_total_size) - self.add_wb_slave( - self.mem_map["spiflash"], - self.spiflash.bus, - platform.spiflash_total_size) - self.add_memory_region( - "spiflash", - self.mem_map["spiflash"], - platform.spiflash_total_size) + self.register_mem("spiflash", self.mem_map["spiflash"], + self.spiflash.bus, size=platform.spiflash_total_size) self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) self.add_constant("DEVICE_TREE_IMAGE_FLASH_OFFSET",0x00000000) From 1a11f51a5ba1e47584e0a3ddf68d98c56756b12c Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Fri, 24 Apr 2020 06:39:09 -0700 Subject: [PATCH 122/153] Add support for CPU_VARIANT to load.py. --- load.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/load.py b/load.py index 96823c2bf..084349e17 100755 --- a/load.py +++ b/load.py @@ -10,9 +10,16 @@ p = os.environ['PLATFORM'] t = os.environ['TARGET'] c = os.environ['CPU'] + try: + v = os.environ['CPU_VARIANT'] + v = "." + v + except: + v ="" + pass - fname = "build/{p}_{t}_{c}/gateware/top.bit".format( - p=p, t=t, c=c) + fname = "build/{p}_{t}_{c}{v}/gateware/top.bit".format( + p=p, t=t, c=c,v=v) + print("fname: ",fname) if prog == 'ise': from litex.build.xilinx import iMPACT From dc5a892a809da270a0ba899f61ab4ab1115db291 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Sat, 25 Apr 2020 15:46:04 -0700 Subject: [PATCH 123/153] Add image-flash, gateware-flash, etc support for pano_logic_g2 target. --- Makefile | 21 +++++++++- platforms/pano_logic_g2.py | 38 +++++++++++++++--- targets/pano_logic_g2/Makefile.mk | 35 +++++++++++----- targets/pano_logic_g2/base.py | 6 +-- .../bscan_spi_xc6slx100_pano.bit | Bin 0 -> 1056808 bytes .../bscan_spi_xc6slx150_pano.bit | Bin 0 -> 1177036 bytes 6 files changed, 78 insertions(+), 22 deletions(-) mode change 100644 => 100755 Makefile mode change 100644 => 100755 targets/pano_logic_g2/Makefile.mk create mode 100644 targets/pano_logic_g2/flash_proxies/bscan_spi_xc6slx100_pano.bit create mode 100644 targets/pano_logic_g2/flash_proxies/bscan_spi_xc6slx150_pano.bit diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index 878e7e445..e3ed6308c --- a/Makefile +++ b/Makefile @@ -207,8 +207,25 @@ ifeq ($(FIRMWARE),clear) OVERRIDE_FIRMWARE=--override-firmware=clear FIRMWARE_FBI= else +ifeq ($(FIRMWARE),linux) +# Linux Image component files - kernel+emulator+dts+rootfs +define fbi_rule +$(1): $(subst .fbi,,$(1)) +endef + +BUILDROOT_IMAGES = third_party/buildroot/output/images +KERNEL_FBI = $(BUILDROOT_IMAGES)/Image.fbi +ROOTFS_FBI = $(BUILDROOT_IMAGES)/rootfs.cpio.fbi +EMULATOR_FBI = $(TARGET_BUILD_DIR)/emulator/emulator.bin.fbi +DTB_FBI = $(FIRMWARE_DIR)/rv32.dtb.fbi +FIRMWARE_FBI = $(KERNEL_FBI) $(ROOTFS_FBI) $(EMULATOR_FBI) $(DTB_FBI) + +$(foreach file,$(FIRMWARE_FBI),$(eval $(call fbi_rule,$(file)))) +else OVERRIDE_FIRMWARE=--override-firmware=$(FIRMWARE_FILEBASE).fbi FIRMWARE_FBI=$(FIRMWARE_FILEBASE).fbi +$(FIRMWARE_FILEBASE).fbi: $(FIRMWARE_FILEBASE).bin +endif endif endif @@ -315,7 +332,7 @@ endif $(FIRMWARE_FILEBASE).bin: firmware-cmd @true -$(FIRMWARE_FILEBASE).fbi: $(FIRMWARE_FILEBASE).bin +%.fbi: % ifeq ($(CPU_ENDIANNESS), little) $(PYTHON) -m litex.soc.software.mkmscimg -f --little $< -o $@ else @@ -328,7 +345,7 @@ firmware: $(FIRMWARE_FILEBASE).bin firmware-load: firmware firmware-load-$(PLATFORM) @true -firmware-flash: firmware firmware-flash-$(PLATFORM) +firmware-flash: firmware $(FIRMWARE_FBI) firmware-flash-$(PLATFORM) @true firmware-flash-py: firmware diff --git a/platforms/pano_logic_g2.py b/platforms/pano_logic_g2.py index d25936215..790f297ba 100755 --- a/platforms/pano_logic_g2.py +++ b/platforms/pano_logic_g2.py @@ -3,7 +3,7 @@ # can be found here https://github.com/tomverbeure/panologic-g2 from litex.build.generic_platform import * -from litex.build.xilinx import XilinxPlatform, iMPACT +from litex.build.xilinx import XilinxPlatform, XC3SProg # IOs ---------------------------------------------------------------------------------------------- @@ -182,6 +182,20 @@ Subsignal("rx", Pins("C17"), IOStandard("LVCMOS33")) ) +# this is needed since make.py calls prog.set_flash_proxy_dir forcing +# proxys to be in ./third_party/flash_proxies but a special proxy is needed for +# the Pano logic device and it has not been accepted by https://github.com/quartiq/bscan_spi_bitstreams +# yet. + +class PanoXC3SProg(XC3SProg): + def __init__(self, cable, flash_proxy_basename=None, position=0): + super(PanoXC3SProg,self).__init__(cable, flash_proxy_basename, position) + + def flash(self, address, data_file): + proxy_dir = os.path.realpath("./targets/pano_logic_g2/flash_proxies") + super(PanoXC3SProg,self).set_flash_proxy_dir(proxy_dir) + super(PanoXC3SProg,self).flash(address, data_file) + # Platform ----------------------------------------------------------------------------------------- class Platform(XilinxPlatform): @@ -190,7 +204,7 @@ class Platform(XilinxPlatform): default_clk_period = 1e9/125e6 # actual .bit file size rounded up to next flash erase boundary - gateware_size = 0x420000 + gateware_size = 0x410000 # Micron M25P128 spiflash_model = "m25p128" @@ -198,9 +212,9 @@ class Platform(XilinxPlatform): spiflash_clock_div = 4 spiflash_total_size = int((128/8)*1024*1024) # 128Mbit/16Mbyte spiflash_page_size = 256 - spiflash_sector_size = 0x20000 + spiflash_sector_size = 0x40000 - def __init__(self, programmer="impact", device="xc6slx150", uart_connection="dvi"): + def __init__(self, programmer="xc3sprog", device="xc6slx150", uart_connection="dvi"): if uart_connection == 'dvi': _io.append(_dvi_serial) elif uart_connection == 'hdmi': @@ -208,7 +222,12 @@ def __init__(self, programmer="impact", device="xc6slx150", uart_connection="dvi else: raise ValueError("Unsupported uart_connection \"{}\", available \"dvi\", \"hdmi\"".format(uart_connection)) + if device != "xc6slx150" and device != "xc6slx100": + raise ValueError("Invalid device \"{}\"".format(device)) + self.device = device + XilinxPlatform.__init__(self, device+"-2-fgg484", _io) + self.toolchain.bitgen_opt += " -g Compress -g ConfigRate:26" self.programmer = programmer self.add_platform_command("""CONFIG VCCAUX="2.5";""") @@ -217,7 +236,14 @@ def do_finalize(self, fragment, *args, **kwargs): pass def create_programmer(self): - if self.programmer == "impact": - return iMPACT() + cable_type = os.getenv('CABLE',default='jtaghs2') + + if self.device == "xc6slx150-2-fgg484": + proxy = "bscan_spi_xc6slx150_pano.bit" + elif self.device == "xc6slx100-2-fgg484": + proxy = "bscan_spi_xc6slx100_pano.bit" + + if self.programmer == "xc3sprog": + return PanoXC3SProg(cable_type, proxy) else: raise ValueError("{} programmer is not supported".format(self.programmer)) diff --git a/targets/pano_logic_g2/Makefile.mk b/targets/pano_logic_g2/Makefile.mk old mode 100644 new mode 100755 index 14323af47..d8339e492 --- a/targets/pano_logic_g2/Makefile.mk +++ b/targets/pano_logic_g2/Makefile.mk @@ -12,26 +12,39 @@ COMM_PORT ?= /dev/ttyUSB0 BAUD ?= 115200 # Image -image-flash-$(PLATFORM): - @echo "Unsupported" - @false +image-flash-$(PLATFORM): gateware-flash-$(PLATFORM) firmware-flash-$(PLATFORM) # Gateware gateware-load-$(PLATFORM): - @echo "Unsupported" - @false + ./load.py ise -gateware-flash-$(PLATFORM): - @echo "Unsupported" - @false +GATEWARE_BIN = $(TARGET_BUILD_DIR)/gateware.bin + +$(GATEWARE_BIN): $(GATEWARE_FILEBASE).bin $(DTB_FBI) $(EMULATOR_FBI) + # note: emulator and DTB are flash with gateware to save flash space + dd if=$(GATEWARE_FILEBASE).bin of=$@ bs=4259840 conv=sync + dd if=$(DTB_FBI) bs=16K conv=sync >> $@ + cat $(EMULATOR_FBI) >> $@ + +gateware-flash-$(PLATFORM): $(GATEWARE_BIN) + # note: emulator and DTB are flash with gateware to save flash space + $(PYTHON) flash.py --mode=other --other-file $(GATEWARE_BIN) --address 0 + @true # Firmware firmware-load-$(PLATFORM): flterm --port=$(COMM_PORT) --kernel=$(FIRMWARE_FILEBASE).bin --speed=$(BAUD) -firmware-flash-$(PLATFORM): - @echo "Unsupported" - @false + +rootfs-flash-$(PLATFORM): + @echo "Flashing roots @ 0x9c0000" + $(PYTHON) flash.py --mode=other --other-file $(ROOTFS_FBI) --address 10223616 + +kernel-flash-$(PLATFORM): + @echo "Flashing kernel @ 0x440000" + $(PYTHON) flash.py --mode=other --other-file $(KERNEL_FBI) --address 4456448 + +firmware-flash-$(PLATFORM): kernel-flash-$(PLATFORM) rootfs-flash-$(PLATFORM) firmware-connect-$(PLATFORM): flterm --port=$(COMM_PORT) --speed=$(BAUD) diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index 01fc184f2..0ee760b77 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -87,9 +87,9 @@ def __init__(self, platform, **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) self.add_constant("DEVICE_TREE_IMAGE_FLASH_OFFSET",0x00000000) - self.add_constant("EMULATOR_IMAGE_FLASH_OFFSET",0x20000) - self.add_constant("KERNEL_IMAGE_FLASH_OFFSET",0x40000) - self.add_constant("ROOTFS_IMAGE_FLASH_OFFSET",0x5c0000) + self.add_constant("EMULATOR_IMAGE_FLASH_OFFSET",0x4000) + self.add_constant("KERNEL_IMAGE_FLASH_OFFSET",0x30000) + self.add_constant("ROOTFS_IMAGE_FLASH_OFFSET",0x5b0000) # Take Ethernet Phy out of reset for SYSCLK of 125 Mhz gmii_rst_n = platform.request("gmii_rst_n") diff --git a/targets/pano_logic_g2/flash_proxies/bscan_spi_xc6slx100_pano.bit b/targets/pano_logic_g2/flash_proxies/bscan_spi_xc6slx100_pano.bit new file mode 100644 index 0000000000000000000000000000000000000000..79035c6b75c33be14793c58cf901bb4c085a7792 GIT binary patch literal 1056808 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 zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg zfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7> z3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36A zpnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim} z0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7j zD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUgfC36Apnw7jD4>7>3Mim}0tzUg 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 z0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51< z1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc z7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf( zSik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?D zU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPq zfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b z0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q? zEMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}n zuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQ zzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI z0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51< z1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc z7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf( zSik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?D zU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPq zfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b z0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q? zEMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}n zuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQ zzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI z0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51< z1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc z7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf( zSik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?D zU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPq zfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b z0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q? zEMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}n zuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQ zzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI z0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51< z1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc z7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf( zSik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?D zU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPq zfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b z0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q? zEMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}n zuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQ zzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI z0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51< z1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc z7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf( zSik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?D zU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPq zfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b z0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q? zEMNf(Sik}nuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}n zuz&?DU;ztQzycPqfCVgI0Sj2b0v51<1uS3z3s}Gc7O;Q?EMNf(Sik}nuz&?DU;zs( z3w-;{@;`@biM7vve?H;wPoI|yYr8*pIbP4@?`y8~{Ni1HeK&sZzu^DH@2|K21JzgF z;oHym?-gST|^S8F@VkM-=@4}X5WywUvMYu`2h Y>)JnWepn0t>zC!Z`@gxwkNy4s0PN}ucK`qY literal 0 HcmV?d00001 From 47ca12003e49fda26d03cfdc2c4779940366379b Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Sun, 26 Apr 2020 20:17:51 -0700 Subject: [PATCH 124/153] Fix micro python build, add micro python support to pano_logic_g2. --- Makefile | 48 ++++++++++++++++++------------- platforms/pano_logic_g2.py | 9 ++++-- targets/pano_logic_g2/Makefile.mk | 21 ++++++++++++-- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index e3ed6308c..a4dbee9a8 100755 --- a/Makefile +++ b/Makefile @@ -207,26 +207,26 @@ ifeq ($(FIRMWARE),clear) OVERRIDE_FIRMWARE=--override-firmware=clear FIRMWARE_FBI= else -ifeq ($(FIRMWARE),linux) -# Linux Image component files - kernel+emulator+dts+rootfs -define fbi_rule -$(1): $(subst .fbi,,$(1)) -endef - -BUILDROOT_IMAGES = third_party/buildroot/output/images -KERNEL_FBI = $(BUILDROOT_IMAGES)/Image.fbi -ROOTFS_FBI = $(BUILDROOT_IMAGES)/rootfs.cpio.fbi -EMULATOR_FBI = $(TARGET_BUILD_DIR)/emulator/emulator.bin.fbi -DTB_FBI = $(FIRMWARE_DIR)/rv32.dtb.fbi -FIRMWARE_FBI = $(KERNEL_FBI) $(ROOTFS_FBI) $(EMULATOR_FBI) $(DTB_FBI) - -$(foreach file,$(FIRMWARE_FBI),$(eval $(call fbi_rule,$(file)))) -else OVERRIDE_FIRMWARE=--override-firmware=$(FIRMWARE_FILEBASE).fbi FIRMWARE_FBI=$(FIRMWARE_FILEBASE).fbi -$(FIRMWARE_FILEBASE).fbi: $(FIRMWARE_FILEBASE).bin endif endif + +ifeq ($(FIRMWARE),linux) +# Linux Image component files - kernel+emulator+dts+rootfs + define fbi_rule + $(1): $(subst .fbi,,$(1)) + endef + + OVERRIDE_FIRMWARE=--override-firmware=none + BUILDROOT_IMAGES = third_party/buildroot/output/images + KERNEL_FBI = $(BUILDROOT_IMAGES)/Image.fbi + ROOTFS_FBI = $(BUILDROOT_IMAGES)/rootfs.cpio.fbi + EMULATOR_FBI = $(TARGET_BUILD_DIR)/emulator/emulator.bin.fbi + DTB_FBI = $(FIRMWARE_DIR)/rv32.dtb.fbi + FIRMWARE_FBI = $(KERNEL_FBI) $(ROOTFS_FBI) $(EMULATOR_FBI) $(DTB_FBI) + + $(foreach file,$(FIRMWARE_FBI),$(eval $(call fbi_rule,$(file)))) endif $(IMAGE_FILE): $(GATEWARE_FILEBASE).bin $(BIOS_FILE) $(FIRMWARE_FBI) @@ -332,20 +332,28 @@ endif $(FIRMWARE_FILEBASE).bin: firmware-cmd @true -%.fbi: % + ifeq ($(CPU_ENDIANNESS), little) - $(PYTHON) -m litex.soc.software.mkmscimg -f --little $< -o $@ + MKMSCIMG = $(PYTHON) -m litex.soc.software.mkmscimg --little else - $(PYTHON) -m litex.soc.software.mkmscimg -f $< -o $@ + MKMSCIMG = $(PYTHON) -m litex.soc.software.mkmscimg endif +$(FIRMWARE_FILEBASE).fbi: $(FIRMWARE_FILEBASE).bin + @echo "making $< -> $@" + $(MKMSCIMG) -f $< -o $@ + +%.fbi: % + @echo "making $< -> $@" + $(MKMSCIMG) -f $< -o $@ + firmware: $(FIRMWARE_FILEBASE).bin @true firmware-load: firmware firmware-load-$(PLATFORM) @true -firmware-flash: firmware $(FIRMWARE_FBI) firmware-flash-$(PLATFORM) +firmware-flash: firmware firmware-flash-$(PLATFORM) @true firmware-flash-py: firmware diff --git a/platforms/pano_logic_g2.py b/platforms/pano_logic_g2.py index 790f297ba..1cf24a6e7 100755 --- a/platforms/pano_logic_g2.py +++ b/platforms/pano_logic_g2.py @@ -203,8 +203,13 @@ class Platform(XilinxPlatform): default_clk_name = "clk125" default_clk_period = 1e9/125e6 - # actual .bit file size rounded up to next flash erase boundary - gateware_size = 0x410000 + flavor = os.environ.get('FIRMWARE', 'firmware') + if flavor == 'linux': + # leave room for emulator and DTS file in the .bit file partition + gateware_size = 0x410000 + else: + # actual .bit file size rounded up to next flash erase boundary + gateware_size = 0x440000 # Micron M25P128 spiflash_model = "m25p128" diff --git a/targets/pano_logic_g2/Makefile.mk b/targets/pano_logic_g2/Makefile.mk index d8339e492..3212df484 100755 --- a/targets/pano_logic_g2/Makefile.mk +++ b/targets/pano_logic_g2/Makefile.mk @@ -18,7 +18,8 @@ image-flash-$(PLATFORM): gateware-flash-$(PLATFORM) firmware-flash-$(PLATFORM) gateware-load-$(PLATFORM): ./load.py ise -GATEWARE_BIN = $(TARGET_BUILD_DIR)/gateware.bin +ifeq ($(FIRMWARE),linux) +GATEWARE_BIN = $(TARGET_BUILD_DIR)/gateware+emulator+dtb.bin $(GATEWARE_BIN): $(GATEWARE_FILEBASE).bin $(DTB_FBI) $(EMULATOR_FBI) # note: emulator and DTB are flash with gateware to save flash space @@ -28,8 +29,12 @@ $(GATEWARE_BIN): $(GATEWARE_FILEBASE).bin $(DTB_FBI) $(EMULATOR_FBI) gateware-flash-$(PLATFORM): $(GATEWARE_BIN) # note: emulator and DTB are flash with gateware to save flash space + @echo "Flashing $(GATEWARE_BIN) @ 0x9c0000" $(PYTHON) flash.py --mode=other --other-file $(GATEWARE_BIN) --address 0 @true +else +gateware-flash-$(PLATFORM): gateware-flash-py +endif # Firmware firmware-load-$(PLATFORM): @@ -44,7 +49,19 @@ kernel-flash-$(PLATFORM): @echo "Flashing kernel @ 0x440000" $(PYTHON) flash.py --mode=other --other-file $(KERNEL_FBI) --address 4456448 -firmware-flash-$(PLATFORM): kernel-flash-$(PLATFORM) rootfs-flash-$(PLATFORM) +ifeq ($(FIRMWARE),linux) +firmware-flash-$(PLATFORM): $(FIRMWARE_FBI) kernel-flash-$(PLATFORM) rootfs-flash-$(PLATFORM) +else +ifeq ($(FIRMWARE),micropython) +MICROPYTHON_FBI = $(TARGET_BUILD_DIR)/software/micropython/firmware.fbi + +firmware-flash-$(PLATFORM): + @echo "Flashing micropython @ 0x440000" + $(PYTHON) flash.py --mode=other --other-file $(MICROPYTHON_FBI) --address 4456448 +else +firmware-flash-$(PLATFORM): firmware-flash-py +endif +endif firmware-connect-$(PLATFORM): flterm --port=$(COMM_PORT) --speed=$(BAUD) From 798c729d0f0cec10f18869244385b2ff9aa4d1c3 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Mon, 27 Apr 2020 07:14:22 -0700 Subject: [PATCH 125/153] Fix failed Linux builds on other targets. --- Makefile | 5 ++--- targets/pano_logic_g2/Makefile.mk | 6 +++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index a4dbee9a8..b4147614e 100755 --- a/Makefile +++ b/Makefile @@ -207,8 +207,8 @@ ifeq ($(FIRMWARE),clear) OVERRIDE_FIRMWARE=--override-firmware=clear FIRMWARE_FBI= else -OVERRIDE_FIRMWARE=--override-firmware=$(FIRMWARE_FILEBASE).fbi -FIRMWARE_FBI=$(FIRMWARE_FILEBASE).fbi +OVERRIDE_FIRMWARE?=--override-firmware=$(FIRMWARE_FILEBASE).fbi +FIRMWARE_FBI?=$(FIRMWARE_FILEBASE).fbi endif endif @@ -218,7 +218,6 @@ ifeq ($(FIRMWARE),linux) $(1): $(subst .fbi,,$(1)) endef - OVERRIDE_FIRMWARE=--override-firmware=none BUILDROOT_IMAGES = third_party/buildroot/output/images KERNEL_FBI = $(BUILDROOT_IMAGES)/Image.fbi ROOTFS_FBI = $(BUILDROOT_IMAGES)/rootfs.cpio.fbi diff --git a/targets/pano_logic_g2/Makefile.mk b/targets/pano_logic_g2/Makefile.mk index 3212df484..ba729d94c 100755 --- a/targets/pano_logic_g2/Makefile.mk +++ b/targets/pano_logic_g2/Makefile.mk @@ -11,6 +11,10 @@ TARGET ?= $(DEFAULT_TARGET) COMM_PORT ?= /dev/ttyUSB0 BAUD ?= 115200 +ifeq ($(FIRMWARE),linux) +OVERRIDE_FIRMWARE=--override-firmware=none +endif + # Image image-flash-$(PLATFORM): gateware-flash-$(PLATFORM) firmware-flash-$(PLATFORM) @@ -55,7 +59,7 @@ else ifeq ($(FIRMWARE),micropython) MICROPYTHON_FBI = $(TARGET_BUILD_DIR)/software/micropython/firmware.fbi -firmware-flash-$(PLATFORM): +firmware-flash-$(PLATFORM): @echo "Flashing micropython @ 0x440000" $(PYTHON) flash.py --mode=other --other-file $(MICROPYTHON_FBI) --address 4456448 else From d793dd8ae3c24ab6de985eabf5c8139fff1c65ab Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Mon, 4 May 2020 14:53:58 -0700 Subject: [PATCH 126/153] Fix errors when scripts are called by Makefile, apply patches only once. --- scripts/build-common.sh | 2 +- scripts/build-linux.sh | 7 +++++-- scripts/build-micropython.sh | 2 +- scripts/build-zephyr.sh | 2 +- scripts/download-env.sh | 4 +++- scripts/download-prebuilt.sh | 2 +- scripts/enter-env.sh | 2 +- 7 files changed, 13 insertions(+), 8 deletions(-) mode change 100644 => 100755 scripts/build-common.sh diff --git a/scripts/build-common.sh b/scripts/build-common.sh old mode 100644 new mode 100755 index ee6a55b2c..6f7fd7c7c --- a/scripts/build-common.sh +++ b/scripts/build-common.sh @@ -13,7 +13,7 @@ function init { fi # Imports TARGET, PLATFORM, CPU and TARGET_BUILD_DIR from Makefile - eval $(make env) + eval $(make --silent env) make info source $SCRIPT_DIR/settings.sh diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 895c8e73c..ef9cf5db9 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -27,7 +27,7 @@ if [ -z "$HDMI2USB_ENV" ]; then fi # Imports TARGET, PLATFORM, CPU and TARGET_BUILD_DIR from Makefile -eval $(make env) +eval $(make --silent env) make info set -x @@ -175,7 +175,10 @@ if [ ${CPU} = vexriscv ]; then # this is a temp fix for building the emulator cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv - git am $TOP_DIR/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch + if [ ! -e .patched ]; then + git am $TOP_DIR/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch + touch .patched + fi cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv/src/main/c/emulator diff --git a/scripts/build-micropython.sh b/scripts/build-micropython.sh index 39562053a..9f86f8556 100755 --- a/scripts/build-micropython.sh +++ b/scripts/build-micropython.sh @@ -27,7 +27,7 @@ if [ -z "$HDMI2USB_ENV" ]; then fi # Imports TARGET, PLATFORM, CPU and TARGET_BUILD_DIR from Makefile -eval $(make env) +eval $(make --silent env) make info set -x diff --git a/scripts/build-zephyr.sh b/scripts/build-zephyr.sh index f05903425..c87046ade 100755 --- a/scripts/build-zephyr.sh +++ b/scripts/build-zephyr.sh @@ -27,7 +27,7 @@ if [ -z "$HDMI2USB_ENV" ]; then fi # Imports TARGET, PLATFORM, CPU and TARGET_BUILD_DIR from Makefile -eval $(make env) +eval $(make --silent env) make info source $SCRIPT_DIR/settings.sh diff --git a/scripts/download-env.sh b/scripts/download-env.sh index 855e8c18e..bce6c62cc 100755 --- a/scripts/download-env.sh +++ b/scripts/download-env.sh @@ -274,7 +274,7 @@ export PATH=$CONDA_DIR/bin:$PATH:/sbin conda info ) -eval $(cd $TOP_DIR; export HDMI2USB_ENV=1; make env || exit 1) || exit 1 +eval $(cd $TOP_DIR; export HDMI2USB_ENV=1; make --silent env || exit 1) || exit 1 ( cd $TOP_DIR export HDMI2USB_ENV=1 @@ -699,3 +699,5 @@ echo "-----------------------" echo "" echo "Completed. To load environment:" echo "source $SETUP_DIR/enter-env.sh" +# Set a flag indicating successfully script completion +touch ${BUILD_DIR}/.env_downloaded diff --git a/scripts/download-prebuilt.sh b/scripts/download-prebuilt.sh index 859ae48ea..92f383f30 100755 --- a/scripts/download-prebuilt.sh +++ b/scripts/download-prebuilt.sh @@ -27,7 +27,7 @@ if [ -z "$HDMI2USB_ENV" ]; then fi # Imports TARGET, PLATFORM, CPU and TARGET_BUILD_DIR from Makefile -eval $(make env) +eval $(make --silent env) if [ -d $TARGET_BUILD_DIR ]; then echo "Build directory '$TARGET_BUILD_DIR' already exists." diff --git a/scripts/enter-env.sh b/scripts/enter-env.sh index fea96839b..de0e3b509 100755 --- a/scripts/enter-env.sh +++ b/scripts/enter-env.sh @@ -197,7 +197,7 @@ export PYTHONNOUSERSITE=1 # Install and setup conda for downloading packages export PATH=$CONDA_DIR/bin:$PATH:/sbin -eval $(cd $TOP_DIR; export HDMI2USB_ENV=1; make env || exit 1) || return 1 +eval $(cd $TOP_DIR; export HDMI2USB_ENV=1; make --silent env || exit 1) || return 1 ( cd $TOP_DIR export HDMI2USB_ENV=1 From 626c9ff3ce85bbda4d67f4106c51a13fb405da57 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Tue, 12 May 2020 19:06:13 -0700 Subject: [PATCH 127/153] Moved Linux specific changes from top level Makefile to target specific .mk. --- Makefile | 20 ++------------------ targets/pano_logic_g2/Makefile.mk | 30 +++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index b4147614e..8cd32f301 100755 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ ifeq ($(shell [ $(JOBS) -gt 1 ] && echo true),true) export MAKEFLAGS="-j $(JOBS) -l $(JOBS)" endif -TARGET_BUILD_DIR = build/$(FULL_PLATFORM)_$(TARGET)_$(FULL_CPU)/ +TARGET_BUILD_DIR = build/$(FULL_PLATFORM)_$(TARGET)_$(FULL_CPU) GATEWARE_FILEBASE = $(TARGET_BUILD_DIR)/gateware/top BIOS_FILE = $(TARGET_BUILD_DIR)/software/bios/bios.bin @@ -212,22 +212,6 @@ FIRMWARE_FBI?=$(FIRMWARE_FILEBASE).fbi endif endif -ifeq ($(FIRMWARE),linux) -# Linux Image component files - kernel+emulator+dts+rootfs - define fbi_rule - $(1): $(subst .fbi,,$(1)) - endef - - BUILDROOT_IMAGES = third_party/buildroot/output/images - KERNEL_FBI = $(BUILDROOT_IMAGES)/Image.fbi - ROOTFS_FBI = $(BUILDROOT_IMAGES)/rootfs.cpio.fbi - EMULATOR_FBI = $(TARGET_BUILD_DIR)/emulator/emulator.bin.fbi - DTB_FBI = $(FIRMWARE_DIR)/rv32.dtb.fbi - FIRMWARE_FBI = $(KERNEL_FBI) $(ROOTFS_FBI) $(EMULATOR_FBI) $(DTB_FBI) - - $(foreach file,$(FIRMWARE_FBI),$(eval $(call fbi_rule,$(file)))) -endif - $(IMAGE_FILE): $(GATEWARE_FILEBASE).bin $(BIOS_FILE) $(FIRMWARE_FBI) $(PYTHON) mkimage.py \ $(MISOC_EXTRA_CMDLINE) $(LITEX_EXTRA_CMDLINE) $(MAKE_LITEX_EXTRA_CMDLINE) \ @@ -352,7 +336,7 @@ firmware: $(FIRMWARE_FILEBASE).bin firmware-load: firmware firmware-load-$(PLATFORM) @true -firmware-flash: firmware firmware-flash-$(PLATFORM) +firmware-flash: firmware $(FIRMWARE_FBI) firmware-flash-$(PLATFORM) @true firmware-flash-py: firmware diff --git a/targets/pano_logic_g2/Makefile.mk b/targets/pano_logic_g2/Makefile.mk index ba729d94c..816e20923 100755 --- a/targets/pano_logic_g2/Makefile.mk +++ b/targets/pano_logic_g2/Makefile.mk @@ -12,7 +12,24 @@ COMM_PORT ?= /dev/ttyUSB0 BAUD ?= 115200 ifeq ($(FIRMWARE),linux) + + OVERRIDE_FIRMWARE=--override-firmware=none +define fbi_rule +$(1): $(subst .fbi,,$(1)) +endef + +TARGET_BUILD_DIR = build/$(FULL_PLATFORM)_$(TARGET)_$(FULL_CPU) +FIRMWARE_DIR = $(TARGET_BUILD_DIR)/software/$(FIRMWARE) + +BUILDROOT_IMAGES = third_party/buildroot/output/images +KERNEL_FBI = $(BUILDROOT_IMAGES)/Image.fbi +ROOTFS_FBI = $(BUILDROOT_IMAGES)/rootfs.cpio.fbi +EMULATOR_FBI = $(TARGET_BUILD_DIR)/emulator/emulator.bin.fbi +DTB_FBI = $(FIRMWARE_DIR)/rv32.dtb.fbi +FIRMWARE_FBI = $(KERNEL_FBI) $(ROOTFS_FBI) $(EMULATOR_FBI) $(DTB_FBI) + +$(foreach file,$(FIRMWARE_FBI),$(eval $(call fbi_rule,$(file)))) endif # Image @@ -26,15 +43,17 @@ ifeq ($(FIRMWARE),linux) GATEWARE_BIN = $(TARGET_BUILD_DIR)/gateware+emulator+dtb.bin $(GATEWARE_BIN): $(GATEWARE_FILEBASE).bin $(DTB_FBI) $(EMULATOR_FBI) - # note: emulator and DTB are flash with gateware to save flash space + # note: emulator and DTB are flashed with gateware to save flash space dd if=$(GATEWARE_FILEBASE).bin of=$@ bs=4259840 conv=sync dd if=$(DTB_FBI) bs=16K conv=sync >> $@ cat $(EMULATOR_FBI) >> $@ +# note: emulator and DTB are flashed with gateware to save flash space gateware-flash-$(PLATFORM): $(GATEWARE_BIN) - # note: emulator and DTB are flash with gateware to save flash space - @echo "Flashing $(GATEWARE_BIN) @ 0x9c0000" +ifeq ($(DUMMY_FLASH),) + @echo "Flashing $(notdir( $(GATEWARE_BIN))) @ 0" $(PYTHON) flash.py --mode=other --other-file $(GATEWARE_BIN) --address 0 +endif @true else gateware-flash-$(PLATFORM): gateware-flash-py @@ -46,12 +65,16 @@ firmware-load-$(PLATFORM): rootfs-flash-$(PLATFORM): +ifeq ($(DUMMY_FLASH),) @echo "Flashing roots @ 0x9c0000" $(PYTHON) flash.py --mode=other --other-file $(ROOTFS_FBI) --address 10223616 +endif kernel-flash-$(PLATFORM): +ifeq ($(DUMMY_FLASH),) @echo "Flashing kernel @ 0x440000" $(PYTHON) flash.py --mode=other --other-file $(KERNEL_FBI) --address 4456448 +endif ifeq ($(FIRMWARE),linux) firmware-flash-$(PLATFORM): $(FIRMWARE_FBI) kernel-flash-$(PLATFORM) rootfs-flash-$(PLATFORM) @@ -82,3 +105,4 @@ help-$(PLATFORM): reset-$(PLATFORM): @echo "Unsupported" @false + From a1a0f6bf4890ddedf30fdd629c495c0a82b4c23c Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Tue, 12 May 2020 19:32:36 -0700 Subject: [PATCH 128/153] Optionally allow checkout commits and BR2_EXTERNAL to be specified. --- scripts/build-linux.sh | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index ef9cf5db9..4a3b6feab 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -235,6 +235,10 @@ if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT:-0} = 1 ]; then cd $(dirname $BD_SRC) echo "Downloading Buildroot code." git clone $BD_REMOTE $BD_SRC + cd $BD_SRC + if [ x$BD_COMMIT != x ]; then + git checkout $BD_COMMIT + fi ) fi @@ -243,6 +247,9 @@ if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT:-0} = 1 ]; then cd $(dirname $LLV_SRC) echo "Downloading Linux on LiteX-VexRiscv code." git clone $LLV_REMOTE $LLV_SRC + if [ x$LLV_COMMIT != x ]; then + (cd $LLV_SRC; git checkout $LLV_COMMIT) + fi ) fi @@ -258,7 +265,11 @@ if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT:-0} = 1 ]; then dtc -I dts -O dtb -o $TARGET_LINUX_BUILD_DIR/rv32.dtb $TARGET_LINUX_BUILD_DIR/rv32.dts cd $BD_SRC - make BR2_EXTERNAL=$LLV_SRC/buildroot/ litex_vexriscv_defconfig + if [ "x$BR2_EXTERNAL" = "x" ]; then + make BR2_EXTERNAL=$LLV_SRC/buildroot/ litex_vexriscv_defconfig + else + make litex_vexriscv_defconfig + fi time make ls -l $BD_SRC/output/images/ ln -sf $BD_SRC/output/images/Image $TOP_DIR/$FIRMWARE_FILEBASE.bin From db0b3de2a23d7464531e61cc52fd5bd0fac2daf2 Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Thu, 14 May 2020 10:35:34 -0700 Subject: [PATCH 129/153] Incorporate review comments. --- scripts/build-linux.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 4a3b6feab..16db2e0ec 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -235,9 +235,8 @@ if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT:-0} = 1 ]; then cd $(dirname $BD_SRC) echo "Downloading Buildroot code." git clone $BD_REMOTE $BD_SRC - cd $BD_SRC if [ x$BD_COMMIT != x ]; then - git checkout $BD_COMMIT + (cd $BD_SRC; git checkout $BD_COMMIT) fi ) fi @@ -265,10 +264,10 @@ if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT:-0} = 1 ]; then dtc -I dts -O dtb -o $TARGET_LINUX_BUILD_DIR/rv32.dtb $TARGET_LINUX_BUILD_DIR/rv32.dts cd $BD_SRC - if [ "x$BR2_EXTERNAL" = "x" ]; then - make BR2_EXTERNAL=$LLV_SRC/buildroot/ litex_vexriscv_defconfig - else + if [ "$(bash -c 'echo ${x$BR2_EXTERNAL}')" ]; then make litex_vexriscv_defconfig + else + make BR2_EXTERNAL=$LLV_SRC/buildroot/ litex_vexriscv_defconfig fi time make ls -l $BD_SRC/output/images/ From 1c7e6c041d6ff339745214738b1869a354ae8b7e Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Thu, 14 May 2020 11:18:00 -0700 Subject: [PATCH 130/153] Incorporate review comments. --- targets/pano_logic_g2/Makefile.mk | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/targets/pano_logic_g2/Makefile.mk b/targets/pano_logic_g2/Makefile.mk index 816e20923..c4cfec662 100755 --- a/targets/pano_logic_g2/Makefile.mk +++ b/targets/pano_logic_g2/Makefile.mk @@ -22,9 +22,8 @@ endef TARGET_BUILD_DIR = build/$(FULL_PLATFORM)_$(TARGET)_$(FULL_CPU) FIRMWARE_DIR = $(TARGET_BUILD_DIR)/software/$(FIRMWARE) -BUILDROOT_IMAGES = third_party/buildroot/output/images -KERNEL_FBI = $(BUILDROOT_IMAGES)/Image.fbi -ROOTFS_FBI = $(BUILDROOT_IMAGES)/rootfs.cpio.fbi +KERNEL_FBI = $(FIRMWARE_DIR)/firmware.bin.fbi +ROOTFS_FBI = $(FIRMWARE_DIR)/riscv32-rootfs.cpio.fbi EMULATOR_FBI = $(TARGET_BUILD_DIR)/emulator/emulator.bin.fbi DTB_FBI = $(FIRMWARE_DIR)/rv32.dtb.fbi FIRMWARE_FBI = $(KERNEL_FBI) $(ROOTFS_FBI) $(EMULATOR_FBI) $(DTB_FBI) @@ -42,8 +41,8 @@ gateware-load-$(PLATFORM): ifeq ($(FIRMWARE),linux) GATEWARE_BIN = $(TARGET_BUILD_DIR)/gateware+emulator+dtb.bin +# note: emulator and DTB are flashed with gateware to save flash space $(GATEWARE_BIN): $(GATEWARE_FILEBASE).bin $(DTB_FBI) $(EMULATOR_FBI) - # note: emulator and DTB are flashed with gateware to save flash space dd if=$(GATEWARE_FILEBASE).bin of=$@ bs=4259840 conv=sync dd if=$(DTB_FBI) bs=16K conv=sync >> $@ cat $(EMULATOR_FBI) >> $@ From ff7e47a980cce5d1241a3a314956156cace3856a Mon Sep 17 00:00:00 2001 From: Skip Hansen Date: Fri, 15 May 2020 07:04:24 -0700 Subject: [PATCH 131/153] Incorporate more review comments. --- scripts/build-linux.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 16db2e0ec..0ac712769 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -264,11 +264,7 @@ if [ ${CPU} = vexriscv ] && [ ${BUILD_BUILDROOT:-0} = 1 ]; then dtc -I dts -O dtb -o $TARGET_LINUX_BUILD_DIR/rv32.dtb $TARGET_LINUX_BUILD_DIR/rv32.dts cd $BD_SRC - if [ "$(bash -c 'echo ${x$BR2_EXTERNAL}')" ]; then - make litex_vexriscv_defconfig - else - make BR2_EXTERNAL=$LLV_SRC/buildroot/ litex_vexriscv_defconfig - fi + make BR2_EXTERNAL=${BR2_EXTERNAL:-$LLV_SRC/buildroot} litex_vexriscv_defconfig time make ls -l $BD_SRC/output/images/ ln -sf $BD_SRC/output/images/Image $TOP_DIR/$FIRMWARE_FILEBASE.bin From 6e053cf2800fc3bc074d63abfc370054f2557748 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 29 Jun 2020 17:46:07 +0200 Subject: [PATCH 132/153] Updating submodules. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * litedram changed from de55a8e to 9044c10 * 9044c10 - phy/ecp5ddrphy: use sys_rst instead of sys2x_rst as reset on primitives and do sys2x reset externally. * fa7d91a - phy/ecp5: simplify/fix dqs_oe/dq_oe and revert BitSlip on dq_i_data. * 8c112c7 - Merge pull request #207 from ozbenh/sim-autoinit |\ | * 4580882 - dfii: Really default to HW control |/ * 52d7dbe - frontend/fifo: make sure FIFO is only used on LiteDRAMNativePort, expose writer/reader fifo depth, add separators and update copyrights. * c4c8803 - Merge pull request #204 from antmicro/jboc/spd-read |\ | * 863c45a - test/spd_data: add missing files to tracking | * cbd9087 - modules/spd: select tFAW_min_ck depending on page size | * a8f2c04 - modules: add DDR4SPDData parser * | 067e8a5 - Merge pull request #205 from antmicro/jboc/fifo |\ \ | * | e5179eb - gen: fix LiteDRAMFIFO parameters | * | 8fedc3f - frontend/fifo: increase FIFO level after data has actually been written |/ / * | 992f80c - litedram_gen: add Ultrascale(+) support and KCU105 config file, remove cmd_delay on 7-series (not automatically calibrated). * | 361d250 - litedram_gen: avoid second S7PLL for iodelay clk, generate it from main S7PLL on CLKOUT0 (with fractional divide). * | 1b56dcf - litedram_gen: add more memtype asserts, remove csr_alignment (now fixed to 32-bit). * | a595fe0 - dfii: simplify control using CSRFields. * | 899462c - Merge pull request #202 from ozbenh/sim-autoinit |\ \ | * | f3f89ed - Default to HW control for sim * | | d62fd24 - Merge pull request #201 from antmicro/jboc/spd-read |\ \ \ | |/ / |/| / | |/ | * 4233f86 - modules/spd: save SPD data in SDRAMModule to allow for runtime verification * | f23cb80 - litedram_gen: revert builder.build(..., regular_comb=False). * | d1db115 - litedram_gen: review/simplify #197. * | a8e281f - Merge pull request #197 from ozbenh/standalone-sim |\ \ | * | d0f0c94 - phy/model: Don't generate empty mem_*.init files | * | b8d6da5 - gen: Allow generation of a standalone sim model * | | 83b9a1d - Merge pull request #199 from antmicro/jboc/spd-read |\ \ \ | |/ / |/| / | |/ | * cbe91bc - modules: add function for parsing SPD EEPROM dumps from BIOS firmware * | 639a31f - test/test_timing: update test_txxd_controller. * | 3c1ab76 - litedram/common/tXXDController: only set reset to 1 when txxd is None. |/ * e95af3f - Merge pull request #195 from enjoy-digital/bios-libs |\ | * fe48a92 - test/reference: update. | * c30910a - init: generate DFII_CONTROL flags in sdram_phy.h instead of defining them in the BIOS. |/ * 5078b19 - core/crossbar: remove retro-compat > 6 months old. * 3b105d5 - modules: fix SDRAMRegisteredModule. * b2a5685 - Merge pull request #189 from daveshah1/ddr4_rdimm_init |\ | * 70054ba - Add support for DDR4 RDIMMs * | 7ae4ad5 - modules: add SDR/DDR/DDR2/DDR3/DDR4 SDRAMModule (and Registered versions). * | 1f7d9eb - litedram_gen: pass FPGA speedgrade to iodelay_pll. * | f4871b9 - litedram_gen: use default settings on wb_bus. * | 6fb8396 - litedram_gen: remove csr_base (no longer needed since CPUNone type will automatically set csr mapping to 0x00000000) and create a use bus with the same address_width as the main bus of the SoC. * | 94c215e - litedram_gen: review/simplify #193, always add ddrctrl. * | f036ec2 - Merge pull request #193 from ozbenh/standalone-cores |\ \ | * | 04717b4 - gen: Rename standalone core wishbone | * | b0838f7 - gen: Add option to specify CSR alignment | * | d5a03b3 - gen: Add option to generate DDRCTL on standalone cores | * | efad6b3 - gen: Add option to specify CSR base for standalone cores | * | c91cbb5 - gen: Remove obsolete bus_expose config option |/ / * | 4e539ad - litedram_gen: switch to SoCCore. * | ac33d29 - litedram_gen: simplify and expose bus when CPU is set to None. * | fe47838 - litedram_gen: expose a Bus Slave port instead of a CSR port. * | 52b49fb - test/reference: update. * | 52ca393 - modules: add MT41J512M16/MT41K512M16. * | 589957f - phy: extend Bitslip capability to 2 sys_clk cycles. * | 5c0231d - common/BitSlip: add cycles parameter to extend bitstlip to multiple system clock cycles. * | ed0810a - gen: Optionally pass cpu_variant from YAML to SoC |/ * dfe6f90 - Merge pull request #188 from daveshah1/ddr4_dimm_x4 |\ | * 5b4381b - usddrphy: Support for x4 chip based DIMMs * | 9f136c0 - Merge pull request #187 from daveshah1/add_MTA18ASF2G72PZ |\ \ | |/ |/| | * 97f0a37 - modules: Add MTA18ASF2G72PZ DDR4 RDIMM |/ * 9a2d3f0 - common: add PHYPadsReducer to only use specific DRAM modules. * 20a849c - test/reference: update ddr4_init.h * cec3a99 - Merge pull request #181 from antmicro/jboc/eeprom-timings |\ | * 312bce2 - modules: pass rate automatically when creating module from SPD data | * 07bbd79 - modules: update existsing SO-DIMM timings based on SPD data | * cf83ac6 - test: improve SPD tests of Micron DDR3 SO-DIMM modules | * 854a614 - modules: fix calculations of speedgrade from tck in SPD data | * c744204 - modules: fix nrows in MT8KTF51264 | * 3980e06 - modules: add option to load module parameters from SPD data * | 48c2fc2 - phy: simplify/improve dqs preamble/postamble. * | eaf0691 - phy/ecp5ddrphy: simplify, working with dqs preamble/postamble. * | 12a017f - phy/ecp5ddrphy: simplify/cleanup. * | 62915cd - phy: rework BitSlip to simplify integration, add DQSPattern module. * | 9ff9e82 - phy/usddrphy: move pads.ten control to control block. * | 91a9a2a - phy/ecp5ddrphy: fix dqs preamble/postamble control. (make it similar to 7-series/Ultrascale). * | 5d29686 - phy/s7ddrphy/usddrphy: more compact write dqs postamble/preamble control path. * | 8d0e7f6 - phy/usddrphy: simplify/cleanup write control path/dqs postamble/preamble control path. * | 57b16c2 - phy/usddrphy: simplify/cleanup write control path, add DQS Pre/Postamble support. * | 1462a43 - phy/usddrphy: cleanup/simplify read control path. * | cd671f9 - phy/s7ddrphy: cleanup/simplify read control path. * | d061e60 - test/reference: update. * | 45a03df - phy/init: add phytype to PhySettings and export more parameters to C header to simplify software. * | 2df9004 - init: improve ident. * | eca7fc2 - phy/ecp5ddrphy: remove Bitslip from comment (no longer present). * | f4f2948 - phy/ecpddrphy: remove Bitslip (not used and redundant with dqs_read) and use BitSlip software control to move dqs_read. * | e2b4c2b - phy/ecp5ddrphy: cosmetics. |/ * f68f1dd - phy/ecp5ddrphy/control: cleanup/simplify and document (no functional changes). * fdf7c76 - phy/control: cleanup/simplify (no functional changes). * a767618 - phy: improve flow control readability (add separators between Read/Write/Write DQS Postamble/Preamble parts). * liteeth changed from 705003e to dbe15f1 * dbe15f1 - Merge pull request #42 from shuffle2/padding |\ | * d66d302 - mac padding: fix counter reset value |/ * b1bcfb2 - mac/LiteEthMACCoreCrossbar: remove unnecessary fifos. * 8e11857 - common: remove Port.connect and use 2 separate Record.connect. * 17caf17 - mac/LiteEthMACCoreCrossbar: remove cpu_dw. * 23b420a - mac/LiteEthMAC: simplify hybrid mode and avoid some duplication. * 51cd546 - core/mac: add missing separators, fix typos. * 59d3336 - mac: add separators, improve indent, minor simplifications. * d06c7b4 - frontend: add separators, improve indent, minor simplifications. * 2d58f48 - core: improve indent. * c262818 - core: add separators. * bb29706 - core: remove mac retro-compatibility (>6 months old). * 0feed17 - phy/gmii/CRG: add BUFG on RX and do the TX clock Mux with combinatorial logic (from @skiphansen initial work). * 53c9eb9 - core/ip: move mcase_oui/ip_mask definition to common and set target_mac with NextValue. * 58e1681 - Merge pull request #41 from shuffle2/mcast |\ | * 6d00ec1 - iptx: support multicast mac and bypass arp table * | 8afdec9 - phy/ecp5rgmii: review/simplify inband_status integration. * | 55af430 - Merge pull request #40 from shuffle2/master |\ \ | |/ |/| | * 26c4e41 - ecp5rgmii: enable reading inband PHY_status |/ * dc67e6d - phy/ecp5rgmii: use DDROutput/DDRInput now available for ECP5. * litepcie changed from 586ef78 to 61c202d * 61c202d - litepcie_gen: allow up to 32 user IRQs with MSI-X. * 9e84d6a - litepcie_gen: remove flash_ios. * 3f63e74 - core/msi/LitePCIeMSIX: use width in enable/pba CSRs. * 2274b88 - litepcie_gen: expose stream's first on AXI interface as tuser. * 3271597 - Merge pull request #32 from sergachev/master |\ | * 9c5d250 - example: fix phy type |/ * 761f8fb - example: uniformize kc705/kcu105 examples. * c84605e - litepcie_gen: add Ultrascale support and example on kcu105.yml. * b73b72e - examples/kcu105: cleanup, use 4 lanes. * 597ab2d - README: add MSI/MSI-X support. * 150b34e - core/msi: test and fix LitePCIeMSIX, add register on S7PCIEPHY to get MSI-X enable status. * 4f8c624 - test/test_examples: update. * 84c9d71 - core/msi: add initial MSI-X implementation (untested). * 3ef2ae7 - software/kernel/main: add MSI Multi-Vector minimal support. * bd375da - litepcie_gen: use generate_litepcie_software_headers. * bf4b23c - software/generate_litepcie_software_header: add kernel to dst in generate_litepcie_software. * 3a7a76b - examples: use generate_litepcie_software. * ad93d52 - software: add generate_litepcie_software_headers/software functions to avoid duplication in targets. * 8534965 - litepcie/software: add copy_litepcie_software function (to easily get litepcie software from targets). * 5533144 - Merge pull request #30 from enjoy-digital/new_driver |\ | * 2703b8a - merge master. | |\ | |/ |/| * | b0e8383 - frontend/dma/LitePCIeDMAReader: immediately return to IDLE state when disabled. * | 4e333cb - Merge pull request #29 from sergachev/master |\ \ | * | 8192494 - kernel: remove unnecessary call to pci_release_regions() on device remove |/ / * | c2fd143 - phy/s7pciephy: expose disable_constraints parameter to use_external_hard_ip. | * 2658ce0 - software/kernel: replace remaining printk with pr_debug or dev_info and use dev_err instead of pr_err when possible. | * a78a248 - software/kernel: replace printk(KERN_INFO with pr_debug for debug messages. | * 79e448e - software/kernel: replace printk(KERN_ERR with pr_err. | * 23f7045 - software: add #ifdef for optional peripheral support. | * 1cae8cf - examples: update and more similarities with the integration in litex-boards. | * 485a6c4 - software: import new driver. | * c4c8705 - software: remove current driver. |/ * 6049a69 - litepcie_gen: add optional Sphinx/Html doc generation with --doc. * 6bb89af - phy/s7pciehy: disable constraints generated from the .xci and use our owns. * ef7d40e - Merge pull request #28 from sergachev/master |\ | * 3eb2b86 - test_dma: remove unused imports and variables, fix mistypes |/ * 9a3ada5 - Merge pull request #27 from sergachev/master |\ | * e637090 - dma: fix another couple of mistypes | * 4c4e3bf - dma: fix mistypes in comments |/ * 3ca6e38 - frontend/dma/monitor: reduce count_width from 32-bit (default) to 16-bit. * 22faa07 - litepcie_gen: add pcie_data_width support. * 96a6cdc - Merge pull request #25 from sergachev/master |\ | * 5804b43 - software: fix definitions * 0496daf - litepcie_gen: add buffers on DMA sink/source to ensure data are clocked on LitePCIe interface and ease integration. * 7818ace - frontend/dma: fix level CSRStatus size (+1). * a85b1d7 - tlp/controller: expose cmp_bufs_buffered parameter. * 264d7f3 - frontend/dma: allow asymetric writer/reader buffering depths. * 9cb938e - frontend/dma: expose table_depth parameter. * a6d836e - gen/examples: add software reset. * litesata changed from 2e5c5b1 to b36d3a3 * b36d3a3 - core/examples: update. * litescope changed from 54488c0 to 15179cb * 15179cb - examples/targets/simple: update. * 0e1ca9e - examples/make: update. * litex changed from 2d018826 to 54598ed2 * 54598ed2 - software/bios/Makefile: fix #578 merge. (get back #579). * 7beffba1 - software/libbase/memtest: fix bus errors reporting. * ad76f5f3 - Merge pull request #578 from scanakci/blackparrot_litex |\ | * eafceb94 - Merge branch 'master' into blackparrot_litex | |\ | |/ |/| * | 5a1c3a7c - Merge pull request #579 from antmicro/fix_building_bios |\ \ | * | d72380c8 - Fix ordering of libraries | | * caf520c8 - clean Makefile | | * 9256a4db - minor change in BP top module | | * 7c83a1b8 - syn with master blackparrot, upgrade BP to IMA | |/ |/| * | dae23f2a - Merge pull request #576 from betrusted-io/deprecate_slave |\ \ | * | 0b4c5059 - Deprecate slave terminology * | | 1e605fb2 - liblitesdcard/sdcard: update with litesdcard. * | | 34e9d12e - interconnect/axi/AXIStreamInterface: add tuser support. * | | 4094a6ec - liblitesdcard/sdcard: increase busy_wait and use common timeout. * | | e8f84c96 - liblitesdcard/sdcard: decode cid only when SDCARD_DEBUG is set. * | | c0770312 - liblitesdcard/sdcard_read: enable multiple block read. * | | 8c572d2b - targets: add fixed sdcard clock on boards with SDCard support. * | | c4669003 - software/bios/litesdcard: remove sdcard_set_clk. * | | dfa3768d - integration/soc/add_sdcard: remove sdclk. * | | 9a27465d - cores/clock/S6DCM: add expose_drp. * | | d8aa9a42 - software/bios/boot: improve printfs. * | | 55e01937 - software/libase/memtest: improve printfs and add progress bar on data test. * | | 49741366 - libbase/progress: reduce to 40 HASHES_PER_LINE. * | | 52d7f59a - software/liblitedram: remove DDRPHY_CMD_DELAY support (no longer useful). * | | 07f145fd - software/liblitedram/sdram: remove SRAM hack. * | | e2f9a825 - software/libbase/memtest: reorder functions. |/ / * | 00d1118d - Merge pull request #575 from antmicro/jboc/memtest |\ \ | * | 3b084b28 - bios: move memtest from liblitedram to libbase |/ / * | 3a5aec69 - software/liblitesdcard: simplify, switch to DMAs, remove clocking/test functions. * | fd4765e1 - integration/soc: replace SDDataReader/SDDataWriter with DMAs. * | bc64e354 - soc/cores: add simple DMA with WishboneDMAReader/WishboneDMAWriter. * | d7cc7d2a - platforms/genesys2: add usb_fifo. * | 309eda42 - litex_term: keep and reduce inter-frame delay to 1e-5. * | 64589cfd - soc/cores/uart/FT245: only use Asynchronous FIFO (Synchronous FIFO requires a software configuration). * | 0780b629 - soc/cores/usb_fifo: cleanup and reduce fifo_depth (provide similar throughput when used as UART). |/ * 52b51e1e - CHANGES: update. * d59cec5a - software: use a single crt0 (deprecate crt0-ctr/crt0-xip) and avoid unnecessary defines. * 384646c6 - platforms/genesys2: use openocd_genesys2.cfg. * e92efc1a - platforms/kcu105: add sdcard/spisdcard. * 35b04658 - genesys2: add sdcard/spisdcard. * d53a51c5 - platforms/netv2: add spisdcard. * c8955864 - platforms/k705: rename mmc to sdcard and make it similar to other boards. * 02908c51 - cpu/lm32: fix config include paths. * b1fe3140 - bios/main: enable sdcardboot in boot_sequence with litesdcard. * 847a5fcf - software/liblitesdcard/sdcard: boot with FatFs working (hacky). * 5b2f9c24 - cores/cpu/microwatt: revert setup stack and fix missing subi %r1,%r1,0x100 (thanks ozbenh). * 0c0689f4 - wishbone/DownConverter: fix read datapath when access is skipped because sel = 0. * 84617b58 - cores/cpu/microwatt: temporary revert crt0.S/setup stack. * e32e8c06 - Merge pull request #573 from ozbenh/bios-data |\ | * 28ea4b3f - software/microwatt: Fix copying data to RAM and clearing BSS |/ * 13e0852a - tools/litex_server: set socket option flags separately (required for Mac OS X). * efa41fd6 - litex_sim: simplify a bit ethernet+etherbone. * b0b37b4c - soc/cores/spi: make cs/loopback CSR optional. * 05cb5f96 - bios/boot: rewrite ROM boot description. * bdcccb92 - Merge pull request #569 from gsomlo/gls-mor1kx-data-init |\ | * e96cfbbc - cpu/mor1kx: fix .data initialization (follow-up to PR #567) * | 4cab38fa - Merge pull request #570 from gsomlo/gls-sdcard-lazy-init |\ \ | |/ |/| | * 9ad45a69 - liblitesdcard/[spi]sdcard: avoid redundant (re-)initialization |/ * aa0cd213 - Merge pull request #565 from gsomlo/gls-cosmetic-spi-fat |\ | * 5d9d99c0 - liblitesdcard/sdcard: streamline initialization (cosmetic) | * c05d0f19 - liblitesdcard/spisdcard: streamline initialization (cosmetic). | * 7d5ca3f9 - bios/boot: addresses should use 'unsigned long' * | 05d4756e - Merge pull request #567 from zyp/fix_data_segment |\ \ | * | 27fcddb2 - soc_core: Increase sram size default to 8k. | * | 9c68d715 - bios/linker: Place .data in sram with initial copy in rom. | * | 33689660 - bios/linker: Place .got in .rodata. | |/ * | b0f76112 - platforms/arty: move sdcard_pmod_io to JD. * | c3ed8025 - Merge pull request #568 from sergachev/master |\ \ | |/ |/| | * 3610b066 - build/sim/core/modules: fix compilation warnings |/ * 68d3804c - CHANGES: update. * 5ddf350c - software/spisdcard: reduce SPISDCARD_CLK_FREQ to 16MHz. * d6f92d1f - build: add DFUProg. * 653edd17 - bios/boot: simplify flashboot (remove specific linux boot). * 7b65a93c - bios/boot: add separators, update copyrights. * f4abdd3f - bios/boot: make Ethernet boot mode flexible (now also using boot.json similarly to SDCard boot). * c2ae22ee - bios/boot: make SDCard boot more flexible using a boot.json file on the SDCard. * d918c0bb - software/bios/boot/sdcardboot: let FatFs do the SDCard initialization with disk_initialize. * 51976008 - software/bios/boot: add sdcardboot support for VexRiscv SMP. * 72026d44 - software/bios/main: clarify address space with @ instead of -. * a01d08e5 - litex_setup.py: update microwatt. * a086237a - Merge pull request #564 from shenki/microwatt-updates |\ | * 748dcc1c - microwatt: Add mmu.vhdl | * b57fc870 - microwatt: Update IRQ signal in wrapper | * 68d2aa45 - microwatt: Add icache flush | * e6909e29 - microwatt: Implement boot helper * | ace81c83 - Merge pull request #562 from gsomlo/gls-crlf |\ \ | * | 5575a921 - liblitesdcard: maintain unix newline convention across all source files | |/ * | 08bef5fc - software/liblitesdcard/ffconf: enable FF_FS_MINIMIZE and FF_FS_TINY. * | 75225e5e - software/bios/boot: move f_mount to copy_image_from_sdcard_to_ram and force mount. * | 59a048b6 - software/libliteeth/tftp: switch to progress bar. * | f7e06a7e - bios/boot/copy_image_from_flash_to_ram: add missing init_progression_bar. * | df9146fb - soc/spisdcard: use 32-bit SPIMaster and do 32-bit xfers in spisdcardreceive_block to optimize speed. * | d45cfc1e - software/libbase/progress: avoid \t in progress bar, reduce HASHES_PER_LINE. * | 5beba178 - software/libsdcard/spisdcard: add and use busy_wait_us to optimize speed. * | dae15511 - bios/boot/copy_image_from_sdcard_to_ram: use chunks of 32KB to increase speed. * | d294e0f1 - bios/boot: add progress bar to copy_image_from_flash_to_ram, use uint32_t in flash/sdcard functions. * | 99f40fec - libase/progress: move __div64_32, do_div to div64.h/c as it was in Barebox. * | 96fc96ec - software/liblitesdcard: remove read_block prototype, minor cleanup. |/ * fe9b42fa - bios/boot: use progress bar in copy_image_from_sdcard_to_ram. * 21b9239d - libbase: add progress bar (from Barebox). * 32ebbc77 - software/liblitesdcard: add retries when setting card to Idle. * 04d0ba61 - software/liblitesdcard/sdcard: add FatFs disk functions. * e27ed657 - software/liblitesdcard/spisdcard: rename #defines and allow external definition. * a9e8860e - software/liblitesdcard: create fat directory for FatFs files. * f1aba7e4 - sofware/liblitesdcard: enable Long Filename (LFN). * fb282d1a - software/libsdcard: rewrite/simplify SPISDCard/FatFs support and only keep SDCard ver2.00+ compatibility. * 20ff2462 - Merge pull request #559 from gsomlo/gls-fix-crlf |\ | * 78e3f251 - liblitesdcard: convert all sources to unix style newlines (cosmetic) |/ * c1806eba - software/liblitesdcard: remove unsused functions with FF_FS_READONLY. * f9b43c81 - software/liblitesdcard: switch to FatFs for sdcardboot. * f972c8e4 - software/liblitesdcard: base it on FatFs generic example code + LiteX's SPIMaster specific functions. * 5b908983 - software/liblitesdcard: add FatFs files. * 7d141258 - software/liblitesdcard/spisdcard: simplify/rewrite for consistency with the others parts of the project. - Improve code readability, remove un-needed or duplicate comments. - Only use a spi_xfer function for both write/read. - Set the SDCard to low clk freq before init and increase it when initialized. * 860ac1e2 - software/liblitesdcard: add copyrights to spisdcard/fat16. * 0ec50881 - software/liblitesdcard/sdcard: simplify readSector. * 8c6f74d4 - software/liblitesdcard: fat16 boot working with both SPI and SD modes. * bdaf6ff2 - software/liblitesdcard: move fat16 code to separate file to avoid duplication. * 4b3c5203 - software/bios/libsdcard: add initial boot from sdcard with litescard, rename spisdcardboot command to sdcardboot. * b30e3353 - soc/add_sdcard: use SDClockerS7 for 7-Series and SDClockerGen for others devices. * efbe1690 - Merge pull request #558 from antmicro/fix-function-names-liblitespi |\ | * eceee7e4 - litex/soc/software/liblitespi: fix names associated with PHY CSRs |/ * fb4b6c35 - boards/ulx3s: add sdcard pins and initial LiteSDCard integration. * 997a17b9 - soc/add_sdcard: add minimal SDClockerECP5 on ECP5. * 9a026c09 - soc/add_sdcard: remove limitation to 7-Series but only add clocker for it. * c311f98c - soc/add_sdcard: emulator clocking moved to litesdcard. * 382f239e - software/libsdcard: keep SDCARD_DEBUG enabled for now, fix typos. * 20bbdaaf - soc/add_sdcard: remove Timer (unused). * ab447df9 - software/liblitesdcard: review/simplify (code is over-complicated, revert part of the old code and write a minimal test for now). * ee4056cf - software/liblitesdcard: remove sdtimer functions (unused). * ecfa44e5 - Merge pull request #556 from antmicro/mglb/symbiflow-fixes |\ | * 635a61e3 - targets/arty: use sys_clk_freq = 60MHz for Symbiflow toolchain | * 5071ef3e - build/xilinx/symbiflow: remap part name |/ * 55723f13 - software/liblitedram: revert sdrsw() in sdrlevel: this is still required for sdrlevel command. * ddcf68c0 - Merge pull request #553 from ozbenh/sim-autoinit |\ | * 4a6256a5 - sdram: Unconditionally switch to SW control before inits * | 47bb3d79 - Merge pull request #557 from antmicro/mor1kx_linux_booting |\ \ | * | f1e7d73e - bios: boot: Boot linux on mor1kx with external device tree and rootfs * | | 10ff9d76 - CHANGES: update and change added features order. |/ / * | 5d202ddb - test: update. * | 01f7947b - targets: rename gateware-toolchain parameter to toolchain. * | 245985d6 - targets/arty: integrate symbiflow changes to avoid duplication. * | 89106873 - build/generic_platform: add default_clk constraints only when used. * | 0cd613cc - build/xilinx/symbiflow: reuse .xdc generation from Vivado to avoid duplication, fix copyright. * | 80ec5eca - boards/arty: remove specific arty_symbiflow platform and adapt target to use standard platform. * | af928b26 - xilinx/simbiflow: add simple symbiflow_device re-mapping. * | 5104d07a - Merge pull request #551 from antmicro/mglb/symbiflow-toolchain-xilinx-7-support |\ \ | * | 7434376c - test/test_targets: add arty_symbiflow | * | ae121aac - targets: add arty_symbiflow | * | 2bb2fbdb - platforms: add arty_symbiflow | * | bd702397 - build/xilinx: add Symbiflow toolchain support | |/ * | 77139289 - Merge pull request #552 from ozbenh/memspeed-long |\ \ | * | 6239eac1 - sdram: Use unsigned long for memory test | |/ * | a116578c - Merge pull request #550 from antmicro/jboc/spd-read |\ \ | * | a433c837 - bios/litedram: add option to verify SPD EEPROM memory contents | * | 1692dfbf - build/sim/spdeeprom: use hex format when loading from file * | | b98a9192 - Merge pull request #549 from antmicro/mglb/fix-vivado-yosys |\ \ \ | |_|/ |/| | | * | a4e83234 - build/xilinx: do not assume build name is "top" |/ / * | 5cc7a988 - Merge pull request #547 from gsomlo/gls-fix-sdcard-status |\ \ | * | 28290efd - soc/software/litesdcard: update for response register back to 128 bits * | | 395af900 - interconnect/wishbone/DownConverter: skip accesses on slave when sel==0 and simplify. * | | 511832a9 - soc/interconnect/axi: generate wishbone.sel for reads. * | | 4f82a36a - soc/software: only keep 32-bit CSR alignment support. |/ / * | 75936775 - wishbone/wishbone2csr: use wishbone.sel on CSR write. * | b1ec092e - soc/software/litesdcard: use new send register to send command and remove CSR8_CMD_FIX. * | efcba14b - platforms/nexys_video: add spisdcard pins. * | 119ce56f - targets/nexys_video: add spi-sdcard and sdcard support. * | cc595017 - plaforms/nexys_video: keep up to date with litex-boards. * | 5cc564fb - targets: simplify Ethernet/Etherbone integration on targets with both. * | 55c7461e - bios/cmds/cmd_litesdcard: rewrite comments/descriptions. * | 6cb03963 - bios/main: replace / with -. * | 5dd5f97b - Merge pull request #545 from gsomlo/gls-fix-mmptr |\ \ | * | 3e1b17d4 - csr: fix simple accessor alignment * | | 6c1e2d84 - software/liblitesdcard: replace hexdump with dump_bytes already available in the BIOS. |/ / * | 9e068a74 - soc/add_sdcard: add with_emulator parameter to use SDCard emulator (from Google Project Vault) and integrate it in litex_sim. * | 2ae55e80 - setup.py: add litex_jtag_uart and litex_crossover_uart to console_scripts. * | 62d939e8 - Merge pull request #543 from antmicro/jboc/eeprom-sim |\| | * a0ce4ce5 - litex/build/sim: add module for simulating SPD EEPROM * | c4f96318 - targets/nexys4ddr: fix sdcard assert. * | 76cc112e - bios: add main bus and csr bus infos, use KiB/GiB. |/ * 02072dea - integration/soc/add_sdcard: always use 32-bit/512bytes memories (not sure this will change?) and allocate sdwrite/sdread regions dynamically. * 4b3afa75 - integration/soc: add add_sdcard method with integration code from nexys4ddr. * c78caeb9 - csr: Fix definition(s) of CSR_BASE in generated headers * f8bb500a - liblitedram/sdram: Add option to disable cdelay() * 6d72ef28 - cpu/serv: add variants. * fd7ec50e - soc/integration/export: add optional csr_base parameter. * 795ff08a - build/sim/verilator: add regular_comb parameter (that defaults to False) and pass it to get_verilog. * 25d2e7c9 - Merge pull request #542 from gsomlo/gls-sdcard-followup |\ | * 6da98ca1 - software/bios: fixup sdclk command * | 3fd6ecd8 - Merge pull request #541 from antmicro/jboc/spd-read |\ \ | * | 1172c10a - bios: move I2C from liblitedram to libbase | * | 472bf9ac - bios/sdram: expose I2C functions | * | bdc7eb5c - litex_sim: load SPD data from files in hexdump format as printed in BIOS | * | a42dc974 - bios/sdram: add BIOS command for reading SPD | * | 8fd3e74e - bios/sdram: add firmware for reading SPD EEPROM * | | 68f83cbc - CHANGES: document deprecated/moved modules. * | | ab806060 - soc/core/uart: move WishboneStreamingBridge in it and rename to Stream2Wishbone. * | | 0a3d649a - interconnect/wishbone: integrate Wishbone2CSR. * | | b5b88d27 - interconnect/csr_bus: add separators. * | | 86952a6e - interconnect/wishbone: remove CSRBank (probably not used by anyone). * | | e404608c - interconnect/wishbone: add separators and move SDRAM/Cache. * | | 1fddd0e3 - interconnect/wishbone: simplify DownConverter. * | | e0d26820 - interconnect/wishbone: remove UpConverter (probably not used by anyone and would need to be rewritten). | |/ |/| * | 696b31ed - tools/litex_sim: switch to SoCCore/add_sdram instead of SoCSDRAM. * | 2efcf879 - targets/nexys4ddr: update add_sdcard method. * | 2934c085 - CHANGES: add JTAG UART. * | 3b47d4a4 - tools/litex_jtag_uart: add openocd config and telnet port parameters. * | 67cf6703 - cpus: remove common cpu variants/extensions definition and simplify variant check. * | 062ff67e - cpu/microwatt: add standard+ghdl variant that uses GHDL Yosys plugin. * | 24687cbd - tools/litex_client/RemoteClient: add base_address parameter. * | 78a9579e - cores/uart/RS232PHYTX: fix startbit duration by pre-loading phase_accumulator_tx to tuning_word. * | 370e4652 - Merge pull request #539 from dayjaby/pr-fix_uart_startbit |\ \ | * | e853ad4b - fix uart startbit: 1 cycle later * | | c75cf45a - tools: add litex_jtag_uart to create a virtual uart for the jtag uart. * | | 2cf83b9f - tools: rename litex_crossover poc to litex_crossover_uart, remove from setup for now. * | | bed5aafd - tools: add litex_crossover to be able to use lxterm (and serialboot) over a crossover UART (bridged over UART/Ethernet/PCIe/USB, etc...). * | | 3833bc3e - litex_sim: override uart_name to sim only for serial. * | | da7fd308 - CHANGES: update. * | | 2fb52e66 - integration/soc: remove TODO in header. * | | b65f18c3 - cpu/cv32e40p: fix copyright year. * | | 30f35170 - cpu/cv32e40p: add copyright and improve indentation. * | | b23702ec - litex_setup/pythondata-cpu-cv32e40p: clone in recursive mode. * | | 4c4cd335 - Merge pull request #535 from antmicro/arty-cv32e40p |\ \ \ | * | | 2d6ee5aa - cores/cpu: add cv32e40p | * | | ca8cb834 - software/bios/isr: add support for cv32e40p | * | | 2903b1bf - litex_setup: add pythondata for cv32e40p * | | | 7d09ea19 - Merge pull request #538 from antmicro/fix_libbase |\ \ \ \ | * | | | 9d16b0fc - libbase: Include missing uart header |/ / / / * | | | 3d06dc02 - test/test_targets: update build_test. * | | | 42350f6d - platforms/targets: keep in sync with litex-boards. * | | | 2eea7864 - build/sim: rename dut to sim (for consistency with other builds). * | | | a6cbbc9d - integration/soc: set build_name to platform.name when not specified. * | | | 16417cb8 - software/liblitespi: fix #endif location. * | | | 9bdb063b - Merge pull request #516 from antmicro/i2s_support_arty |\ \ \ \ | * | | | ce499900 - Extend I2S capabilities * | | | | c2e9a26e - Merge pull request #534 from fjullien/fix_litex_sim_warn |\ \ \ \ \ | |/ / / / |/| | | | | * | | | 7c5f56c2 - litex/sim: fix compiler warnings |/ / / / * | | | 6fedaa70 - Merge pull request #533 from antmicro/fix-dummy-bits-function-name |\ \ \ \ | * | | | ab41e27e - software/liblitespi/spiflash: fix dummy bits setup function name |/ / / / * | | | d71152ef - litex_setup: move requests import to avoid having to install it on travis. * | | | 9854fdd5 - .travis: install requests package before running litex_setup.py. * | | | bd0f21ba - targets/netv2: remove LiteSPI integration (not mature enough to be directly integrated on targets). * | | | 80eca300 - software/liblitespi/spiflash: review/simplify/update and test on arty. * | | | 4a175620 - build/xilinx: simplify LITEX_ENV_ISE/VIVADO handling. * | | | e91c3171 - software/bios: cleanup includes and specify the lib in the include. * | | | c3a03d0d - software: create liblitespi and mode litespi code to it (with some parts commented out for now). * | | | 61238bee - soc/software/bios: add autoconfiguration functionality for LiteSPI core * | | | d3890055 - litex_setup: add automatic update of litex_setup (because it also changes) and be sure we are on master branch before update. * | | | 939f546a - Merge pull request #531 from gsomlo/gls-bios-linker |\ \ \ \ | |_|/ / |/| | | | * | | c5524dbf - software/bios: fix link order to avoid undefined symbol errors |/ / / * | | b4267a79 - build/xilinx: source settings64.sh automatically just before build if LITEX_ENV_ISE/LITEX_ENV_VIVADO environment variables are set. * | | de7e0ee9 - integration/soc_core: avoid cpu_variant check if custom cpu_cls is passed. * | | 6f8f0d23 - litex_setup: add litehyperbus and remove hyperbus core/test. |/ / * | 109fd267 - integration/builder: simplify default output_dir to "build/platform". * | 55c0ddab - litex_setup: add sha1 support on git clone/pull and fix microwatt to a specific sha1. |/ * 23d43a2c - Merge pull request #530 from enjoy-digital/bios-libs |\ | * 7192397a - software/libbase: remove linker-sdram (unused). | * b4b84def - software/bios: mode spisdcard code to liblitesdcard. | * 21e2a34c - software/bios: rename commands to cmds and update with libs' names. | * 33f6ce74 - software/bios: move hw flags definitions to respective libs, remove hw/flags.h. | * 403355a8 - software: create liblitescard and move sdcard init/test code to it. | * 920d0ee5 - software: create liblitedram and move sdram init/test code to it. | * c95084e5 - bios/software: rename cmd_dram/cmd_sdcard/cmd_spi_flash to cmd_litedram/cmd_litesdcard/cmd_spiflash. | * 573a8815 - software/bios/commands: rename cmd_mdio to cmd_liteeth. | * ff8d9e61 - software/bios: move mdio to libliteeth. | * 70a67ce7 - software/bios: rename libnet to libliteeth and move all ethernet files to it. | * 56b8723b - software/bios: rename cmd_mem_access to cmd_mem. |/ * a02077d5 - cpu/microwatt/add_sources: add use_ghdl_yosys_synth parameter to convert microwatt to verilog using GHDL-Yosys-plugin and use converted verilog for build. * b5352f40 - cpu/microwatt: update microwatt_wraper.vhdl * be25500e - uptime: rework and integrate it in Timer to ease software support. * d6549ff8 - bios: add uptime command and rewrite cmd_bios comments. * fc0e55be - soc: improve uptime comments. * 840679ad - Merge pull request #526 from rprinz08/master |\ | * 3f649077 - Make booting from SD-Card to behave same as from SPI flash * | 82364de5 - soc/SoCController: add uptime since start (disabled by default) and allow features to be enabled/disabled. |/ * 3391398a - bios/sdram: always show bitslip on two digits to keep scan aligned. * 4a5072a0 - Merge pull request #517 from ozbenh/csr-access-rework |\ | * 1e35b0e7 - csr: Rework accessors |/ * d4f44597 - CHANGES: update. * a51c7a7b - Merge pull request #518 from enjoy-digital/csr_base |\ | * 748ef1ad - export: add define of CSR_BASE if not already defined and use it for CSRs definitions/accesses. * | 177c1e53 - Merge pull request #523 from DurandA/patch-5 |\ \ | * | 9d9e7d54 - Update litex_term help |/ / * | 2e59dc32 - platforms/nexys4ddr: add card detect pin to sdcard. * | 51742be2 - integration/soc: review/simplify interconnect and add logger.info. * | 78413cc0 - Merge pull request #519 from ozbenh/point2point |\ \ | |/ |/| | * 1ed68691 - soc: Revive generation of a PointToPoint interconnect |/ * 9f941138 - test/test_targets: workaround to fix travis. * 9d1443c1 - cpu/soc_core: automatically set csr mapping to 0x00000000 when using CPUNone, remove csr_base parameter that was used for that. * 5ea3bae0 - bios/boot: review/fix #503. * bf7857f5 - Merge pull request #503 from rprinz08/master |\ | * 1f55fcf4 - fixed bug in BIOS spi flash "fw" command | * f062c0c4 - removed FLASH_BOOT_OFFSET, replaced memcyp with copy_image_from_flash_to_ram | * ea232fc5 - BIOS boot firmware from SPI with address offset * | b4e349eb - Merge pull request #513 from mubes/bios_linker |\ \ | * | d2d82dac - Bios linker edits to prevent inappropriate optimisation |/ / * | 3fb99b7d - cores/spi_flash: add back old SpiFlashDualQuad and rename new one as SpiFlashQuadReadWrite. * | 2a5a7536 - Merge pull request #478 from antmicro/extended_spi_flash |\ \ | * | 00f973ea - spi_flash: extend non-bitbanged flash support | * | a344e20b - spi_flash: fix building without bitbang * | | 7d79da8e - Merge pull request #510 from mubes/colorlight_usb |\ \ \ | * | | 84997332 - Fix dumb missing line | * | | 33e202ed - Bring into line with master | |\ \ \ | * | | | dc1d4520 - Addition of boot address parameter for trellis builds * | | | | 3a6dd95d - integration/soc: review/simplify changes for standalone cores. * | | | | 0d5eb133 - Merge pull request #511 from ozbenh/standalone-cores |\ \ \ \ \ | * | | | | f628ff6b - WB2CSR: Use CSR address_width for the wishbone bus | * | | | | 520c17e9 - soc_core: Add option to override CSR base | * | | | | ecbd4028 - soc: Don't update CSR alignment when there is no CPU | * | | | | f28f2471 - soc: Don't create a wishbone slave to LiteDRAM with no CPU | * | | | | dcc881db - soc: Don't create a share intercon with only one master and one slave | | |/ / / | |/| | | * | | | | 873d95e5 - interconnect/wishbonebridge: refresh/simplify. * | | | | c136113a - Merge pull request #506 from scanakci/blackparrot_litex |\ \ \ \ \ | * | | | | aed1d514 - Update README.md and core.py for BlackParrot | * | | | | 5e4a4360 - Vivado Command Update for Systemverilog | |/ / / / * | | | | d2c9d385 - Merge pull request #508 from antmicro/update_litesdcard |\ \ \ \ \ | |/ / / / |/| | | | | * | | | 0db35069 - Update Litex bios to handle updated litesdcard. |/ / / / * | | | 3ce90100 - Merge pull request #505 from DurandA/patch-3 |\ \ \ \ | * | | | 2c40967b - Enable 1x mode on SPI flash | | |_|/ | |/| | * | | | e2176cef - soc: remove with_wishbone (a SoC always always has a Bus) and expose more bus parameters. * | | | 1e610600 - build/lattice/diamond/clock_constraints: review and improve similarities with the others build backends. * | | | ebcf67c1 - Merge pull request #502 from shuffle2/master |\ \ \ \ | * | | | eeee179d - diamond: close project when done | * | | | 9b782bd7 - diamond: clock constraint improvements | |/ / / * | | | 80f5327e - Merge pull request #490 from daveshah1/rdimm_bside_init |\ \ \ \ | * \ \ \ 13db89eb - Merge branch 'master' into rdimm_bside_init | |\ \ \ \ | |/ / / / |/| | | | * | | | | c9e36d7f - lattice/icestorm: add ignoreloops/seed support (similar to trellis) and icestorm_args. * | | | | ea7fe383 - lattice/trellis: simplify seed support and add it to trellis_args. * | | | | 5ee01c94 - Merge pull request #484 from ilya-epifanov/lattice-trellis-toolchain-seed |\ \ \ \ \ | * | | | | ac1e9683 - Can now pass `--seed` to `nextpnr-ecp5` via `TrellisToolchain` `kwargs` * | | | | | 5987ddb4 - Merge pull request #485 from ilya-epifanov/cpu-imac-config-for-vexriscv |\ \ \ \ \ \ | * \ \ \ \ \ c5f74a5a - Merge branch 'master' into cpu-imac-config-for-vexriscv | |\ \ \ \ \ \ | |/ / / / / / |/| | | | | | * | | | | | | 59d88a88 - integration/soc/add_adapter: rename is_master to direction. * | | | | | | 57390666 - Merge pull request #504 from sergachev/master |\ \ \ \ \ \ \ | * | | | | | | e4fa4bbc - integration/soc: fix add_adapter for slaves |/ / / / / / / * | | | / / / 2d70220b - bios: Fix warning on 64-bit | |_|_|/ / / |/| | | | | * | | | | | fbbbdf03 - core/led: simplify LedChaser (to have the same user interface than GPIOOut). * | | | | | 05869beb - cores/led: add LedChaser (now that LiteX is running on FPGA mining boards let's use fancy led blinks :)) * | | | | | 90c485fc - integration/soc: add clock_domain parameter to add_etherbone. * | | | | | f1a50a21 - integration/soc: add add_uartbone method (to add a UARTBone aka UART Wishbone bridge). | |_|_|/ / |/| | | | * | | | | 79ee135f - bios/sdram: fix lfsr typo. * | | | | 162d3260 - Merge pull request #500 from mubes/fixups |\ \ \ \ \ | * \ \ \ \ 2a37b97d - Merge branch 'master' of https://github.com/enjoy-digital/litex into fixups | |\ \ \ \ \ | * | | | | | 967e38bb - Small fixups to address compiler warnings etc. | | |_|_|_|/ | |/| | | | * | | | | | d74f8fc9 - build/xilinx: add disable_constraints parameter to Platform.add_ip. | |/ / / / |/| | | | * | | | | 84841e1d - bios/sdram: fix merge typo in lfsr (thanks Benjamin Herrenschmidt). * | | | | 99c5b0fc - bios/sdram: Use an LFSR to speed up pseudo-random number generation * | | | | 34f26868 - Merge pull request #499 from DurandA/patch-2 |\ \ \ \ \ | * | | | | 5e049d89 - Add data dirs to manifest * | | | | | 8b9aa16d - boards/platforms: update xilinx programmers. * | | | | | 3c34039b - build/xilinx/vivado: ensure Vivado process our .xdc early. |/ / / / / * | | | | b0578580 - gen/fhdl/verilog: explicitly define input/output/inout wires. * | | | | 0aa3c339 - targets/genesys2: set cmd_latency to 1. * | | | | 95b57899 - bios: remove usddrphy debug (we'll use a specific debug firmware to fix the usddrphy corner cases). * | | | | 98d1b451 - platforms/targets: fix CI. * | | | | 22bcbec0 - boards: keep in sync with LiteX-Boards, integrate improvements. * | | | | 28f85c74 - build/lattice/programmer: add UJProg (for ULX3S). * | | | | 85ac5ef1 - build/lattice/programmer: make OpenOCDJTAGProgrammer closer to OpenOCD programmer. * | | | | 9a7f9cb8 - build/generic_programmer: catch 404 not found when downloading config/proxy. * | | | | d0b8daa0 - build/platform: allow doing a loose lookup_request (return None instead of ConstraintError) and allow subname in lookup_request. * | | | | b8f9f83a - build/openocd: add find_config method to allow using local config file or download it if not available locally. * | | | | 9bef218a - cpu/microwatt: fix integration/crt0.S (thanks Benjamin Herrenschmidt). * | | | | 6f24d46d - Merge pull request #496 from gsomlo/gls-fix-makefiles |\ \ \ \ \ | * | | | | edfed4f0 - software/*/Makefile: no need to copy .S files from CPU directory |/ / / / / * | | | | 7f8e34c6 - Merge pull request #494 from shuffle2/patch-2 |\ \ \ \ \ | * | | | | ee413527 - diamond: quiet warning about missing clkin freq for EHXPLLL |/ / / / / * | | | | 07e0153b - CHANGES: update. * | | | | 21127031 - cpu/microwatt: add powerpc64le-linux-gnu to gcc_triple. * | | | | c06a1279 - cpu/microwatt: add pythondata and fix build with it. * | | | | 45377d9f - cpus: use a common definition of gcc_triple for the RISC-V CPUs, reorganize CPU by ISA/Data-Width. * | | | | 7c69a6db - bios/cmd_mdio.c: fix missing import. * | | | | b0205335 - cpu/vexriscv: fix flush_cpu_icache, remove workaround on boot.c. * | | | | 97e534d0 - cpus: add nop instruction and use it to simplify the BIOS. * | | | | 4efc7835 - cpus: add human_name attribute and use it to simplify the BIOS. * | | | | d81f171c - software/libbase/system.c: remove unused includes. * | | | | 3bbadb35 - Merge pull request #492 from scanakci/blackparrot_litex |\ \ \ \ \ | * \ \ \ \ 999b93af - Merge branch 'master' into blackparrot_litex | |\ \ \ \ \ | |/ / / / / |/| | | | | * | | | | | 705d3887 - Merge pull request #474 from fjullien/term_hist_auto_compl |\ \ \ \ \ \ | * | | | | | 74dc444b - bios: add auto completion for commands | * | | | | | fc2b8226 - bios: switch command handler to a modular format | * | | | | | 86cab3d3 - bios: move helper functions to their own file | * | | | | | bc5a1986 - bios: add terminal history | * | | | | | e764eabd - builder: add a parameter to pass options to BIOS Makefile | | * | | | | 0c770e06 - Update README.md | | * | | | | 19bb1b9b - update to comply with python-data layout | | * | | | | 3eb9efd6 - BP fpga recent version | | * | | | | bf864d33 - Fix memory transducer bug, --with-sdram for BIOS works, memspeed works | | * | | | | cf01ea65 - rebased, minor changes in core.py | | * | | | | b7b9a1f0 - Linux works, LiteDRAM works (need cleaning, temporary push) | | * | | | | 74140587 - Create GETTING STARTED | |/ / / / / |/| | | | | * | | | | | e853cac6 - Merge pull request #483 from ilya-epifanov/lattice-openocd-jtag-programmer-erase-flag-and-quiet-output |\ \ \ \ \ \ | * | | | | | a11f1c39 - Removed erase flag and made progress output less noisy | | |_|_|/ / | |/| | | | * | | | | | a6779b9d - Merge pull request #491 from gsomlo/gls-spisd-clusters |\ \ \ \ \ \ | * | | | | | c8e3bba4 - software: spisdcard: cosmetic: avoid filling screen with cluster numbers * | | | | | | b5978b21 - .travis.yml: disable python3.5 test (nMigen requires 3.6+). * | | | | | | 10371a33 - CHANGES: update. * | | | | | | bd8a4100 - cpu/minerva: add pythondata and use it to compile the sources. * | | | | | | e4a4659d - litex_setup: add nmigen dependency (used to generate Minerva CPU). * | | | | | | d3e3ca06 - CHANGES: start listing changes for next release. |/ / / / / / * | / / / / 3c70c83f - cpu/software: move flush_cpu_icache/flush_cpu_dcache functions to CPUs. | |/ / / / |/| | | | * | | | | bb70a232 - cpu/software: move CPU specific software from the BIOS to the CPU directories. * | | | | 0abc7d4f - cpu/Minerva: Clone the repository locally for now, we need to create a pythondata repository. * | | | | b82b3b7e - integration/soc: rename usb_cdc to usb_acm. * | | | | 0a1afbf6 - litex/__init__.py: remove retro-compat > 6 months old. * | | | | 3531a641 - soc: allow passing custom CPU class to SoC. | | | * | 83f4dcb2 - Added `imac` config for CPUs which implements the most basic working riscv32imac feature set, implemented for VexRiscv | | |/ / | |/| | | | | * 64b50515 - Add RDIMM side-B inversion support | |_|/ |/| | * | | 90a6343d - Merge pull request #488 from enjoy-digital/python3.5 |\ \ \ | |/ / |/| | | * | 9941e4c1 - travis: add back test on python3.5 (python3.6 is recommended but we can try to keep 3.5 compatibility until we have good reason to no longer support it). |/ / * | 855d614e - Merge pull request #481 from betrusted-io/unfstringify |\ \ | * | 17b76654 - propose patch to not break litex for python 3.5 |/ / * | 56aa7897 - create first release, add CHANGES and note about Python modules in README. * | 6d0896de - cpu/serv: switch to pythondata package instead of local git clone. * | 1b069268 - README: update Python minimal version to 3.6. * | ff61b1f6 - litex_setup: disable automatic clone of BlackParrot/Microwatt CPUs, reorder LiteX data. * | 4d86ab9d - Merge pull request #399 from mithro/litex-sm2py |\ \ | * \ 317ea7ed - Merge branch 'master' into litex-sm2py | |\ \ | * | | 1f356695 - litex_sim: Find tapcfg from pythondata module. | * | | 3aee8a52 - Remove directories from submodules from MANIFEST.in file. | * | | ebcb2a44 - Rename litex-data-XXX-YYY to pythondata-XXX-YYY | * | | a39a4ec2 - Only allow fast-forward pulls. | * | | e618d41f - Fixing mor1kx data finding. | * | | 2e3b7f20 - Fix typo in error message. | * | | 83b25813 - Fix the libcompiler_rt path. | * | | 1c1c5bcb - Remove submodules. | * | | c96d1e66 - Fix import for data. | * | | 119985f3 - Use the current directory you are running. | * | | 69367f8d - Make litex a namespace. | * | | 3ae4f8f2 - Adding missing vexriscv CPU. | * | | ac3fd794 - Adding missing comma. | * | | 3df6c0c8 - Adding litex-data-software-compiler_rt as a required package. | * | | 3964565e - Fixed quotes in `litex_setup.py` | * | | d5a21a75 - Converting litex to use Python modules. | / / * | | 5ef869b9 - soc/cpu: add memory_buses to cpus and use them in add_sdram. * | | 467fee3e - soc/cpu: rename cpu.buses to cpu.periph_buses. |/ / * | 05815c4e - Merge pull request #477 from shuffle2/patch-1 |\ \ | * | f71014b9 - diamond: fix include paths |/ / * | 4dece4ce - soc/cpu: simplify integration of CPU without interrupts (and automatically use UART_POLLING mode in this case). * | c5ef9c73 - Merge pull request #473 from fjullien/memusage |\ \ | * | 3892d7a9 - bios: print memory usage * | | 9460e048 - tools/litex_sim: use similar analyzer configuration than wiki. * | | 443cc72d - Merge pull request #476 from enjoy-digital/serv |\ \ \ | * | | 1d1a4ecd - software/irq: cleanup and make explicit that irqs are not supported with Microwatt and SERV, fix compilation warning. | * | | fb9e369a - serv: connect reset. | * | | 71778ad2 - serv: update copyrights (Greg Davill found the typos/issues). | * | | 1f9db583 - serv/cores: fix verilog top level (use serv_rf_top instead of serv_top), working :). | * | | 2efd939d - serv: fix ibus/dbus byte/word addressing inconsistency, add missing ibus.sel (thanks @GregDavill). | * | | 22c39236 - initial SERV integration. | | |/ | |/| * | | c4c891de - build/icestorm: add verilog_read -defer option to yosys script (changes similar the ones applied to trellis). * | | 192849f0 - Merge pull request #475 from gregdavill/read_verilog_defer |\ \ \ | |_|/ |/| | | * | 642c4b30 - build/trellis: add verilog_read -defer option to yosys script |/ / * | 96e7e6e8 - bios/sdram: reduce number of scan loops during cdly scan to speed it up. * | 43e1a5d6 - targets/kcu105: use cmd_latency=1. * | 85a059bf - bios/sdram: add some margin on cdly ideal_delay, do the read_leveling even if write_leveling is not optimal. * | 038e1bc0 - targets/kc705: manual DDRPHY_CMD_DELAY no longer needed. * | aaed4b94 - bios/sdram: review/cleanup Command/Clock calibration, set window at the start instead of middle. * | 33c7b2ce - Merge pull request #472 from antmicro/jboc/sdram-calibration |\ \ | * | ab92e81e - bios/sdram: add automatic cdly calibration during write leveling * | | 4608bd18 - Merge pull request #470 from antmicro/jboc/sdram-eeprom-timings |\ \ \ | |_|/ |/| | | * | b0f8ee98 - litex_sim: add option to create SDRAM module from SPD data * | | 0b3c4b50 - soc/cores/spi: add optional aligned mode. * | | 6bb22dfe - cores/spi: simplify. * | | fc434af9 - build/lattice/common: add specific LatticeiCE40SDROutputImpl/LatticeiCE40SDRTristateImpl (thanks @tnt). * | | 1457c320 - xilinx/common: use a common SDRTristate implementation for Spartan6, 7-Series and Ultrascale. * | | 69462e66 - build/xilinx/common: add 7-Series/Ultrascale SDROutput/Input. * | | 65e6ddc6 - lattice/common: add LatticeECP5DDRInput. * | | 2031f280 - lattice/common: cleanup instances, simplify tritates. * | | 2d25bcb0 - lattice/common: add LatticeiCE40DDRInput, LatticeiCE40SDROutput and LatticeiCE40SDRInput. | |/ |/| * | 56e15284 - platforms/de0nano: swap serial tx/rx to ease use of cheap FT232 based cables. * | 08e4dc02 - tools/remote/etherbone: update import. |/ * 19f983c4 - targets: manual define of the SDRAM PHY no longer needed. * c0f3710d - bios/sdram: update/simplify with new exported LiteDRAM parameters. * 3915ed97 - litex_sim: add phytype to PhySettings. * c0c5ae55 - build/generic_programmer: move requests import to do it only when needed. * c9ab5939 - bios/sdram/ECP5: set ERR_DDRPHY_BITSLIP to 4. * litex-boards changed from cb95962 to 1356ebb * 1356ebb - targets/ecp5: update clocking on boards with DDR3 to use reset from ddrphy.init and use primary clock for Power on reset. * 4997399 - Merge pull request #85 from oskirby/logicbone |\ | * 76a32ba - Add Logicbone ECP5 board * | efe33c9 - targets/arty: add fixed sdcard clock and remove sys2x (use NETWORKING interface_type on DDR3). * | 6753a92 - targets: add fixed sdcard clock on boards with SDCard support. * | 782c856 - platforms/genesys2: add usb_fifo. * | 936ba5b - platforms/genesys2: add openocd specific configuration (channel 1 used for JTAG). * | 55ed9fb - platforms/kcu105: add sdcard/spisdcard. * | eee00eb - platforms/genesys2: add sdcard/spisdcard. * | 6568c8a - platforms/netv2: add spisdcard. * | 7de7c4b - platforms/kc705: rename mmc to sdcard and make it similar to other boards. |/ * 0ecb860 - platform/arty: also update spisdcard. * 7a8b0b7 - platforms/pano_logic_g2: -x. * 2db7aa7 - Merge pull request #84 from antmicro/sdcard-pmod |\ | * f70655d - Change sdcard Pmod from JB to JD |/ * 04f6d44 - versa_ecp5: simplify device (LFE5UM5G or LFE5UM) and adapt integrated_rom_size only for Microwatt. * 1537189 - Merge pull request #83 from madscientist159/master |\ | * 9009216 - Add device option for ECP5 Versa board | * b1be5dc - Fix FTBFS from undersized BIOS ROM region with Microwatt |/ * 9b45ec0 - de10lite: simplify vga terminal. * 85cac7a - de10nano/Mister: review/simplify. * 64372d7 - targets/orangecrab: add spi-sdcard and workaround for ValentyUSB. * c94cbae - orangecrab: add user_led (RGB leds), DFUProg and --load support. * 9aea227 - Merge pull request #80 from rob-ng15/master |\ | * 485c242 - Use 128mb sdram, uart via i/o port on i/o board and vga terminal via i/o board | * e52d6ac - Use 128mb sdram, uart via i/o port on i/o board and vga terminal via i/o board * | 45bd50b - targets: rename colorlight_5a_75b to colorlight_5a_75x (since we are now also supporting the 75e). * | ad1693a - Merge pull request #82 from Disasm/colorlight-5a-75e |\ \ | * | 0c590ab - Update colorlight_5a_75b target: add 5A-75E board support | * | 1acdb96 - Add 5A-75E V7.1 board | |/ * | b312c65 - Merge pull request #81 from Disasm/fix-5a-75b |\ \ | * | 939f05f - Update J4 pin 5 on Colorlight 5A-75B V7.0 | |/ * | 94861bb - targets/orangecrab: uncomment MT41K512M16. * | b6df166 - platforms/arty: add spisdcard to _sdcard_pmod_io. * | 00c8e40 - platforms/ulx3s: add sdcard pins. |/ * aa35cd2 - Merge pull request #79 from gsomlo/gls-trellis-sdcard |\ | * f9a8edb - targets/trellisboard: add initial LiteSDCard support |/ * d87a11a - targets/pcie: use generate_litepcie_software on all targets with PCIe. * 9f83b6e - targets/acorn_cle_215: use new generate_litepcie_software functions and add --driver argument to generate driver. * 091ec84 - targets/acorn_cle_215: automatically copy software from litepcie and generate headers in kernel directory. * 06edf48 - targets: rename gateware-toolchain parameter to toolchain. * 0b11aba - platforms/nexys_video: add spisdcard pins. * 76df4e3 - targets: simplify Ethernet/Etherbone integration on targets with both. * 2e1a816 - pano_logic_g2: switch to LiteEthPHY and simplify Ethernet/Etherbone. * 33fe308 - Merge pull request #78 from antmicro/jboc/spd-read |\ | * e5578a1 - zcu104/platform: change I2C number to 0 | * ac1f1cd - zcu104: add I2C * | 71f220a - colorlight_5a_75b: remove unnecessary parenthesis. * | 2f3817c - pano_logic_g2: add ethernet (build but not functional yet) and use user_btn_n as sys_rst. * | f19bc36 - pano_logic_g2: add revision support (b and c, c as default) and add OpenOCD programmer. * | d6518c7 - prog/openocd: fix openocd_xc6 cfgs. * | 22f18f6 - pano_logic_g2: move gmii_rst_n to _CRG. * | 935a711 - Merge pull request #77 from skiphansen/master |\ \ | * | 0648c04 - Updated comment, added link to clocking documentation. | * | 1ab4656 - Take Ethernet PHY out of reset so default clock is 125 Mhz (and baud rate is 115,200) |/ / * | 9b572ec - forest_kitten_33: add minimal target and use es1. * | 7ad0363 - Merge pull request #76 from gsomlo/gls-nexys4-spisdcard |\ \ | * | 435913f - platforms/nexys4ddr: add option to build with spi-mode sdcard support |/ / * | 0d549a8 - platforms: add forest_kitten_33 initial platform suppport. * | 12b54a7 - platforms/alveo_u250: add clk300 clock constraints. * | 46f78b5 - nexys_video: add usb_fifo pins. * | 445338e - platforms/nexys_video: add specific openocd cfg (use channel 1). * | 5aeb7d8 - targets/acorn_cle_215: fix typo in description. * | eeba64d - targets: use soc.build_name in load/flash bitstream. * | 76551de - platforms/nexys_video: add sdcard pins, move clk/rst to top. * | 83457b8 - platforms/arty: add _sdcard_pmod_io. * | 8158d94 - targets/c10lprefkit: switch to litehyperbus. * | 587caf7 - paltforms/marblemini: add break_off_pmod. * | c2cd863 - platforms/ecp5_evn: rename spiflash1x to spiflash, rewrite hardware/configuration description and remove make_spiflash. * | 3f0f120 - Merge pull request #70 from ilya-epifanov/ecp5-evn-spi1x-and-flash-params |\ \ | |/ |/| | * 0ba8045 - Added spiflash1x pins, a method to create an SpiFlash instance and a note on a second UART channel of FT2232H * | b9ee3a7 - alveo_u250: re-organize the auto-generated IOs, add build/load parameters. * | c0b7afc - targets/alveo_u250: +x. * | 67d2a49 - tools/extract_xdc_pins: +x. * | 482d7a6 - targets/pcie: use 128-bit datapath and 8 max_pending_requests on pcie_x4 configurations. * | 2bb7fce - targets/acorn_cle_215: add minimal instructions to reproduce the results. * | 6757c4e - Merge pull request #71 from daveshah1/alveo_u250 |\ \ | * | 088ccec - Add Alveo U250 platform and target | |/ * | c7404e3 - targets/acorn_cle_215: switch to MT41K512M16 (Acorn has a 1GB DDR3 vs 512MB on NiteFury). * | d05b10f - target/camlink_4k: add missing import. * | b211c43 - test/test_targets: add acorn_cle_215 and marblemini. * | 4faa91c - platforms/marblemini: review/cleanup. * | 4ffdcb5 - Merge pull request #75 from jersey99/marblemini |\ \ | * | e4ccfcf - platforms/marblemini.py: Cleanup. Add openocd for programming marblemini | * | a7d6de7 - Merge branch 'master' into marblemini | |\ \ | * | | 5f7f087 - community/platforms/marblemini.py: Added marblemini from https://github.com/berkeleylab/marble-mini/ | / / * | | 6f22f08 - targets: add LedChaser on platforms with user_leds. * | | b9a0f23 - Merge pull request #74 from tommythorn/master |\ \ \ | |/ / |/| | | * | 6335717 - targets/orangecrab.py: propagate command arguments * | | 19b12fd - targets/panol_logic_g2: replace with a minimal target. * | | 99c0435 - platforms/pano_logic_g2: simplify/cleanup. * | | 6b5492a - pano_logic_g2: add copyrights. * | | 6ddd859 - add pano_logic_g2 from litex-buildenv. * | | 27c242b - targets/pcie: switch to PCIe X4 on all boards that support it. * | | f993953 - targets/pcie: update LitePCIe constraints. |/ / * | d34c3ba - prog: use different openocd config files for FT232/FT2232. * | 117d1a1 - prog: add colorlight_5a_75b openocd config. * | e500d90 - platforms/ecpix5: set pullups on rx_data to advertise as RGMII mode. * | 59e8c2c - acorn_cle_215: add .bin generation and --flash argument, working on hardware :). * | a049fa6 - add Acorn CLE 215+ platform/target. * | da61aab - targets: remove USDDRPHY_DEBUG and set cmd_latency to on all Kintex7/Ultrascale targets. * | b58b9b9 - platforms: fix CI. * | 2d9543b - targets: add build/load parameters on all targets. * | 19eb570 - platforms: make sure all traditional platforms have a create_programmer method. * | 84468c2 - targets/CRG: platforms are now automatically constraining the input clocks. * | 1f88a9d - platforms: make sure clocks inputs are constraints on all platforms. * | 86648ec - platforms/vcu118: rename ddram_second_channel to ddram:1. * | e1820c7 - platforms/ac701: indent HPC. * | 2129b67 - platforms: make sure all plarforms have separators. * | ea0eda9 - platforms: make sure all Xilinx/Altera platforms have a create_programmer method, use OpenOCD on Spartan6 and 7-Series. * | 588bbac - add prog directory with some Xilinx OpenOCD configurations files. * | 78b5727 - targets: rename usb_cdc to usb_acm. |/ * 2213d73 - targets/kcu105: use cmd_latency=1. * a8a42c5 - targets/kc705: manual DDRPHY_CMD_DELAY adjustment no longer needed. * 865b01e - ecpix5: add ethernet. * 6fe4c4e - ecpix5: add DDR3 (working) * efb13bc - add mininal ECPIX-5 board support (Clk/Rst/Leds/UART), BIOS working. * 4154bdf - targets/PCIe: add PCIe software reset. * 4ad6042 - platforms/de0nano: swap serial tx/rx to ease use of cheap FT232 based cables. * 4185a01 - targets: manual define of the SDRAM PHY is no longer needed. * litex-renode changed from 7da3929 to 77df9bd * 77df9bd - Merge pull request #27 from antmicro/realign_memory * 8ef7904 - Re-align selected memory regions * migen changed from 0.6.dev-337-g19d5eae to 0.6.dev-347-gb1b2b29 * b1b2b29 - zc706: redo FMC connectors * 0d16e03 - kasli: add DCXO pins * ea1eefe - zc706: add FMC HPC connector HA pins * dc9cfe6 - kasli2: add upper EEMs * 6809ee0 - kasli2: add cdr_clk and cdr_clk_clean * afc6b02 - zc706: fix LAxx_CC pin naming consistency with KC705 * 0762612 - zc706: add user_sma_clock * e71f21e - zc706: add FMC connectors * 5b5e4fd - kasli: typo * bea0bdc - kasli: v2.0 support (WIP) Full submodule status -- 2942d0652a89646c5225bee15dd55cc3b0871766 VexRiscv (1.0.1-417-g2942d06) 3a6108a75be356a3dc53760d22782f1323248b6b edid-decode (heads/master) 3a06aa84b62ad24467fb0d2c6ceddf565e9ea447 flash_proxies (heads/master) 9044c104087819b49d19361494eb41182ee4058f litedram (2020.04-61-g9044c10) dbe15f17fcf96b8a4671465a4df93381ca11b818 liteeth (2020.04-19-gdbe15f1) 6fdd02058fba29008c90b162e0ef707dce15ebeb liteiclink (2020.04) 61c202dc82fe7e36c55ccfebea41b37b6e553b68 litepcie (2020.04-40-g61c202d) b36d3a33fbbfcffdb77a7a9e05bc8121387858d3 litesata (2020.04-1-gb36d3a3) 15179cb46f68bff1679631a8bade6f7e1607a40a litescope (2020.04-2-g15179cb) 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 liteusb (heads/master) 41f30143075ece3fff5c33a332ed067d1837cbb3 litevideo (2020.04) 54598ed2f808a376c2b8bc57d4a7306049d617c0 litex (2020.04-410-g54598ed2) 1356ebb416502d42620eeb66723508dee2b20aa3 litex-boards (2020.04-112-g1356ebb) 77df9bd84d6e85dd5fcb814b17ed6a1e808ad490 litex-renode (remotes/origin/HEAD) b1b2b298b85a795239daad84c75be073ddc4f8bd migen (0.6.dev-347-gb1b2b29) 8f5a253b22cd4ebcd56304a3662f4c70e3b34ed5 nmigen (v0.1-69-g8f5a253) --- third_party/litedram | 2 +- third_party/liteeth | 2 +- third_party/litepcie | 2 +- third_party/litesata | 2 +- third_party/litescope | 2 +- third_party/litex | 2 +- third_party/litex-boards | 2 +- third_party/litex-renode | 2 +- third_party/migen | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/third_party/litedram b/third_party/litedram index de55a8e17..9044c1040 160000 --- a/third_party/litedram +++ b/third_party/litedram @@ -1 +1 @@ -Subproject commit de55a8e17046ffd6bf68d1c0d606088abdb37950 +Subproject commit 9044c104087819b49d19361494eb41182ee4058f diff --git a/third_party/liteeth b/third_party/liteeth index 705003e52..dbe15f17f 160000 --- a/third_party/liteeth +++ b/third_party/liteeth @@ -1 +1 @@ -Subproject commit 705003e5231436de9a276e8f834564c6fbe90a1e +Subproject commit dbe15f17fcf96b8a4671465a4df93381ca11b818 diff --git a/third_party/litepcie b/third_party/litepcie index 586ef7879..61c202dc8 160000 --- a/third_party/litepcie +++ b/third_party/litepcie @@ -1 +1 @@ -Subproject commit 586ef787946512087a64fb60b79bdafe39aee6d0 +Subproject commit 61c202dc82fe7e36c55ccfebea41b37b6e553b68 diff --git a/third_party/litesata b/third_party/litesata index 2e5c5b12d..b36d3a33f 160000 --- a/third_party/litesata +++ b/third_party/litesata @@ -1 +1 @@ -Subproject commit 2e5c5b12d52f695f4560ca7dd08b4170d7568715 +Subproject commit b36d3a33fbbfcffdb77a7a9e05bc8121387858d3 diff --git a/third_party/litescope b/third_party/litescope index 54488c0f4..15179cb46 160000 --- a/third_party/litescope +++ b/third_party/litescope @@ -1 +1 @@ -Subproject commit 54488c0f4d6e9e953f1a0de3d578915a5e4ccddf +Subproject commit 15179cb46f68bff1679631a8bade6f7e1607a40a diff --git a/third_party/litex b/third_party/litex index 2d0188265..54598ed2f 160000 --- a/third_party/litex +++ b/third_party/litex @@ -1 +1 @@ -Subproject commit 2d018826532e486b94615c6b9cee4f16a924dba2 +Subproject commit 54598ed2f808a376c2b8bc57d4a7306049d617c0 diff --git a/third_party/litex-boards b/third_party/litex-boards index cb9596285..1356ebb41 160000 --- a/third_party/litex-boards +++ b/third_party/litex-boards @@ -1 +1 @@ -Subproject commit cb959628506e61cae2d7be05276bba8f42138cfb +Subproject commit 1356ebb416502d42620eeb66723508dee2b20aa3 diff --git a/third_party/litex-renode b/third_party/litex-renode index 7da392963..77df9bd84 160000 --- a/third_party/litex-renode +++ b/third_party/litex-renode @@ -1 +1 @@ -Subproject commit 7da392963878842f93f09a7a218c1052ae5e45d6 +Subproject commit 77df9bd84d6e85dd5fcb814b17ed6a1e808ad490 diff --git a/third_party/migen b/third_party/migen index 19d5eae29..b1b2b298b 160000 --- a/third_party/migen +++ b/third_party/migen @@ -1 +1 @@ -Subproject commit 19d5eae29b9ff57ea11540252f79ad1a9526ff3a +Subproject commit b1b2b298b85a795239daad84c75be073ddc4f8bd From ac61db2c9e64e6f027bae075aad0450a087a93a6 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 2 Jun 2020 12:47:19 +0200 Subject: [PATCH 133/153] Install missing python dependencies --- scripts/download-env.sh | 27 +++++++++++++++++++++++++++ scripts/enter-env.sh | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/scripts/download-env.sh b/scripts/download-env.sh index bce6c62cc..87b88e3c6 100755 --- a/scripts/download-env.sh +++ b/scripts/download-env.sh @@ -657,6 +657,33 @@ echo "Installing robotframework (python module)" pip install robotframework==3.0.4 check_import robot +( +cd $THIRD_DIR + +if [ ! -d pythondata-software-compiler_rt ]; then + git clone https://github.com/litex-hub/pythondata-software-compiler_rt.git +fi + +cd pythondata-software-compiler_rt +echo "Installing pythondata-software-compiler_rt (local python module)" +python setup.py develop +cd .. + +check_import pythondata_software_compiler_rt + + +if [ ! -d pythondata-cpu-$CPU ]; then + git clone https://github.com/litex-hub/pythondata-cpu-$CPU.git +fi + +cd pythondata-cpu-$CPU +echo "Installing pythondata-cpu-$CPU (local python module)" +python setup.py develop +cd .. + +check_import pythondata_cpu_$CPU +) + # git commands echo "" echo "Updating git config" diff --git a/scripts/enter-env.sh b/scripts/enter-env.sh index de0e3b509..058ecb021 100755 --- a/scripts/enter-env.sh +++ b/scripts/enter-env.sh @@ -554,6 +554,10 @@ check_import netifaces || return 1 check_import robot || return 1 +check_import pythondata_software_compiler_rt || return 1 + +check_import pythondata_cpu_$CPU || return 1 + # git commands echo "" echo "Updating git config" From d581cd5d6a32f2c94559b7b8633543248ffaa301 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 29 Jun 2020 09:44:37 +0200 Subject: [PATCH 134/153] firmware: Adapt to CPU/crt0 location changes --- firmware/Makefile | 6 +++--- firmware/linker-ctr.ld | 3 +++ firmware/linker-xip.ld | 3 +++ firmware/stub/Makefile | 6 +++--- firmware/stub/linker.ld | 3 +++ 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/firmware/Makefile b/firmware/Makefile index 3dd09fc77..9dc487275 100755 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -66,11 +66,11 @@ include $(UIP_DIRECTORY)/Makefile.mk LDFLAGS += \ +CRT0 = ../libbase/crt0.o + ifeq ($(COPY_TO_MAIN_RAM), 1) -CRT0 = ../libbase/crt0-$(CPU)-ctr.o LINKER_LD = linker-ctr.ld else -CRT0 = ../libbase/crt0-$(CPU)-xip.o LINKER_LD = linker-xip.ld endif @@ -106,7 +106,7 @@ firmware.elf: $(FIRMWARE_DIRECTORY)/$(LINKER_LD) $(OBJECTS) # pull in dependency info for *existing* .o files -include $(OBJECTS:.o=.d) -boot-helper-$(CPU).S: $(BIOS_DIRECTORY)/boot-helper-$(CPU).S +boot-helper-$(CPU).S: $(CPU_DIRECTORY)/boot-helper.S cp $< $@ boot-helper-$(CPU).o: boot-helper-$(CPU).S diff --git a/firmware/linker-ctr.ld b/firmware/linker-ctr.ld index 420a48d15..36af68283 100644 --- a/firmware/linker-ctr.ld +++ b/firmware/linker-ctr.ld @@ -51,3 +51,6 @@ SECTIONS } PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); + +PROVIDE(_fdata_rom = LOADADDR(.data)); +PROVIDE(_edata_rom = LOADADDR(.data) + SIZEOF(.data)); diff --git a/firmware/linker-xip.ld b/firmware/linker-xip.ld index d1df88804..aa308cbcf 100755 --- a/firmware/linker-xip.ld +++ b/firmware/linker-xip.ld @@ -56,3 +56,6 @@ SECTIONS } PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); + +PROVIDE(_fdata_rom = LOADADDR(.data)); +PROVIDE(_edata_rom = LOADADDR(.data) + SIZEOF(.data)); diff --git a/firmware/stub/Makefile b/firmware/stub/Makefile index dab79d5c8..1c0f4534c 100755 --- a/firmware/stub/Makefile +++ b/firmware/stub/Makefile @@ -35,11 +35,11 @@ endif firmware.elf: $(STUB_DIRECTORY)/$(LINKER_LD) $(OBJECTS) -%.elf: ../libbase/crt0-$(CPU)-xip.o ../libbase/libbase-nofloat.a ../libcompiler_rt/libcompiler_rt.a +%.elf: ../libbase/crt0.o ../libbase/libbase-nofloat.a ../libcompiler_rt/libcompiler_rt.a $(LD) $(LDFLAGS) \ -T $(STUB_DIRECTORY)/$(LINKER_LD) \ -N -o $@ \ - ../libbase/crt0-$(CPU)-xip.o \ + ../libbase/crt0.o \ $(OBJECTS) \ -L../libbase \ -lbase-nofloat \ @@ -51,7 +51,7 @@ firmware.elf: $(STUB_DIRECTORY)/$(LINKER_LD) $(OBJECTS) # pull in dependency info for *existing* .o files -include $(OBJECTS:.o=.d) -boot-helper-$(CPU).S: $(BIOS_DIRECTORY)/boot-helper-$(CPU).S +boot-helper-$(CPU).S: $(CPU_DIRECTORY)/boot-helper.S cp $< $@ boot-helper-$(CPU).o: boot-helper-$(CPU).S diff --git a/firmware/stub/linker.ld b/firmware/stub/linker.ld index d1df88804..aa308cbcf 100755 --- a/firmware/stub/linker.ld +++ b/firmware/stub/linker.ld @@ -56,3 +56,6 @@ SECTIONS } PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4); + +PROVIDE(_fdata_rom = LOADADDR(.data)); +PROVIDE(_edata_rom = LOADADDR(.data) + SIZEOF(.data)); From e27a63aeed8e788fa1da08d0108d984c05530b25 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 29 Jun 2020 09:44:37 +0200 Subject: [PATCH 135/153] firmware: Fix includes and flags --- firmware/ci.c | 1 - firmware/hdmi_in0.c | 15 ++++++++++++++- firmware/heartbeat.c | 1 - firmware/main.c | 1 - firmware/pattern.c | 1 - firmware/processor.c | 5 ++++- firmware/uip/liteethmac-drv.c | 4 +++- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/firmware/ci.c b/firmware/ci.c index 0a79b0c48..fdb92b384 100644 --- a/firmware/ci.c +++ b/firmware/ci.c @@ -21,7 +21,6 @@ #include #include -#include #include #include diff --git a/firmware/hdmi_in0.c b/firmware/hdmi_in0.c index ba2d34468..b88654eef 100644 --- a/firmware/hdmi_in0.c +++ b/firmware/hdmi_in0.c @@ -7,7 +7,6 @@ #include #include #include -#include #include "extra-flags.h" #include "stdio_wrap.h" @@ -22,6 +21,20 @@ int hdmi_in0_fb_index; //#define CLEAN_COMMUTATION //#define DEBUG +#define DVISAMPLER_TOO_LATE 0x1 +#define DVISAMPLER_TOO_EARLY 0x2 + +#define DVISAMPLER_DELAY_MASTER_CAL 0x01 +#define DVISAMPLER_DELAY_MASTER_RST 0x02 +#define DVISAMPLER_DELAY_SLAVE_CAL 0x04 +#define DVISAMPLER_DELAY_SLAVE_RST 0x08 +#define DVISAMPLER_DELAY_INC 0x10 +#define DVISAMPLER_DELAY_DEC 0x20 + +#define DVISAMPLER_SLOT_EMPTY 0 +#define DVISAMPLER_SLOT_LOADED 1 +#define DVISAMPLER_SLOT_PENDING 2 + fb_ptrdiff_t hdmi_in0_framebuffer_base(char n) { return HDMI_IN0_FRAMEBUFFERS_BASE + n * FRAMEBUFFER_SIZE; } diff --git a/firmware/heartbeat.c b/firmware/heartbeat.c index a5e78d167..8d9be3649 100644 --- a/firmware/heartbeat.c +++ b/firmware/heartbeat.c @@ -1,7 +1,6 @@ #include #include -#include #include #include diff --git a/firmware/main.c b/firmware/main.c index 6d0dcb624..8b0be58e2 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include diff --git a/firmware/pattern.c b/firmware/pattern.c index 087991f05..cbda4f125 100644 --- a/firmware/pattern.c +++ b/firmware/pattern.c @@ -2,7 +2,6 @@ #include #include -#include #include #include diff --git a/firmware/processor.c b/firmware/processor.c index 238551888..a3a2d0149 100644 --- a/firmware/processor.c +++ b/firmware/processor.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -37,6 +36,10 @@ #include "heartbeat.h" #include "pcie.h" +#define CLKGEN_STATUS_BUSY 0x1 +#define CLKGEN_STATUS_PROGDONE 0x2 +#define CLKGEN_STATUS_LOCKED 0x4 + /* ----------------->>> Time ----------->>> diff --git a/firmware/uip/liteethmac-drv.c b/firmware/uip/liteethmac-drv.c index 1ac5ba653..42fb1550c 100644 --- a/firmware/uip/liteethmac-drv.c +++ b/firmware/uip/liteethmac-drv.c @@ -9,11 +9,13 @@ #include #include #include -#include #include #include #include +#define ETHMAC_EV_SRAM_WRITER 0x1 +#define ETHMAC_EV_SRAM_READER 0x1 + #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) From f2cd4786fbb1ea61d166e52fe064e89bfbc45d63 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 4 Jun 2020 11:35:12 +0200 Subject: [PATCH 136/153] targets: Increase integrated rom size --- targets/arty/base.py | 5 ++++- targets/arty/net.py | 5 ++--- targets/atlys/base.py | 5 ++++- targets/atlys/net.py | 6 +++--- targets/basys3/base.py | 2 +- targets/cmod_a7/base.py | 2 +- targets/galatea/base.py | 2 +- targets/matrix_voice/base.py | 2 +- targets/mimas_a7/base.py | 5 ++++- targets/mimas_a7/bridge_net.py | 2 +- targets/mimas_a7/net.py | 4 ---- targets/mimasv2/base.py | 8 ++++++-- targets/minispartan6/base.py | 2 +- targets/neso/base.py | 2 +- targets/netv2/base.py | 2 +- targets/netv2/net.py | 2 -- targets/nexys_video/base.py | 2 +- targets/nexys_video/net.py | 4 ---- targets/opsis/base.py | 5 ++++- targets/opsis/net.py | 4 ---- targets/pano_logic_g2/base.py | 2 +- targets/pipistrello/base.py | 5 ++++- targets/saturn/base.py | 2 +- targets/sim/base.py | 2 +- targets/sim/net.py | 4 ---- targets/waxwing/base.py | 2 +- targets/waxwing/net.py | 2 +- 27 files changed, 45 insertions(+), 45 deletions(-) diff --git a/targets/arty/base.py b/targets/arty/base.py index da8cbaa78..3b621df4a 100755 --- a/targets/arty/base.py +++ b/targets/arty/base.py @@ -22,7 +22,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(100e6) diff --git a/targets/arty/net.py b/targets/arty/net.py index 009604804..0abf2c30f 100755 --- a/targets/arty/net.py +++ b/targets/arty/net.py @@ -13,9 +13,8 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): - # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if kwargs.get('cpu_type', 'lm32') != 'lm32': - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + # Need a larger integrated ROM to fit the BIOS with TFTP support. + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) BaseSoC.__init__(self, platform, *args, **kwargs) diff --git a/targets/atlys/base.py b/targets/atlys/base.py index af3f60bef..44aa14cf8 100644 --- a/targets/atlys/base.py +++ b/targets/atlys/base.py @@ -24,7 +24,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + if kwargs.get('cpu_type', None) == "mor1kx": + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = 75*1000000 diff --git a/targets/atlys/net.py b/targets/atlys/net.py index 53b4efb74..e989a0f8a 100644 --- a/targets/atlys/net.py +++ b/targets/atlys/net.py @@ -3,6 +3,7 @@ from liteeth.core.mac import LiteEthMAC from liteeth.phy import LiteEthPHY +from targets.utils import dict_set_max from .base import BaseSoC @@ -12,9 +13,8 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): - # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if kwargs.get('cpu_type', 'lm32') != 'lm32': - kwargs['integrated_rom_size'] = 0x10000 + # Need a larger integrated ROM to fit the BIOS with TFTP support. + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) BaseSoC.__init__(self, platform, *args, **kwargs) diff --git a/targets/basys3/base.py b/targets/basys3/base.py index 16c3936a3..c410e3854 100755 --- a/targets/basys3/base.py +++ b/targets/basys3/base.py @@ -19,7 +19,7 @@ class BaseSoC(SoCCore): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(100e6) diff --git a/targets/cmod_a7/base.py b/targets/cmod_a7/base.py index fecb9d2e0..b7e98defb 100755 --- a/targets/cmod_a7/base.py +++ b/targets/cmod_a7/base.py @@ -19,7 +19,7 @@ class BaseSoC(SoCCore): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(100e6) diff --git a/targets/galatea/base.py b/targets/galatea/base.py index 21519bcb9..1ecbb0512 100644 --- a/targets/galatea/base.py +++ b/targets/galatea/base.py @@ -23,7 +23,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) sys_clk_freq = 50*1000000 diff --git a/targets/matrix_voice/base.py b/targets/matrix_voice/base.py index aab5240f4..b31693942 100644 --- a/targets/matrix_voice/base.py +++ b/targets/matrix_voice/base.py @@ -27,7 +27,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) kwargs['uart_baudrate']=230400 diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index 2fa0fead0..446a21ec0 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -23,7 +23,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == "mor1kx": + dict_set_max(kwargs, 'integrated_rom_size', 0x14000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x10000) sys_clk_freq = int(100e6) diff --git a/targets/mimas_a7/bridge_net.py b/targets/mimas_a7/bridge_net.py index 1298ed2bf..fbff8c5ec 100755 --- a/targets/mimas_a7/bridge_net.py +++ b/targets/mimas_a7/bridge_net.py @@ -66,7 +66,7 @@ def __init__(self, platform, cpu_type=None, mac_address=0x10e2d5000000, ip_addre SoCCore.__init__(self, platform, clk_freq, cpu_type=None, integrated_main_ram_size=0x8000, - integrated_rom_size=0x8000, + integrated_rom_size=0x10000, integrated_sram_size=0x8000, csr_data_width=32, with_uart=False, diff --git a/targets/mimas_a7/net.py b/targets/mimas_a7/net.py index 31d8b5aa7..c571cfa2f 100755 --- a/targets/mimas_a7/net.py +++ b/targets/mimas_a7/net.py @@ -12,10 +12,6 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): - # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if 'integrated_rom_size' not in kwargs and kwargs.get('cpu_type', 'lm32') != 'lm32': - kwargs['integrated_rom_size'] = 0x10000 - BaseSoC.__init__(self, platform, *args, **kwargs) # Ethernet --------------------------------------------------------------------------------- diff --git a/targets/mimasv2/base.py b/targets/mimasv2/base.py index 67a38971b..b75d6c078 100644 --- a/targets/mimasv2/base.py +++ b/targets/mimasv2/base.py @@ -27,7 +27,7 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_sram_size', 0x4000) - + # disable ROM, it'll be added later kwargs['integrated_rom_size'] = 0x0 kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size @@ -99,7 +99,11 @@ def __init__(self, platform, **kwargs): self.mem_map["spiflash"], platform.spiflash_total_size) - bios_size = 0x8000 + if kwargs.get('cpu_type', None) == "mor1kx": + bios_size = 0x14000 + else: + bios_size = 0x10000 + self.add_constant("ROM_DISABLE", 1) self.add_memory_region( "rom", kwargs['cpu_reset_address'], bios_size, diff --git a/targets/minispartan6/base.py b/targets/minispartan6/base.py index 7e0ebe4c9..949c99fb5 100755 --- a/targets/minispartan6/base.py +++ b/targets/minispartan6/base.py @@ -81,7 +81,7 @@ def __init__(self, platform, **kwargs): self.mem_map["spiflash"], platform.spiflash_total_size) - bios_size = 0x8000 + bios_size = 0x10000 self.add_constant("ROM_DISABLE", 1) self.add_memory_region( "rom", kwargs['cpu_reset_address'], bios_size, diff --git a/targets/neso/base.py b/targets/neso/base.py index cf90635b4..363b6d314 100755 --- a/targets/neso/base.py +++ b/targets/neso/base.py @@ -89,7 +89,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) diff --git a/targets/netv2/base.py b/targets/netv2/base.py index 94abeb14d..317a2e4ac 100755 --- a/targets/netv2/base.py +++ b/targets/netv2/base.py @@ -102,7 +102,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, csr_data_width=8, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) diff --git a/targets/netv2/net.py b/targets/netv2/net.py index 0d3a4d5d2..4ef66f04c 100755 --- a/targets/netv2/net.py +++ b/targets/netv2/net.py @@ -14,8 +14,6 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) - BaseSoC.__init__(self, platform, *args, **kwargs) self.submodules.ethphy = LiteEthPHYRMII( diff --git a/targets/nexys_video/base.py b/targets/nexys_video/base.py index 73244f8f2..a6e76ef73 100755 --- a/targets/nexys_video/base.py +++ b/targets/nexys_video/base.py @@ -29,7 +29,7 @@ class BaseSoC(SoCSDRAM): # "uart_phy", def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(100e6) diff --git a/targets/nexys_video/net.py b/targets/nexys_video/net.py index 7484dd2b4..5c9d08812 100755 --- a/targets/nexys_video/net.py +++ b/targets/nexys_video/net.py @@ -14,10 +14,6 @@ class NetSoC(BaseSoC): ) def __init__(self, platform, *args, **kwargs): - # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if kwargs.get('cpu_type', 'lm32') != 'lm32': - kwargs['integrated_rom_size'] = 0x10000 - BaseSoC.__init__(self, platform, *args, **kwargs) # Ethernet PHY diff --git a/targets/opsis/base.py b/targets/opsis/base.py index 1e88b3917..e689e7efd 100644 --- a/targets/opsis/base.py +++ b/targets/opsis/base.py @@ -57,7 +57,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + if kwargs.get('cpu_type', None) == "mor1kx": + dict_set_max(kwargs, 'integrated_rom_size', 0x15000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = 50*1000000 diff --git a/targets/opsis/net.py b/targets/opsis/net.py index 7c829a2d7..3f8ec91ac 100644 --- a/targets/opsis/net.py +++ b/targets/opsis/net.py @@ -13,10 +13,6 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): - # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if kwargs.get('cpu_type', 'lm32') != 'lm32': - kwargs['integrated_rom_size'] = 0x10000 - BaseSoC.__init__(self, platform, *args, **kwargs) # Ethernet --------------------------------------------------------------------------------- diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index 0ee760b77..aa76e795f 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -23,7 +23,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(50e6) diff --git a/targets/pipistrello/base.py b/targets/pipistrello/base.py index 29e179ff6..945d7ab91 100644 --- a/targets/pipistrello/base.py +++ b/targets/pipistrello/base.py @@ -26,7 +26,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + if kwargs.get('cpu_type', None) == "mor1kx": + dict_set_max(kwargs, 'integrated_rom_size', 0x14000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) sys_clk_freq = (83 + Fraction(1, 3))*1000*1000 diff --git a/targets/saturn/base.py b/targets/saturn/base.py index 88acd576c..a061540db 100644 --- a/targets/saturn/base.py +++ b/targets/saturn/base.py @@ -26,7 +26,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) sys_clk_freq = (31 + Fraction(1, 4))*1000*1000 diff --git a/targets/sim/base.py b/targets/sim/base.py index d8c8accd2..4b378ea49 100644 --- a/targets/sim/base.py +++ b/targets/sim/base.py @@ -22,7 +22,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) dict_set_max(kwargs, 'firmware_ram_size', 0x10000) diff --git a/targets/sim/net.py b/targets/sim/net.py index 351eea87d..2192f799c 100644 --- a/targets/sim/net.py +++ b/targets/sim/net.py @@ -12,10 +12,6 @@ class NetSoC(BaseSoC): }} def __init__(self, *args, **kwargs): - # Need a larger integrated ROM on or1k to fit the BIOS with TFTP support. - if kwargs.get('cpu_type', 'lm32') != 'lm32': - kwargs['integrated_rom_size'] = 0x10000 - BaseSoC.__init__(self, *args, **kwargs) self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth")) diff --git a/targets/waxwing/base.py b/targets/waxwing/base.py index 598e1d3b9..fea6ea9d6 100644 --- a/targets/waxwing/base.py +++ b/targets/waxwing/base.py @@ -27,7 +27,7 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = (31 + Fraction(1, 4))*1000*1000 diff --git a/targets/waxwing/net.py b/targets/waxwing/net.py index 92f368be5..148c3916e 100755 --- a/targets/waxwing/net.py +++ b/targets/waxwing/net.py @@ -31,7 +31,7 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x8000) + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = (31 + Fraction(1, 4))*1000*1000 From d2bb7e2881666295392af52b93417a273e48f351 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 4 Jun 2020 17:38:36 +0200 Subject: [PATCH 137/153] Use 64-bit toolchain for RISC-V To make it consistent with LiteX --- Makefile | 9 ++++++++- scripts/download-env.sh | 2 +- scripts/enter-env.sh | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8cd32f301..ee395c838 100755 --- a/Makefile +++ b/Makefile @@ -394,12 +394,19 @@ ifeq ($(IN_TFTPD),) IN_TFTPD:=/usr/sbin/in.tftpd endif +ifeq ($(CPU),vexriscv) + ROOTFS_FILE := riscv32-rootfs.cpio +else + ROOTFS_FILE := $(CPU_ARCH)-rootfs.cpio +endif + tftp: $(FIRMWARE_FILEBASE).bin rm -rf $(TFTPD_DIR) mkdir -p $(TFTPD_DIR) + ifeq ($(FIRMWARE),linux) cp $(FIRMWARE_FILEBASE).bin $(TFTPD_DIR)/Image - cp $(FIRMWARE_DIR)/$(CPU_ARCH)-rootfs.cpio $(TFTPD_DIR)/rootfs.cpio + cp $(FIRMWARE_DIR)/$(ROOTFS_FILE) $(TFTPD_DIR)/rootfs.cpio ifeq ($(CPU),vexriscv) cp $(FIRMWARE_DIR)/rv32.dtb $(TFTPD_DIR) cp $(TARGET_BUILD_DIR)/emulator/emulator.bin $(TFTPD_DIR) diff --git a/scripts/download-env.sh b/scripts/download-env.sh index 87b88e3c6..4bd992996 100755 --- a/scripts/download-env.sh +++ b/scripts/download-env.sh @@ -98,7 +98,7 @@ if [ "$CPU" = "lm32" ]; then elif [ "$CPU" = "mor1kx" ]; then export CPU_ARCH=or1k elif [ "$CPU" = "vexriscv" -o "$CPU" = "picorv32" -o "$CPU" = "minerva" ]; then - export CPU_ARCH=riscv32 + export CPU_ARCH=riscv64 elif [ "$CPU" = "none" ]; then export CPU_ARCH=$(gcc -dumpmachine) else diff --git a/scripts/enter-env.sh b/scripts/enter-env.sh index 058ecb021..dd6d3e7cd 100755 --- a/scripts/enter-env.sh +++ b/scripts/enter-env.sh @@ -98,7 +98,7 @@ if [ "$CPU" = "lm32" ]; then elif [ "$CPU" = "mor1kx" ]; then export CPU_ARCH=or1k elif [ "$CPU" = "vexriscv" -o "$CPU" = "picorv32" -o "$CPU" = "minerva" ]; then - export CPU_ARCH=riscv32 + export CPU_ARCH=riscv64 elif [ "$CPU" = "none" ]; then export CPU_ARCH=$(gcc -dumpmachine) else From 503c9c9eafc1c77813ff4fd6837c221d35030330 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 5 Jun 2020 10:48:27 +0200 Subject: [PATCH 138/153] firmware: Get rid of a duplicated `busy_wait` function --- firmware/oled.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/firmware/oled.c b/firmware/oled.c index 76e27d363..f352da1cf 100644 --- a/firmware/oled.c +++ b/firmware/oled.c @@ -38,16 +38,6 @@ unsigned char oled_buffer[128*32/8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static void busy_wait(unsigned int ds) -{ - timer0_en_write(0); - timer0_reload_write(0); - timer0_load_write(CONFIG_CLOCK_FREQUENCY/100*ds); - timer0_en_write(1); - timer0_update_value_write(1); - while(timer0_value_read()) timer0_update_value_write(1); -} - void oled_spi_write(unsigned char value) { oled_spi_mosi_write(value); oled_spi_length_write(8); From d8fd94de25f539d2f6ef9e06b007d13fcc122440 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 5 Jun 2020 10:48:50 +0200 Subject: [PATCH 139/153] nexys_video: Adapt to reorganization in python packages --- targets/nexys_video/base.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/targets/nexys_video/base.py b/targets/nexys_video/base.py index a6e76ef73..515d81860 100755 --- a/targets/nexys_video/base.py +++ b/targets/nexys_video/base.py @@ -1,8 +1,7 @@ # Support for Digilent Nexys Video board from migen import * -from litex.soc.cores.uart import * #UART, RS232PHYInterface, RS232PHY, RS232PHYMultiplexer -from litex.soc.interconnect.wishbonebridge import WishboneStreamingBridge +from litex.soc.cores.uart import * #UART, RS232PHYInterface, RS232PHY, RS232PHYMultiplexer, Stream2Wishbone from litex.soc.integration.soc_sdram import * from litex.soc.integration.builder import * @@ -68,7 +67,7 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): # Extended UART ---------------------------------------------------------------------------- uart_interfaces = [RS232PHYInterface() for i in range(2)] self.submodules.uart = UART(uart_interfaces[0]) - self.submodules.bridge = WishboneStreamingBridge(uart_interfaces[1], sys_clk_freq) + self.submodules.bridge = Stream2Wishbone(uart_interfaces[1], sys_clk_freq) self.add_wb_master(self.bridge.wishbone) self.add_csr("uart") self.add_interrupt("uart") From 4838a8910c7fadc7616a1a4fe178ca7caa6a3969 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 5 Jun 2020 16:43:28 +0200 Subject: [PATCH 140/153] micropython: Fix building against the new LiteX --- scripts/build-micropython.sh | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/build-micropython.sh b/scripts/build-micropython.sh index 9f86f8556..bcbeea9ca 100755 --- a/scripts/build-micropython.sh +++ b/scripts/build-micropython.sh @@ -63,10 +63,13 @@ fi # in order to build; these need to end up in top level include directory # so that they are found by compiler/assembler. # -LITEX_INCLUDE_BASE="$PWD/third_party/litex/litex/soc/software/include/base" +LITEX_INCLUDE_BASE="$PWD/third_party/litex/litex/soc/cores/cpu/$CPU" for FILE in system.h csr-defs.h spr-defs.h; do - cp -p "$LITEX_INCLUDE_BASE/$FILE" "$TARGET_BUILD_DIR/software/include" + # spr-defs.h is available only for selected CPUs + if [ -e "$LITEX_INCLUDE_BASE/$FILE" ]; then + cp -p "$LITEX_INCLUDE_BASE/$FILE" "$TARGET_BUILD_DIR/software/include" + fi done # Setup the micropython build directory @@ -85,6 +88,14 @@ if [ ! -e "$TARGET_MPY_BUILD_DIR/hw" ]; then ln -s $(realpath $PWD/../../../../third_party/litex/litex/soc/software/include/hw) hw ) fi + +if [ ! -e "$TARGET_MPY_BUILD_DIR/base" ]; then + ( + cd $TARGET_MPY_BUILD_DIR + ln -s $(realpath $PWD/../../../../third_party/litex/litex/soc/software/include/base) base + ) +fi + TARGET_MPY_BUILD_DIR="$(realpath $TARGET_BUILD_DIR/software/micropython)" # Build micropython From a328ae9c6cdaeb1c118517b216f17607ba3d6bad Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 5 Jun 2020 17:30:57 +0200 Subject: [PATCH 141/153] micropython: Temporarily switch to Antmicro's fork This fork contains fixes necessary to build MicroPython against the new LiteX. --- scripts/build-micropython.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build-micropython.sh b/scripts/build-micropython.sh index bcbeea9ca..0c8b9390f 100755 --- a/scripts/build-micropython.sh +++ b/scripts/build-micropython.sh @@ -48,7 +48,7 @@ MPY_SRC_DIR=$TOP_DIR/third_party/micropython if [ ! -d "$MPY_SRC_DIR" ]; then ( cd $(dirname $MPY_SRC_DIR) - git clone https://github.com/fupy/micropython.git + git clone --branch new_litex https://github.com/antmicro/micropython.git cd $MPY_SRC_DIR git submodule update --init ) From 99258137d64ed48feebcaffaa484af3082e5d1d6 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 8 Jun 2020 11:20:28 +0200 Subject: [PATCH 142/153] VexRiscv: Add as a submodule This provides VexRiscv's emulator required by Linux. --- .gitmodules | 3 + ...-Use-external-hw-common.h-from-LiteX.patch | 82 ------------------- scripts/build-linux.sh | 11 +-- third_party/VexRiscv | 1 + 4 files changed, 6 insertions(+), 91 deletions(-) delete mode 100644 patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch create mode 160000 third_party/VexRiscv diff --git a/.gitmodules b/.gitmodules index 467761972..3a47222c9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,3 +43,6 @@ [submodule "third_party/liteiclink"] path = third_party/liteiclink url = https://github.com/enjoy-digital/liteiclink.git +[submodule "third_party/VexRiscv"] + path = third_party/VexRiscv + url = https://github.com/SpinalHDL/VexRiscv.git diff --git a/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch b/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch deleted file mode 100644 index 42e7bfdec..000000000 --- a/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch +++ /dev/null @@ -1,82 +0,0 @@ -From f88b259ebacb84624f2df3cfd14db56a5dd2ca4f Mon Sep 17 00:00:00 2001 -From: Mateusz Holenko -Date: Mon, 24 Feb 2020 12:43:35 +0100 -Subject: [PATCH] emulator: Use external hw/common.h from LiteX - -Remove code copied from `hw/common.h` and use -the header from the LiteX repository provided -using `LITEX_BASE` environment variable. - -Content of `common.h` is now evolving (new functions -are added, some are removed) and syncing it -between repos would be cumbersome. ---- - src/main/c/emulator/makefile | 7 ++++--- - src/main/c/emulator/src/hal.c | 32 -------------------------------- - 2 files changed, 4 insertions(+), 35 deletions(-) - -diff --git a/src/main/c/emulator/makefile b/src/main/c/emulator/makefile -index 7534d08..6f3c8fc 100755 ---- a/src/main/c/emulator/makefile -+++ b/src/main/c/emulator/makefile -@@ -18,10 +18,11 @@ sim: all - qemu: CFLAGS += -DQEMU - qemu: all - --litex: CFLAGS += -DLITEX -I${LITEX_BASE}/software/include --litex: | check_litex_base all --check_litex_base: -+litex: CFLAGS += -DLITEX -I${LITEX_GENERATED} -I${LITEX_BASE}/litex/soc/software/include -+litex: | check_litex all -+check_litex: - @[ "${LITEX_BASE}" ] || ( echo ">> LITEX_BASE is not set"; exit 1 ) -+ @[ "${LITEX_GENERATED}" ] || ( echo ">> LITEX_GENERATED is not set"; exit 1 ) - - include ${STANDALONE}/common/riscv64-unknown-elf.mk - include ${STANDALONE}/common/standalone.mk -diff --git a/src/main/c/emulator/src/hal.c b/src/main/c/emulator/src/hal.c -index 5a151bb..aa6745b 100644 ---- a/src/main/c/emulator/src/hal.c -+++ b/src/main/c/emulator/src/hal.c -@@ -146,38 +146,6 @@ void halInit(){ - - #ifdef LITEX - --// this is copied from LiteX --#define CSR_ACCESSORS_DEFINED --static inline void csr_writeb(uint8_t value, unsigned long addr) --{ -- *((volatile uint8_t *)addr) = value; --} -- --static inline uint8_t csr_readb(unsigned long addr) --{ -- return *(volatile uint8_t *)addr; --} -- --static inline void csr_writew(uint16_t value, unsigned long addr) --{ -- *((volatile uint16_t *)addr) = value; --} -- --static inline uint16_t csr_readw(unsigned long addr) --{ -- return *(volatile uint16_t *)addr; --} -- --static inline void csr_writel(uint32_t value, unsigned long addr) --{ -- *((volatile uint32_t *)addr) = value; --} -- --static inline uint32_t csr_readl(unsigned long addr) --{ -- return *(volatile uint32_t *)addr; --} -- - // this is a file generated by LiteX - #include - --- -2.25.0 - diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 0ac712769..864c3b9fa 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -173,17 +173,10 @@ if [ ${CPU} = vexriscv ]; then # get rid of 'L' suffix RAM_BASE_ADDRESS=${RAM_BASE_ADDRESS::-1} - # this is a temp fix for building the emulator - cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv - if [ ! -e .patched ]; then - git am $TOP_DIR/patches/0001-emulator-Use-external-hw-common.h-from-LiteX.patch - touch .patched - fi - - cd $TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv/verilog/ext/VexRiscv/src/main/c/emulator + cd $TOP_DIR/third_party/VexRiscv/src/main/c/emulator # offsets are hardcoded in BIOS - export CFLAGS="-DOS_CALL=$((RAM_BASE_ADDRESS + 0x0)) -DDTB=$((RAM_BASE_ADDRESS + 0x01000000)) -Wl,--defsym,__ram_origin=$((RAM_BASE_ADDRESS + 0x01100000))" + export CFLAGS="-DOS_CALL=$((RAM_BASE_ADDRESS + 0x0)) -DDTB=$((RAM_BASE_ADDRESS + 0x01000000)) -Wl,--defsym,__ram_origin=$((RAM_BASE_ADDRESS + 0x01100000)) -I$TOP_DIR/third_party/litex/litex/soc/cores/cpu/vexriscv" export LITEX_GENERATED="$TOP_DIR/$TARGET_BUILD_DIR/software/include" export LITEX_BASE="$TOP_DIR/third_party/litex" export RISCV_BIN="${CPU_ARCH}-elf-newlib-" diff --git a/third_party/VexRiscv b/third_party/VexRiscv new file mode 160000 index 000000000..2942d0652 --- /dev/null +++ b/third_party/VexRiscv @@ -0,0 +1 @@ +Subproject commit 2942d0652a89646c5225bee15dd55cc3b0871766 From 3022fc3361d74829f7de9d4e8b3f3a7df448ebc1 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 23 Jun 2020 17:52:23 +0200 Subject: [PATCH 143/153] targets: Fix building `net` platforms --- targets/arty/net.py | 2 +- targets/atlys/net.py | 2 +- targets/mimas_a7/net.py | 2 +- targets/netv2/net.py | 2 +- targets/nexys_video/net.py | 2 +- targets/opsis/net.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/targets/arty/net.py b/targets/arty/net.py index 0abf2c30f..834c18a87 100755 --- a/targets/arty/net.py +++ b/targets/arty/net.py @@ -1,6 +1,6 @@ from litex.soc.integration.soc_sdram import * -from liteeth.core.mac import LiteEthMAC +from liteeth.mac import LiteEthMAC from liteeth.phy import LiteEthPHY from targets.utils import dict_set_max diff --git a/targets/atlys/net.py b/targets/atlys/net.py index e989a0f8a..1465d9171 100644 --- a/targets/atlys/net.py +++ b/targets/atlys/net.py @@ -1,6 +1,6 @@ from litex.soc.integration.soc_sdram import * -from liteeth.core.mac import LiteEthMAC +from liteeth.mac import LiteEthMAC from liteeth.phy import LiteEthPHY from targets.utils import dict_set_max diff --git a/targets/mimas_a7/net.py b/targets/mimas_a7/net.py index c571cfa2f..36acb394b 100755 --- a/targets/mimas_a7/net.py +++ b/targets/mimas_a7/net.py @@ -1,6 +1,6 @@ from litex.soc.integration.soc_sdram import * -from liteeth.core.mac import LiteEthMAC +from liteeth.mac import LiteEthMAC from liteeth.phy.s7rgmii import LiteEthPHYRGMII from .base import BaseSoC diff --git a/targets/netv2/net.py b/targets/netv2/net.py index 4ef66f04c..1a90d50fc 100755 --- a/targets/netv2/net.py +++ b/targets/netv2/net.py @@ -1,7 +1,7 @@ from litex.soc.integration.soc_core import mem_decoder from litex.soc.integration.soc_sdram import * -from liteeth.core.mac import LiteEthMAC +from liteeth.mac import LiteEthMAC from liteeth.phy.rmii import LiteEthPHYRMII from targets.utils import dict_set_max diff --git a/targets/nexys_video/net.py b/targets/nexys_video/net.py index 5c9d08812..bd3fc4d85 100755 --- a/targets/nexys_video/net.py +++ b/targets/nexys_video/net.py @@ -1,7 +1,7 @@ from litex.soc.integration.soc_core import mem_decoder from litex.soc.integration.soc_sdram import * -from liteeth.core.mac import LiteEthMAC +from liteeth.mac import LiteEthMAC from liteeth.phy.s7rgmii import LiteEthPHYRGMII from targets.nexys_video.base import SoC as BaseSoC diff --git a/targets/opsis/net.py b/targets/opsis/net.py index 3f8ec91ac..ead09acba 100644 --- a/targets/opsis/net.py +++ b/targets/opsis/net.py @@ -1,6 +1,6 @@ from litex.soc.integration.soc_sdram import * -from liteeth.core.mac import LiteEthMAC +from liteeth.mac import LiteEthMAC from gateware.s6rgmii import LiteEthPHYRGMII From 2d322573426d2ad007eeadf2724b60a5fb0350d3 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 26 Jun 2020 12:50:52 +0200 Subject: [PATCH 144/153] make.py: Set EXECUTE_IN_PLACE/COPY_TO_MAIN_RAM flags This has been removed from LiteX, but is necessary for litex-buildenv's firmware. --- make.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/make.py b/make.py index 9530e7c32..be23d0291 100755 --- a/make.py +++ b/make.py @@ -137,6 +137,22 @@ def main(): buildargs['csr_json'] = os.path.join(testdir, "csr.json") builder = Builder(soc, **buildargs) + + if builder.bios_options is None: + builder.bios_options = {} + + # using 'bios_options' is a hack, as those settings + # are intended for the firmware (not bios) - there + # is just no dictionary for 'firmware_options' + # available in LiteX; + # the intended effect of setting those options is to + # generate entries in the .mak files that can be used + # in the Makefile + if 'user_flash' in soc.mem_regions: + builder.bios_options['EXECUTE_IN_PLACE'] = 1 + else: + builder.bios_options['COPY_TO_MAIN_RAM'] = 1 + if not args.no_compile_firmware or args.override_firmware: builder.add_software_package("uip", "{}/firmware/uip".format(os.getcwd())) From 8649374e04a5909730eb6cc765bac8db5dc8c67e Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 26 Jun 2020 14:46:27 +0200 Subject: [PATCH 145/153] Makefile: Fix bitstream file name --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ee395c838..fd59719a9 100755 --- a/Makefile +++ b/Makefile @@ -143,7 +143,7 @@ endif TARGET_BUILD_DIR = build/$(FULL_PLATFORM)_$(TARGET)_$(FULL_CPU) -GATEWARE_FILEBASE = $(TARGET_BUILD_DIR)/gateware/top +GATEWARE_FILEBASE = $(TARGET_BUILD_DIR)/gateware/$(PLATFORM) BIOS_FILE = $(TARGET_BUILD_DIR)/software/bios/bios.bin FIRMWARE_DIR = $(TARGET_BUILD_DIR)/software/$(FIRMWARE) FIRMWARE_FILEBASE = $(FIRMWARE_DIR)/firmware From 82057513b8234141712711e8258cebc2ae528a0b Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 26 Jun 2020 14:51:34 +0200 Subject: [PATCH 146/153] basys3: Add `user_flash` memory region --- targets/basys3/base.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/targets/basys3/base.py b/targets/basys3/base.py index c410e3854..a84fbf126 100755 --- a/targets/basys3/base.py +++ b/targets/basys3/base.py @@ -78,5 +78,15 @@ def __init__(self, platform, spiflash="spiflash_1x", **kwargs): self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size self.add_constant("FLASH_BOOT_ADDRESS", self.flash_boot_address) + # We don't have a DRAM, so use the remaining SPI flash for user + # program. + self.add_memory_region("user_flash", + self.flash_boot_address, + # Leave a grace area- possible one-by-off bug in add_memory_region? + # Possible fix: addr < origin + length - 1 + platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100, + type="cached+linker") + + SoC = BaseSoC From da4a474780921b700d95ed77aa49b966ea7cb1ee Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Fri, 26 Jun 2020 16:01:37 +0200 Subject: [PATCH 147/153] linux: Add `boot.json` helper file generation --- Makefile | 1 + scripts/build-linux.sh | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/Makefile b/Makefile index fd59719a9..c5b835f3d 100755 --- a/Makefile +++ b/Makefile @@ -408,6 +408,7 @@ ifeq ($(FIRMWARE),linux) cp $(FIRMWARE_FILEBASE).bin $(TFTPD_DIR)/Image cp $(FIRMWARE_DIR)/$(ROOTFS_FILE) $(TFTPD_DIR)/rootfs.cpio ifeq ($(CPU),vexriscv) + cp $(FIRMWARE_DIR)/boot.json $(TFTPD_DIR) cp $(FIRMWARE_DIR)/rv32.dtb $(TFTPD_DIR) cp $(TARGET_BUILD_DIR)/emulator/emulator.bin $(TFTPD_DIR) endif diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh index 864c3b9fa..43ebc7be0 100755 --- a/scripts/build-linux.sh +++ b/scripts/build-linux.sh @@ -281,6 +281,15 @@ else fetch_file $ROOTFS_LOCATION/$DTB_MD5-rv32.dtb $DTB_MD5 $TARGET_LINUX_BUILD_DIR/rv32.dtb + cat << EOF > $TARGET_LINUX_BUILD_DIR/boot.json +{ + "Image": "0x40000000", + "rootfs.cpio": "0x40800000", + "rv32.dtb": "0x41000000", + "emulator.bin": "0x41100000" +} +EOF + KERNEL_BINARY=Image make O="$TARGET_LINUX_BUILD_DIR" olddefconfig fi From c04580d3fdb77e6fab002d82821b8e22710f0c2d Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Mon, 29 Jun 2020 09:30:28 +0200 Subject: [PATCH 148/153] Disable running Linux tests on VexRiscv 653edd17ca87fe5443053bda07db8fd56b2ebb44 removes the option of booting Linux from flash in LiteX. --- scripts/test-renode.sh | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/scripts/test-renode.sh b/scripts/test-renode.sh index f5f06005c..bc548ef85 100755 --- a/scripts/test-renode.sh +++ b/scripts/test-renode.sh @@ -64,15 +64,9 @@ RENODE_REPL="$RENODE_SCRIPTS_DIR/litex_buildenv.repl" mkdir -p $RENODE_SCRIPTS_DIR if [ "$FIRMWARE" == "linux" ]; then - python $TOP_DIR/third_party/litex-renode/generate-renode-scripts.py $LITEX_CONFIG_FILE \ - --repl "$RENODE_REPL" \ - --resc "$RENODE_RESC" \ - --bios-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/bios/bios.bin" \ - --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/linux/arch/riscv/boot/Image:kernel_image_flash_offset" \ - --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/linux/riscv32-rootfs.cpio:rootfs_image_flash_offset"\ - --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/software/linux/rv32.dtb:device_tree_image_flash_offset" \ - --flash-binary "$TOP_DIR/$TARGET_BUILD_DIR/emulator/emulator.bin:emulator_image_flash_offset" - + # TODO: remove after this is handled in Renode + echo "Running Linux tests is currently not supported - skipping the test" + exit 0 else python $TOP_DIR/third_party/litex-renode/generate-renode-scripts.py $LITEX_CONFIG_FILE \ --repl "$RENODE_REPL" \ From a282f9c4f532aef6f0086f549190f1bfe2d188ec Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 4 Jun 2020 13:54:23 +0200 Subject: [PATCH 149/153] temporarily disable notifications --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 33d403c63..ca5cb5967 100644 --- a/.travis.yml +++ b/.travis.yml @@ -157,11 +157,3 @@ jobs: - env: C=lm32 TC="ise" P=atlys T="hdmi2usb" - env: C=lm32 TC="ise" P=opsis T="hdmi2usb" -notifications: - email: - - hdmi2usb-spam@googlegroups.com - irc: - channels: - - "chat.freenode.net#hdmi2usb" - template: - - "[%{repository_slug}/%{branch}#%{build_number}] (%{commit}): %{message} (%{build_url})" From 43be54fab07eb6315ff32779dc4380921e016b4a Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 25 Jun 2020 10:48:01 +0200 Subject: [PATCH 150/153] temporarily disable running Vivado/ISE in CI --- .travis/download-xilinx.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis/download-xilinx.sh b/.travis/download-xilinx.sh index 1ede84ca0..3801eb07f 100755 --- a/.travis/download-xilinx.sh +++ b/.travis/download-xilinx.sh @@ -2,6 +2,7 @@ # Cutback Xilinx ISE for CI # -------- # Save the passphrase to a file so we don't echo it in the logs +XILINX_PASSPHRASE="" if [ ! -z "$XILINX_PASSPHRASE" ]; then XILINX_PASSPHRASE_FILE=$(tempfile -s .passphrase | mktemp --suffix=.passphrase) trap "rm -f -- '$XILINX_PASSPHRASE_FILE'" EXIT From da5b557c227e4a53d4ae416c7a5e66b7ed232afc Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Thu, 4 Jun 2020 13:12:23 +0200 Subject: [PATCH 151/153] temporarily disable failing on dirty repo --- .travis/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis/build.sh b/.travis/build.sh index aa07dccf1..285bd5150 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -138,7 +138,7 @@ function build() { git submodule foreach --recursive git status git status git diff - exit 1 + # exit 1 fi if grep -q -- "-dirty" $VERSION_DATA; then @@ -147,7 +147,7 @@ function build() { git submodule foreach --recursive git status git status git diff - exit 1 + # exit 1 fi fi echo "=============================================" From 530879c564cd45a034b30d8176e9882b99178c24 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 30 Jun 2020 12:30:11 +0200 Subject: [PATCH 152/153] ffix --- targets/basys3/base.py | 5 ++++- targets/cmod_a7/base.py | 5 ++++- targets/galatea/base.py | 5 ++++- targets/matrix_voice/base.py | 5 ++++- targets/mimas_a7/base.py | 4 ++-- targets/mimas_a7/net.py | 4 ++++ targets/mimasv2/base.py | 4 ++-- targets/minispartan6/base.py | 6 +++++- targets/neso/base.py | 5 ++++- targets/netv2/base.py | 5 ++++- targets/netv2/net.py | 3 +++ targets/nexys_video/base.py | 5 ++++- targets/nexys_video/net.py | 4 ++++ targets/opsis/base.py | 4 ++-- targets/opsis/net.py | 4 ++++ targets/pano_logic_g2/base.py | 5 ++++- targets/pipistrello/base.py | 4 ++-- targets/saturn/base.py | 5 ++++- targets/sim/base.py | 4 ++++ targets/sim/net.py | 4 ++++ targets/waxwing/base.py | 5 ++++- targets/waxwing/net.py | 2 +- 22 files changed, 77 insertions(+), 20 deletions(-) diff --git a/targets/basys3/base.py b/targets/basys3/base.py index a84fbf126..6ba36973f 100755 --- a/targets/basys3/base.py +++ b/targets/basys3/base.py @@ -19,7 +19,10 @@ class BaseSoC(SoCCore): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(100e6) diff --git a/targets/cmod_a7/base.py b/targets/cmod_a7/base.py index b7e98defb..2bfb545bf 100755 --- a/targets/cmod_a7/base.py +++ b/targets/cmod_a7/base.py @@ -19,7 +19,10 @@ class BaseSoC(SoCCore): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(100e6) diff --git a/targets/galatea/base.py b/targets/galatea/base.py index 1ecbb0512..a65c3c3d3 100644 --- a/targets/galatea/base.py +++ b/targets/galatea/base.py @@ -23,7 +23,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) sys_clk_freq = 50*1000000 diff --git a/targets/matrix_voice/base.py b/targets/matrix_voice/base.py index b31693942..a89695918 100644 --- a/targets/matrix_voice/base.py +++ b/targets/matrix_voice/base.py @@ -27,7 +27,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) kwargs['uart_baudrate']=230400 diff --git a/targets/mimas_a7/base.py b/targets/mimas_a7/base.py index 446a21ec0..6a0919b3d 100755 --- a/targets/mimas_a7/base.py +++ b/targets/mimas_a7/base.py @@ -24,9 +24,9 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, spiflash="spiflash_1x", **kwargs): if kwargs.get('cpu_type', None) == "mor1kx": - dict_set_max(kwargs, 'integrated_rom_size', 0x14000) - else: dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x10000) sys_clk_freq = int(100e6) diff --git a/targets/mimas_a7/net.py b/targets/mimas_a7/net.py index 36acb394b..e4d3d6547 100755 --- a/targets/mimas_a7/net.py +++ b/targets/mimas_a7/net.py @@ -3,6 +3,7 @@ from liteeth.mac import LiteEthMAC from liteeth.phy.s7rgmii import LiteEthPHYRGMII +from targets.utils import dict_set_max from .base import BaseSoC @@ -12,6 +13,9 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): + # Need a larger integrated ROM to fit the BIOS with TFTP support. + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + BaseSoC.__init__(self, platform, *args, **kwargs) # Ethernet --------------------------------------------------------------------------------- diff --git a/targets/mimasv2/base.py b/targets/mimasv2/base.py index b75d6c078..61e7fd718 100644 --- a/targets/mimasv2/base.py +++ b/targets/mimasv2/base.py @@ -100,9 +100,9 @@ def __init__(self, platform, **kwargs): platform.spiflash_total_size) if kwargs.get('cpu_type', None) == "mor1kx": - bios_size = 0x14000 - else: bios_size = 0x10000 + else: + bios_size = 0x8000 self.add_constant("ROM_DISABLE", 1) self.add_memory_region( diff --git a/targets/minispartan6/base.py b/targets/minispartan6/base.py index 949c99fb5..cef5b2edf 100755 --- a/targets/minispartan6/base.py +++ b/targets/minispartan6/base.py @@ -81,7 +81,11 @@ def __init__(self, platform, **kwargs): self.mem_map["spiflash"], platform.spiflash_total_size) - bios_size = 0x10000 + if kwargs.get('cpu_type', None) == "mor1kx": + bios_size = 0x10000 + else: + bios_size = 0x8000 + self.add_constant("ROM_DISABLE", 1) self.add_memory_region( "rom", kwargs['cpu_reset_address'], bios_size, diff --git a/targets/neso/base.py b/targets/neso/base.py index 363b6d314..4b0b3fe5e 100755 --- a/targets/neso/base.py +++ b/targets/neso/base.py @@ -89,7 +89,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) diff --git a/targets/netv2/base.py b/targets/netv2/base.py index 317a2e4ac..9de67b76a 100755 --- a/targets/netv2/base.py +++ b/targets/netv2/base.py @@ -102,7 +102,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, csr_data_width=8, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = int(100e6) diff --git a/targets/netv2/net.py b/targets/netv2/net.py index 1a90d50fc..dbed5bb5d 100755 --- a/targets/netv2/net.py +++ b/targets/netv2/net.py @@ -14,6 +14,9 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): + # Need a larger integrated ROM to fit the BIOS with TFTP support. + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + BaseSoC.__init__(self, platform, *args, **kwargs) self.submodules.ethphy = LiteEthPHYRMII( diff --git a/targets/nexys_video/base.py b/targets/nexys_video/base.py index 515d81860..39ad38a63 100755 --- a/targets/nexys_video/base.py +++ b/targets/nexys_video/base.py @@ -28,7 +28,10 @@ class BaseSoC(SoCSDRAM): # "uart_phy", def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(100e6) diff --git a/targets/nexys_video/net.py b/targets/nexys_video/net.py index bd3fc4d85..265dbd991 100755 --- a/targets/nexys_video/net.py +++ b/targets/nexys_video/net.py @@ -4,6 +4,7 @@ from liteeth.mac import LiteEthMAC from liteeth.phy.s7rgmii import LiteEthPHYRGMII +from targets.utils import dict_set_max from targets.nexys_video.base import SoC as BaseSoC @@ -14,6 +15,9 @@ class NetSoC(BaseSoC): ) def __init__(self, platform, *args, **kwargs): + # Need a larger integrated ROM to fit the BIOS with TFTP support. + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + BaseSoC.__init__(self, platform, *args, **kwargs) # Ethernet PHY diff --git a/targets/opsis/base.py b/targets/opsis/base.py index e689e7efd..12640106b 100644 --- a/targets/opsis/base.py +++ b/targets/opsis/base.py @@ -58,9 +58,9 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, **kwargs): if kwargs.get('cpu_type', None) == "mor1kx": - dict_set_max(kwargs, 'integrated_rom_size', 0x15000) - else: dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = 50*1000000 diff --git a/targets/opsis/net.py b/targets/opsis/net.py index ead09acba..47e9090e6 100644 --- a/targets/opsis/net.py +++ b/targets/opsis/net.py @@ -4,6 +4,7 @@ from gateware.s6rgmii import LiteEthPHYRGMII +from targets.utils import dict_set_max from .base import BaseSoC @@ -13,6 +14,9 @@ class NetSoC(BaseSoC): }} def __init__(self, platform, *args, **kwargs): + # Need a larger integrated ROM to fit the BIOS with TFTP support. + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + BaseSoC.__init__(self, platform, *args, **kwargs) # Ethernet --------------------------------------------------------------------------------- diff --git a/targets/pano_logic_g2/base.py b/targets/pano_logic_g2/base.py index aa76e795f..7dc77dbd5 100755 --- a/targets/pano_logic_g2/base.py +++ b/targets/pano_logic_g2/base.py @@ -23,7 +23,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = int(50e6) diff --git a/targets/pipistrello/base.py b/targets/pipistrello/base.py index 945d7ab91..5fb820c6f 100644 --- a/targets/pipistrello/base.py +++ b/targets/pipistrello/base.py @@ -27,9 +27,9 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, **kwargs): if kwargs.get('cpu_type', None) == "mor1kx": - dict_set_max(kwargs, 'integrated_rom_size', 0x14000) - else: dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) sys_clk_freq = (83 + Fraction(1, 3))*1000*1000 diff --git a/targets/saturn/base.py b/targets/saturn/base.py index a061540db..a393acfc6 100644 --- a/targets/saturn/base.py +++ b/targets/saturn/base.py @@ -26,7 +26,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x4000) sys_clk_freq = (31 + Fraction(1, 4))*1000*1000 diff --git a/targets/sim/base.py b/targets/sim/base.py index 4b378ea49..216042b9d 100644 --- a/targets/sim/base.py +++ b/targets/sim/base.py @@ -23,6 +23,10 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, **kwargs): dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) dict_set_max(kwargs, 'firmware_ram_size', 0x10000) diff --git a/targets/sim/net.py b/targets/sim/net.py index 2192f799c..7028e136a 100644 --- a/targets/sim/net.py +++ b/targets/sim/net.py @@ -3,6 +3,7 @@ from liteeth.phy.model import LiteEthPHYModel from liteeth.core.mac import LiteEthMAC +from targets.utils import dict_set_max from targets.sim.base import BaseSoC @@ -12,6 +13,9 @@ class NetSoC(BaseSoC): }} def __init__(self, *args, **kwargs): + # Need a larger integrated ROM to fit the BIOS with TFTP support. + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + BaseSoC.__init__(self, *args, **kwargs) self.submodules.ethphy = LiteEthPHYModel(self.platform.request("eth")) diff --git a/targets/waxwing/base.py b/targets/waxwing/base.py index fea6ea9d6..1c38649c2 100644 --- a/targets/waxwing/base.py +++ b/targets/waxwing/base.py @@ -27,7 +27,10 @@ class BaseSoC(SoCSDRAM): }} def __init__(self, platform, **kwargs): - dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + if kwargs.get('cpu_type', None) == 'mor1kx': + dict_set_max(kwargs, 'integrated_rom_size', 0x10000) + else: + dict_set_max(kwargs, 'integrated_rom_size', 0x8000) dict_set_max(kwargs, 'integrated_sram_size', 0x8000) sys_clk_freq = (31 + Fraction(1, 4))*1000*1000 diff --git a/targets/waxwing/net.py b/targets/waxwing/net.py index 148c3916e..b8402e19b 100755 --- a/targets/waxwing/net.py +++ b/targets/waxwing/net.py @@ -31,8 +31,8 @@ class BaseSoC(SoCSDRAM): def __init__(self, platform, **kwargs): + # Need a larger integrated ROM to fit the BIOS with TFTP support. dict_set_max(kwargs, 'integrated_rom_size', 0x10000) - dict_set_max(kwargs, 'integrated_sram_size', 0x8000) clk_freq = (31 + Fraction(1, 4))*1000*1000 SoCSDRAM.__init__(self, platform, clk_freq, **kwargs) From 6cf61713d9c32dcfca3eeb8532435ee0fb05b130 Mon Sep 17 00:00:00 2001 From: Mateusz Holenko Date: Tue, 30 Jun 2020 13:11:36 +0200 Subject: [PATCH 153/153] x --- targets/basys3/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/basys3/base.py b/targets/basys3/base.py index 6ba36973f..50666e1aa 100755 --- a/targets/basys3/base.py +++ b/targets/basys3/base.py @@ -19,7 +19,7 @@ class BaseSoC(SoCCore): }} def __init__(self, platform, spiflash="spiflash_1x", **kwargs): - if kwargs.get('cpu_type', None) == 'mor1kx': + if kwargs.get('cpu_type', None) == 'mor1kx': dict_set_max(kwargs, 'integrated_rom_size', 0x10000) else: dict_set_max(kwargs, 'integrated_rom_size', 0x8000)