diff --git a/CHANGES b/CHANGES index f6572c018..787c3b833 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,8 @@ - BIOS: rename/reorganize commands. - litex_server: simplify usage with PCIe and add debug parameter. - LitePCIe: add Ultrascale(+) support up to Gen3 X16. + - LiteSATA: add BIOS/Boot integration. + - Add litex_cli to provides common RemoteClient functions: get identifier, dump regs, etc... [> API changes/Deprecation -------------------------- diff --git a/litex/boards/platforms/arty.py b/litex/boards/platforms/arty.py index 663083b07..5d8254745 100644 --- a/litex/boards/platforms/arty.py +++ b/litex/boards/platforms/arty.py @@ -12,6 +12,12 @@ from litex.build.openocd import OpenOCD # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst + ("clk100", 0, Pins("E3"), IOStandard("LVCMOS33")), + ("cpu_reset", 0, Pins("C2"), IOStandard("LVCMOS33")), + + + # Leds ("user_led", 0, Pins("H5"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("J5"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("T9"), IOStandard("LVCMOS33")), @@ -23,21 +29,18 @@ _io = [ Subsignal("b", Pins("E1")), IOStandard("LVCMOS33"), ), - ("rgb_led", 1, Subsignal("r", Pins("G3")), Subsignal("g", Pins("J4")), Subsignal("b", Pins("G4")), IOStandard("LVCMOS33"), ), - ("rgb_led", 2, Subsignal("r", Pins("J3")), Subsignal("g", Pins("J2")), Subsignal("b", Pins("H4")), IOStandard("LVCMOS33"), ), - ("rgb_led", 3, Subsignal("r", Pins("K1")), Subsignal("g", Pins("H6")), @@ -45,26 +48,26 @@ _io = [ IOStandard("LVCMOS33"), ), + # Switches ("user_sw", 0, Pins("A8"), IOStandard("LVCMOS33")), ("user_sw", 1, Pins("C11"), IOStandard("LVCMOS33")), ("user_sw", 2, Pins("C10"), IOStandard("LVCMOS33")), ("user_sw", 3, Pins("A10"), IOStandard("LVCMOS33")), + # Buttons ("user_btn", 0, Pins("D9"), IOStandard("LVCMOS33")), ("user_btn", 1, Pins("C9"), IOStandard("LVCMOS33")), ("user_btn", 2, Pins("B9"), IOStandard("LVCMOS33")), ("user_btn", 3, Pins("B8"), IOStandard("LVCMOS33")), - ("clk100", 0, Pins("E3"), IOStandard("LVCMOS33")), - - ("cpu_reset", 0, Pins("C2"), IOStandard("LVCMOS33")), - + # Serial ("serial", 0, Subsignal("tx", Pins("D10")), Subsignal("rx", Pins("A9")), IOStandard("LVCMOS33") ), + # SPI ("spi", 0, Subsignal("clk", Pins("F1")), Subsignal("cs_n", Pins("C1")), @@ -73,6 +76,7 @@ _io = [ IOStandard("LVCMOS33"), ), + # I2C ("i2c", 0, Subsignal("scl", Pins("L18")), Subsignal("sda", Pins("M18")), @@ -81,12 +85,7 @@ _io = [ IOStandard("LVCMOS33"), ), - ("spiflash4x", 0, - Subsignal("cs_n", Pins("L13")), - Subsignal("clk", Pins("L16")), - Subsignal("dq", Pins("K17", "K18", "L14", "M14")), - IOStandard("LVCMOS33") - ), + # SPIFlash ("spiflash", 0, Subsignal("cs_n", Pins("L13")), Subsignal("clk", Pins("L16")), @@ -96,7 +95,14 @@ _io = [ Subsignal("hold", Pins("M14")), IOStandard("LVCMOS33"), ), + ("spiflash4x", 0, + Subsignal("cs_n", Pins("L13")), + Subsignal("clk", Pins("L16")), + Subsignal("dq", Pins("K17", "K18", "L14", "M14")), + IOStandard("LVCMOS33") + ), + # DDR3 SDRAM ("ddram", 0, Subsignal("a", Pins( "R2 M6 N4 T1 N6 R7 V6 U7", @@ -127,6 +133,7 @@ _io = [ Misc("SLEW=FAST"), ), + # MII Ethernet ("eth_ref_clk", 0, Pins("G18"), IOStandard("LVCMOS33")), ("eth_clocks", 0, Subsignal("tx", Pins("H16")), diff --git a/litex/boards/platforms/avalanche.py b/litex/boards/platforms/avalanche.py index f19ce8989..9e500f279 100644 --- a/litex/boards/platforms/avalanche.py +++ b/litex/boards/platforms/avalanche.py @@ -10,31 +10,29 @@ from litex.build.microsemi import MicrosemiPlatform # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst ("clk50", 0, Pins("R1"), IOStandard("LVCMOS25")), ("clk50", 1, Pins("J3"), IOStandard("LVCMOS25")), - ("rst_n", 0, Pins("F5"), IOStandard("LVCMOS33")), + # Leds ("user_led", 0, Pins("D6"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("D7"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("D8"), IOStandard("LVCMOS33")), ("user_led", 3, Pins("D9"), IOStandard("LVCMOS33")), + # Buttons ("user_btn", 0, Pins("E13"), IOStandard("LVCMOS33")), ("user_btn", 1, Pins("E14"), IOStandard("LVCMOS33")), + # Serial ("serial", 0, Subsignal("tx", Pins("F17")), Subsignal("rx", Pins("F16")), IOStandard("LVCMOS33") ), - ("spiflash4x", 0, - Subsignal("clk", Pins("J1")), - Subsignal("cs_n", Pins("H1")), - Subsignal("dq", Pins("F2 F1 M7 M8")), - IOStandard("LVCMOS25") - ), + # SPIFlash ("spiflash", 0, Subsignal("clk", Pins("J1")), Subsignal("cs_n", Pins("H1")), @@ -44,7 +42,14 @@ _io = [ Subsignal("hold", Pins("M8")), IOStandard("LVCMOS25"), ), + ("spiflash4x", 0, + Subsignal("clk", Pins("J1")), + Subsignal("cs_n", Pins("H1")), + Subsignal("dq", Pins("F2 F1 M7 M8")), + IOStandard("LVCMOS25") + ), + # DDR3 SDRAM ("ddram", 0, Subsignal("a", Pins( "U5 U4 V4 W3 V5 W4 Y3 AA3", @@ -69,6 +74,7 @@ _io = [ Subsignal("reset_n", Pins("AB7"), IOStandard("SSTL15II")), ), + # Ethernet ("eth_clocks", 0, Subsignal("tx", Pins("J8")), Subsignal("rx", Pins("K3")), diff --git a/litex/boards/platforms/de0nano.py b/litex/boards/platforms/de0nano.py index 3d93aaeaa..320ae0e58 100644 --- a/litex/boards/platforms/de0nano.py +++ b/litex/boards/platforms/de0nano.py @@ -11,8 +11,10 @@ from litex.build.altera.programmer import USBBlaster # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk ("clk50", 0, Pins("R8"), IOStandard("3.3-V LVTTL")), + # Leds ("user_led", 0, Pins("A15"), IOStandard("3.3-V LVTTL")), ("user_led", 1, Pins("A13"), IOStandard("3.3-V LVTTL")), ("user_led", 2, Pins("B13"), IOStandard("3.3-V LVTTL")), @@ -22,14 +24,17 @@ _io = [ ("user_led", 6, Pins("B1"), IOStandard("3.3-V LVTTL")), ("user_led", 7, Pins("L3"), IOStandard("3.3-V LVTTL")), + # Button ("key", 0, Pins("J15"), IOStandard("3.3-V LVTTL")), ("key", 1, Pins("E1"), IOStandard("3.3-V LVTTL")), + # Switches ("sw", 0, Pins("M1"), IOStandard("3.3-V LVTTL")), ("sw", 1, Pins("T8"), IOStandard("3.3-V LVTTL")), ("sw", 2, Pins("B9"), IOStandard("3.3-V LVTTL")), ("sw", 3, Pins("M15"), IOStandard("3.3-V LVTTL")), + # Serial ("serial", 0, # Compatible with cheap FT232 based cables (ex: Gaoominy 6Pin Ftdi Ft232Rl Ft232) # GND on JP1 Pin 12. @@ -37,6 +42,7 @@ _io = [ Subsignal("rx", Pins("B4"), IOStandard("3.3-V LVTTL")) # GPIO_05 (JP1 Pin 8) ), + # SDR SDRAM ("sdram_clock", 0, Pins("R4"), IOStandard("3.3-V LVTTL")), ("sdram", 0, Subsignal("a", Pins( @@ -55,6 +61,7 @@ _io = [ IOStandard("3.3-V LVTTL") ), + # ECPS ("epcs", 0, Subsignal("data0", Pins("H2")), Subsignal("dclk", Pins("H1")), @@ -63,18 +70,21 @@ _io = [ IOStandard("3.3-V LVTTL") ), + # I2C ("i2c", 0, Subsignal("sclk", Pins("F2")), Subsignal("sdat", Pins("F1")), IOStandard("3.3-V LVTTL") ), - ("g_sensor", 0, + # Accelerometer + ("acc", 0, Subsignal("cs_n", Pins("G5")), Subsignal("int", Pins("M2")), IOStandard("3.3-V LVTTL") ), + # ADC ("adc", 0, Subsignal("cs_n", Pins("A10")), Subsignal("saddr", Pins("B10")), @@ -83,6 +93,7 @@ _io = [ IOStandard("3.3-V LVTTL") ), + # GPIOs ("gpio_0", 0, Pins( "D3 C3 A2 A3 B3 B4 A4 B5", "A5 D5 B6 A6 B7 D6 A7 C6", diff --git a/litex/boards/platforms/genesys2.py b/litex/boards/platforms/genesys2.py index 52c755e29..1c7e85e93 100644 --- a/litex/boards/platforms/genesys2.py +++ b/litex/boards/platforms/genesys2.py @@ -11,6 +11,14 @@ from litex.build.openocd import OpenOCD # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst + ("clk200", 0, + Subsignal("p", Pins("AD12"), IOStandard("LVDS")), + Subsignal("n", Pins("AD11"), IOStandard("LVDS")) + ), + ("cpu_reset_n", 0, Pins("R19"), IOStandard("LVCMOS33")), + + # Leds ("user_led", 0, Pins("T28"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("V19"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("U30"), IOStandard("LVCMOS33")), @@ -20,14 +28,14 @@ _io = [ ("user_led", 6, Pins("W24"), IOStandard("LVCMOS33")), ("user_led", 7, Pins("W23"), IOStandard("LVCMOS33")), - ("cpu_reset_n", 0, Pins("R19"), IOStandard("LVCMOS33")), - + # Buttons ("user_btn_c", 0, Pins("E18"), IOStandard("LVCMOS33")), ("user_btn_d", 0, Pins("M19"), IOStandard("LVCMOS33")), ("user_btn_l", 0, Pins("M20"), IOStandard("LVCMOS33")), ("user_btn_r", 0, Pins("C19"), IOStandard("LVCMOS33")), ("user_btn_u", 0, Pins("B19"), IOStandard("LVCMOS33")), + # Switches ("user_sw", 0, Pins("G19"), IOStandard("LVCMOS12")), ("user_sw", 1, Pins("G25"), IOStandard("LVCMOS12")), ("user_sw", 2, Pins("H24"), IOStandard("LVCMOS12")), @@ -37,17 +45,14 @@ _io = [ ("user_sw", 6, Pins("P26"), IOStandard("LVCMOS33")), ("user_sw", 7, Pins("P27"), IOStandard("LVCMOS33")), - ("clk200", 0, - Subsignal("p", Pins("AD12"), IOStandard("LVDS")), - Subsignal("n", Pins("AD11"), IOStandard("LVDS")) - ), - + # Serial ("serial", 0, Subsignal("tx", Pins("Y23")), Subsignal("rx", Pins("Y20")), IOStandard("LVCMOS33") ), + # USB FIFO ("usb_fifo", 0, # Can be used when FT2232H's Channel A configured to ASYNC FIFO 245 mode Subsignal("data", Pins("AD27 W27 W28 W29 Y29 Y28 AA28 AA26")), Subsignal("rxf_n", Pins("AB29")), @@ -61,14 +66,7 @@ _io = [ IOStandard("LVCMOS33"), ), - ("sdcard", 0, - Subsignal("clk", Pins("R28")), - Subsignal("cmd", Pins("R29"), Misc("PULLUP True")), - Subsignal("data", Pins("R26 R30 P29 T30"), Misc("PULLUP True")), - Misc("SLEW=FAST"), - IOStandard("LVCMOS33") - ), - + # SDCard ("spisdcard", 0, Subsignal("clk", Pins("R28")), Subsignal("cs_n", Pins("T30")), @@ -77,7 +75,16 @@ _io = [ Misc("SLEW=FAST"), IOStandard("LVCMOS33") ), + ("sdcard", 0, + Subsignal("clk", Pins("R28")), + Subsignal("cmd", Pins("R29"), Misc("PULLUP True")), + Subsignal("data", Pins("R26 R30 P29 T30"), Misc("PULLUP True")), + Misc("SLEW=FAST"), + IOStandard("LVCMOS33") + ), + + # DDR3 SDRAM ("ddram", 0, Subsignal("a", Pins( "AC12 AE8 AD8 AC10 AD9 AA13 AA10 AA11", @@ -109,6 +116,7 @@ _io = [ Misc("VCCAUX_IO=HIGH") ), + # RGMII Ethernet ("eth_clocks", 0, Subsignal("tx", Pins("AE10")), Subsignal("rx", Pins("AG10")), diff --git a/litex/boards/platforms/icebreaker.py b/litex/boards/platforms/icebreaker.py index d2cc9fc51..a2fb92184 100644 --- a/litex/boards/platforms/icebreaker.py +++ b/litex/boards/platforms/icebreaker.py @@ -16,19 +16,27 @@ from litex.build.lattice.programmer import IceStormProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst + ("clk12", 0, Pins("35"), IOStandard("LVCMOS33")) + + # Leds ("user_led_n", 0, Pins("11"), IOStandard("LVCMOS33")), ("user_led_n", 1, Pins("37"), IOStandard("LVCMOS33")), - # Color-specific aliases - ("user_ledr_n", 0, Pins("11"), IOStandard("LVCMOS33")), - ("user_ledg_n", 0, Pins("37"), IOStandard("LVCMOS33")), + + ("user_ledr_n", 0, Pins("11"), IOStandard("LVCMOS33")), # Color-specific alias + ("user_ledg_n", 0, Pins("37"), IOStandard("LVCMOS33")), # Color-specific alias + + # Button ("user_btn_n", 0, Pins("10"), IOStandard("LVCMOS33")), + # Serial ("serial", 0, Subsignal("rx", Pins("6")), Subsignal("tx", Pins("9"), Misc("PULLUP")), IOStandard("LVCMOS33") ), + # SPIFlash ("spiflash", 0, Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")), Subsignal("clk", Pins("15"), IOStandard("LVCMOS33")), @@ -37,14 +45,11 @@ _io = [ Subsignal("wp", Pins("12"), IOStandard("LVCMOS33")), Subsignal("hold", Pins("13"), IOStandard("LVCMOS33")), ), - ("spiflash4x", 0, Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")), Subsignal("clk", Pins("15"), IOStandard("LVCMOS33")), Subsignal("dq", Pins("14 17 12 13"), IOStandard("LVCMOS33")), ), - - ("clk12", 0, Pins("35"), IOStandard("LVCMOS33")) ] # Connectors --------------------------------------------------------------------------------------- diff --git a/litex/boards/platforms/kc705.py b/litex/boards/platforms/kc705.py index 6d24e8962..fd76365fa 100644 --- a/litex/boards/platforms/kc705.py +++ b/litex/boards/platforms/kc705.py @@ -13,40 +13,7 @@ from litex.build.openocd import OpenOCD # IOs ---------------------------------------------------------------------------------------------- _io = [ - ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")), - ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")), - ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")), - ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")), - ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")), - ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")), - ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")), - ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), - - ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")), - - ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")), - ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")), - ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")), - ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")), - ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")), - - ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")), - ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")), - ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")), - ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")), - - ("user_sma_clock", 0, - Subsignal("p", Pins("L25"), IOStandard("LVDS_25"), - Misc("DIFF_TERM=TRUE")), - Subsignal("n", Pins("K25"), IOStandard("LVDS_25"), - Misc("DIFF_TERM=TRUE")) - ), - ("user_sma_clock_p", 0, Pins("L25"), IOStandard("LVCMOS25")), - ("user_sma_clock_n", 0, Pins("K25"), IOStandard("LVCMOS25")), - - ("user_sma_gpio_p", 0, Pins("Y23"), IOStandard("LVCMOS25")), - ("user_sma_gpio_n", 0, Pins("Y24"), IOStandard("LVCMOS25")), - + # Clk / Rst ("clk200", 0, Subsignal("p", Pins("AD12"), IOStandard("LVDS")), Subsignal("n", Pins("AD11"), IOStandard("LVDS")) @@ -56,12 +23,50 @@ _io = [ Subsignal("p", Pins("K28"), IOStandard("LVDS_25")), Subsignal("n", Pins("K29"), IOStandard("LVDS_25")) ), + ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")), + # Leds + ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")), + ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")), + ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")), + ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")), + ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")), + ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")), + ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")), + ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), + + # Buttons + ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")), + ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")), + ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")), + ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")), + ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")), + + # Switches + ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")), + ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")), + ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")), + ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")), + + # SMA + ("user_sma_clock", 0, + Subsignal("p", Pins("L25"), IOStandard("LVDS_25"), + Misc("DIFF_TERM=TRUE")), + Subsignal("n", Pins("K25"), IOStandard("LVDS_25"), + Misc("DIFF_TERM=TRUE")) + ), + ("user_sma_clock_p", 0, Pins("L25"), IOStandard("LVCMOS25")), + ("user_sma_clock_n", 0, Pins("K25"), IOStandard("LVCMOS25")), + ("user_sma_gpio_p", 0, Pins("Y23"), IOStandard("LVCMOS25")), + ("user_sma_gpio_n", 0, Pins("Y24"), IOStandard("LVCMOS25")), + + # I2C ("i2c", 0, Subsignal("scl", Pins("K21")), Subsignal("sda", Pins("L21")), IOStandard("LVCMOS25")), + # Serial ("serial", 0, Subsignal("cts", Pins("L27")), Subsignal("rts", Pins("K23")), @@ -70,56 +75,7 @@ _io = [ IOStandard("LVCMOS25") ), - ("spiflash", 0, # clock needs to be accessed through STARTUPE2 - Subsignal("cs_n", Pins("U19")), - Subsignal("dq", Pins("P24", "R25", "R20", "R21")), - IOStandard("LVCMOS25") - ), - - ("sdcard", 0, - Subsignal("clk", Pins("AB23")), - Subsignal("cmd", Pins("AB22"), Misc("PULLUP True")), - Subsignal("data", Pins("AC20 AA23 AA22 AC21"), Misc("PULLUP True")), - Misc("SLEW=FAST"), - IOStandard("LVCMOS25") - ), - - ("spisdcard", 0, - Subsignal("clk", Pins("AB23")), - Subsignal("cs_n", Pins("AC21")), - Subsignal("mosi", Pins("AB22"), Misc("PULLUP")), - Subsignal("miso", Pins("AC20"), Misc("PULLUP")), - Misc("SLEW=FAST"), - IOStandard("LVCMOS25") - ), - - ("lcd", 0, - Subsignal("db", Pins("AA13 AA10 AA11 Y10")), - Subsignal("e", Pins("AB10")), - Subsignal("rs", Pins("Y11")), - Subsignal("rw", Pins("AB13")), - IOStandard("LVCMOS15")), - - ("rotary", 0, - Subsignal("a", Pins("Y26")), - Subsignal("b", Pins("Y25")), - Subsignal("push", Pins("AA26")), - IOStandard("LVCMOS25")), - - ("hdmi", 0, - Subsignal("d", Pins( - "B23 A23 E23 D23 F25 E25 E24 D24", - "F26 E26 G23 G24 J19 H19 L17 L18", - "K19 K20")), - Subsignal("de", Pins("H17")), - Subsignal("clk", Pins("K18")), - Subsignal("vsync", Pins("H20")), - Subsignal("hsync", Pins("J18")), - Subsignal("int", Pins("AH24")), - Subsignal("spdif", Pins("J17")), - Subsignal("spdif_out", Pins("G20")), - IOStandard("LVCMOS25")), - + # DDR3 SDRAM ("ddram", 0, Subsignal("a", Pins( "AH12 AG13 AG12 AF12 AJ12 AJ13 AJ14 AH14", @@ -156,42 +112,31 @@ _io = [ Misc("VCCAUX_IO=HIGH") ), - ("ddram_dual_rank", 0, - Subsignal("a", Pins( - "AH12 AG13 AG12 AF12 AJ12 AJ13 AJ14 AH14", - "AK13 AK14 AF13 AE13 AJ11 AH11 AK10 AK11"), - IOStandard("SSTL15")), - Subsignal("ba", Pins("AH9 AG9 AK9"), IOStandard("SSTL15")), - Subsignal("ras_n", Pins("AD9"), IOStandard("SSTL15")), - Subsignal("cas_n", Pins("AC11"), IOStandard("SSTL15")), - Subsignal("we_n", Pins("AE9"), IOStandard("SSTL15")), - Subsignal("cs_n", Pins("AC12 AE8"), IOStandard("SSTL15")), - Subsignal("dm", Pins( - "Y16 AB17 AF17 AE16 AK5 AJ3 AF6 AC7"), - IOStandard("SSTL15")), - Subsignal("dq", Pins( - "AA15 AA16 AC14 AD14 AA17 AB15 AE15 Y15", - "AB19 AD16 AC19 AD17 AA18 AB18 AE18 AD18", - "AG19 AK19 AG18 AF18 AH19 AJ19 AE19 AD19", - "AK16 AJ17 AG15 AF15 AH17 AG14 AH15 AK15", - "AK8 AK6 AG7 AF7 AF8 AK4 AJ8 AJ6", - "AH5 AH6 AJ2 AH2 AH4 AJ4 AK1 AJ1", - "AF1 AF2 AE4 AE3 AF3 AF5 AE1 AE5", - "AC1 AD3 AC4 AC5 AE6 AD6 AC2 AD4"), - IOStandard("SSTL15_T_DCI")), - Subsignal("dqs_p", Pins("AC16 Y19 AJ18 AH16 AH7 AG2 AG4 AD2"), - IOStandard("DIFF_SSTL15")), - Subsignal("dqs_n", Pins("AC15 Y18 AK18 AJ16 AJ7 AH1 AG3 AD1"), - IOStandard("DIFF_SSTL15")), - Subsignal("clk_p", Pins("AG10 AE11"), IOStandard("DIFF_SSTL15")), - Subsignal("clk_n", Pins("AH10 AF11"), IOStandard("DIFF_SSTL15")), - Subsignal("cke", Pins("AF10 AE10"), IOStandard("SSTL15")), - Subsignal("odt", Pins("AD8 AC10"), IOStandard("SSTL15")), - Subsignal("reset_n", Pins("AK3"), IOStandard("LVCMOS15")), - Misc("SLEW=FAST"), - Misc("VCCAUX_IO=HIGH") + # SPIFlash + ("spiflash", 0, # clock needs to be accessed through STARTUPE2 + Subsignal("cs_n", Pins("U19")), + Subsignal("dq", Pins("P24", "R25", "R20", "R21")), + IOStandard("LVCMOS25") ), + # SDCard + ("spisdcard", 0, + Subsignal("clk", Pins("AB23")), + Subsignal("cs_n", Pins("AC21")), + Subsignal("mosi", Pins("AB22"), Misc("PULLUP")), + Subsignal("miso", Pins("AC20"), Misc("PULLUP")), + Misc("SLEW=FAST"), + IOStandard("LVCMOS25") + ), + ("sdcard", 0, + Subsignal("clk", Pins("AB23")), + Subsignal("cmd", Pins("AB22"), Misc("PULLUP True")), + Subsignal("data", Pins("AC20 AA23 AA22 AC21"), Misc("PULLUP True")), + Misc("SLEW=FAST"), + IOStandard("LVCMOS25") + ), + + # GMII Ethernet ("eth_clocks", 0, Subsignal("tx", Pins("M28")), Subsignal("gtx", Pins("K30")), @@ -214,6 +159,40 @@ _io = [ IOStandard("LVCMOS25") ), + # LCD + ("lcd", 0, + Subsignal("db", Pins("AA13 AA10 AA11 Y10")), + Subsignal("e", Pins("AB10")), + Subsignal("rs", Pins("Y11")), + Subsignal("rw", Pins("AB13")), + IOStandard("LVCMOS15") + ), + + # Rotary Encoder + ("rotary", 0, + Subsignal("a", Pins("Y26")), + Subsignal("b", Pins("Y25")), + Subsignal("push", Pins("AA26")), + IOStandard("LVCMOS25") + ), + + # HDMI + ("hdmi", 0, + Subsignal("d", Pins( + "B23 A23 E23 D23 F25 E25 E24 D24", + "F26 E26 G23 G24 J19 H19 L17 L18", + "K19 K20")), + Subsignal("de", Pins("H17")), + Subsignal("clk", Pins("K18")), + Subsignal("vsync", Pins("H20")), + Subsignal("hsync", Pins("J18")), + Subsignal("int", Pins("AH24")), + Subsignal("spdif", Pins("J17")), + Subsignal("spdif_out", Pins("G20")), + IOStandard("LVCMOS25") + ), + + # PCIe ("pcie_x1", 0, Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")), Subsignal("clk_p", Pins("U8")), @@ -251,13 +230,13 @@ _io = [ Subsignal("tx_n", Pins("L3 M1 N3 P1 T1 U3 V1 Y1")) ), - ("vadj_on_b", 0, Pins("J27"), IOStandard("LVCMOS25")), - + # SGMII Clk ("sgmii_clock", 0, Subsignal("p", Pins("G8")), Subsignal("n", Pins("G7")) ), + # SMA ("user_sma_mgt_refclk", 0, Subsignal("p", Pins("J8")), Subsignal("n", Pins("J7")) @@ -270,6 +249,8 @@ _io = [ Subsignal("p", Pins("K6")), Subsignal("n", Pins("K5")) ), + + # SFP ("sfp", 0, # inverted prior to HW rev 1.1 Subsignal("txp", Pins("H2")), Subsignal("txn", Pins("H1")), @@ -287,6 +268,7 @@ _io = [ ("sfp_tx_disable_n", 0, Pins("Y20"), IOStandard("LVCMOS25")), ("sfp_rx_los", 0, Pins("P19"), IOStandard("LVCMOS25")), + # SI5324 ("si5324", 0, Subsignal("rst_n", Pins("AE20"), IOStandard("LVCMOS25")), Subsignal("int", Pins("AG24"), IOStandard("LVCMOS25")) @@ -299,6 +281,9 @@ _io = [ Subsignal("p", Pins("L8")), Subsignal("n", Pins("L7")) ), + + # Others + ("vadj_on_b", 0, Pins("J27"), IOStandard("LVCMOS25")), ] # Connectors --------------------------------------------------------------------------------------- diff --git a/litex/boards/platforms/kcu105.py b/litex/boards/platforms/kcu105.py index bdde0bc61..8b9c9bee1 100644 --- a/litex/boards/platforms/kcu105.py +++ b/litex/boards/platforms/kcu105.py @@ -10,42 +10,7 @@ from litex.build.xilinx import XilinxPlatform, VivadoProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ - ("user_led", 0, Pins("AP8"), IOStandard("LVCMOS18")), - ("user_led", 1, Pins("H23"), IOStandard("LVCMOS18")), - ("user_led", 2, Pins("P20"), IOStandard("LVCMOS18")), - ("user_led", 3, Pins("P21"), IOStandard("LVCMOS18")), - ("user_led", 4, Pins("N22"), IOStandard("LVCMOS18")), - ("user_led", 5, Pins("M22"), IOStandard("LVCMOS18")), - ("user_led", 6, Pins("R23"), IOStandard("LVCMOS18")), - ("user_led", 7, Pins("P23"), IOStandard("LVCMOS18")), - - ("cpu_reset", 0, Pins("AN8"), IOStandard("LVCMOS18")), - - ("user_btn_c", 0, Pins("AE10"), IOStandard("LVCMOS18")), - ("user_btn_n", 0, Pins("AD10"), IOStandard("LVCMOS18")), - ("user_btn_s", 0, Pins("AF8"), IOStandard("LVCMOS18")), - ("user_btn_w", 0, Pins("AF9"), IOStandard("LVCMOS18")), - ("user_btn_e", 0, Pins("AE8"), IOStandard("LVCMOS18")), - - ("user_dip_btn", 0, Pins("AN16"), IOStandard("LVCMOS12")), - ("user_dip_btn", 1, Pins("AN19"), IOStandard("LVCMOS12")), - ("user_dip_btn", 2, Pins("AP18"), IOStandard("LVCMOS12")), - ("user_dip_btn", 3, Pins("AN14"), IOStandard("LVCMOS12")), - - ("user_sma_clock", 0, - Subsignal("p", Pins("D23"), IOStandard("LVDS")), - Subsignal("n", Pins("C23"), IOStandard("LVDS")) - ), - ("user_sma_clock_p", 0, Pins("D23"), IOStandard("LVCMOS18")), - ("user_sma_clock_n", 0, Pins("C23"), IOStandard("LVCMOS18")), - - ("user_sma_gpio", 0, - Subsignal("p", Pins("H27"), IOStandard("LVDS")), - Subsignal("n", Pins("G27"), IOStandard("LVDS")) - ), - ("user_sma_gpio_p", 0, Pins("H27"), IOStandard("LVCMOS18")), - ("user_sma_gpio_n", 0, Pins("G27"), IOStandard("LVCMOS18")), - + # Clk / Rst ("clk125", 0, Subsignal("p", Pins("G10"), IOStandard("LVDS")), Subsignal("n", Pins("F10"), IOStandard("LVDS")) @@ -55,13 +20,53 @@ _io = [ Subsignal("p", Pins("AK17"), IOStandard("DIFF_SSTL12")), Subsignal("n", Pins("AK16"), IOStandard("DIFF_SSTL12")) ), + ("cpu_reset", 0, Pins("AN8"), IOStandard("LVCMOS18")), + # Leds + ("user_led", 0, Pins("AP8"), IOStandard("LVCMOS18")), + ("user_led", 1, Pins("H23"), IOStandard("LVCMOS18")), + ("user_led", 2, Pins("P20"), IOStandard("LVCMOS18")), + ("user_led", 3, Pins("P21"), IOStandard("LVCMOS18")), + ("user_led", 4, Pins("N22"), IOStandard("LVCMOS18")), + ("user_led", 5, Pins("M22"), IOStandard("LVCMOS18")), + ("user_led", 6, Pins("R23"), IOStandard("LVCMOS18")), + ("user_led", 7, Pins("P23"), IOStandard("LVCMOS18")), + + # Buttons + ("user_btn_c", 0, Pins("AE10"), IOStandard("LVCMOS18")), + ("user_btn_n", 0, Pins("AD10"), IOStandard("LVCMOS18")), + ("user_btn_s", 0, Pins("AF8"), IOStandard("LVCMOS18")), + ("user_btn_w", 0, Pins("AF9"), IOStandard("LVCMOS18")), + ("user_btn_e", 0, Pins("AE8"), IOStandard("LVCMOS18")), + + # Switches + ("user_dip_btn", 0, Pins("AN16"), IOStandard("LVCMOS12")), + ("user_dip_btn", 1, Pins("AN19"), IOStandard("LVCMOS12")), + ("user_dip_btn", 2, Pins("AP18"), IOStandard("LVCMOS12")), + ("user_dip_btn", 3, Pins("AN14"), IOStandard("LVCMOS12")), + + # SMA + ("user_sma_clock", 0, + Subsignal("p", Pins("D23"), IOStandard("LVDS")), + Subsignal("n", Pins("C23"), IOStandard("LVDS")) + ), + ("user_sma_clock_p", 0, Pins("D23"), IOStandard("LVCMOS18")), + ("user_sma_clock_n", 0, Pins("C23"), IOStandard("LVCMOS18")), + ("user_sma_gpio", 0, + Subsignal("p", Pins("H27"), IOStandard("LVDS")), + Subsignal("n", Pins("G27"), IOStandard("LVDS")) + ), + ("user_sma_gpio_p", 0, Pins("H27"), IOStandard("LVCMOS18")), + ("user_sma_gpio_n", 0, Pins("G27"), IOStandard("LVCMOS18")), + + # I2C ("i2c", 0, Subsignal("scl", Pins("J24")), Subsignal("sda", Pins("J25")), IOStandard("LVCMOS18") ), + # Serial ("serial", 0, Subsignal("cts", Pins("L23")), Subsignal("rts", Pins("K27")), @@ -70,26 +75,19 @@ _io = [ IOStandard("LVCMOS18") ), + # SPIFlash ("spiflash", 0, # clock needs to be accessed through primitive Subsignal("cs_n", Pins("U7")), Subsignal("dq", Pins("AC7 AB7 AA7 Y7")), IOStandard("LVCMOS18") ), - ("spiflash", 1, # clock needs to be accessed through primitive Subsignal("cs_n", Pins("G26")), Subsignal("dq", Pins("M20 L20 R21 R22")), IOStandard("LVCMOS18") ), - ("sdcard", 0, - Subsignal("clk", Pins("AL10")), - Subsignal("cmd", Pins("AD9"), Misc("PULLUP True")), - Subsignal("data", Pins("AP9 AN9 AH9 AH8"), Misc("PULLUP True")), - Misc("SLEW=FAST"), - IOStandard("LVCMOS18") - ), - + # SDCard ("spisdcard", 0, Subsignal("clk", Pins("AL10")), Subsignal("cs_n", Pins("AH8")), @@ -98,7 +96,15 @@ _io = [ Misc("SLEW=FAST"), IOStandard("LVCMOS18") ), + ("sdcard", 0, + Subsignal("clk", Pins("AL10")), + Subsignal("cmd", Pins("AD9"), Misc("PULLUP True")), + Subsignal("data", Pins("AP9 AN9 AH9 AH8"), Misc("PULLUP True")), + Misc("SLEW=FAST"), + IOStandard("LVCMOS18") + ), + # Rotary Encoder ("rotary", 0, Subsignal("a", Pins("Y21")), Subsignal("b", Pins("AD26")), @@ -106,6 +112,7 @@ _io = [ IOStandard("LVCMOS18") ), + # HDMI ("hdmi", 0, Subsignal("d", Pins( "AK11 AP11 AP13 AN13 AN11 AM11 AN12 AM12", @@ -120,6 +127,7 @@ _io = [ IOStandard("LVCMOS18") ), + # DDR4 SDRAM ("ddram", 0, Subsignal("a", Pins( "AE17 AH17 AE18 AJ15 AG16 AL17 AK18 AG17", @@ -165,6 +173,7 @@ _io = [ Misc("SLEW=FAST"), ), + # PCIe ("pcie_x1", 0, Subsignal("rst_n", Pins("K22"), IOStandard("LVCMOS18")), Subsignal("clk_p", Pins("AB6")), @@ -174,7 +183,6 @@ _io = [ Subsignal("tx_p", Pins("AC4")), Subsignal("tx_n", Pins("AC3")) ), - ("pcie_x2", 0, Subsignal("rst_n", Pins("K22"), IOStandard("LVCMOS18")), Subsignal("clk_p", Pins("AB6")), @@ -184,7 +192,6 @@ _io = [ Subsignal("tx_p", Pins("AC4 AE4")), Subsignal("tx_n", Pins("AC3 AE3")) ), - ("pcie_x4", 0, Subsignal("rst_n", Pins("K22"), IOStandard("LVCMOS18")), Subsignal("clk_p", Pins("AB6")), @@ -194,7 +201,6 @@ _io = [ Subsignal("tx_p", Pins("AC4 AE4 AG4 AH6")), Subsignal("tx_n", Pins("AC3 AE3 AG3 AH5")) ), - ("pcie_x8", 0, Subsignal("rst_n", Pins("K22"), IOStandard("LVCMOS18")), Subsignal("clk_p", Pins("AB6")), @@ -205,16 +211,19 @@ _io = [ Subsignal("tx_n", Pins("AC3 AE3 AG3 AH5 AK5 AL3 AM5 AN3")) ), + # SGMII Clk ("sgmii_clock", 0, Subsignal("p", Pins("P26"), IOStandard("LVDS_25")), Subsignal("n", Pins("N26"), IOStandard("LVDS_25")) ), + # SI570 ("si570_refclk", 0, Subsignal("p", Pins("P6")), Subsignal("n", Pins("P5")) ), + # SMA ("user_sma_mgt_refclk", 0, Subsignal("p", Pins("V6")), Subsignal("n", Pins("V5")) @@ -228,6 +237,7 @@ _io = [ Subsignal("n", Pins("P1")) ), + # SFP ("sfp", 0, Subsignal("txp", Pins("U4")), Subsignal("txn", Pins("U3")), diff --git a/litex/boards/platforms/machxo3.py b/litex/boards/platforms/machxo3.py index 477468e80..1d909de7b 100644 --- a/litex/boards/platforms/machxo3.py +++ b/litex/boards/platforms/machxo3.py @@ -11,9 +11,11 @@ from litex.build.lattice.programmer import LatticeProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst ("clk12", 0, Pins("C8"), IOStandard("LVCMOS33")), ("rst_n", 0, Pins("B3"), IOStandard("LVCMOS33")), + # Leds ("user_led", 0, Pins("H11"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("J13"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("J11"), IOStandard("LVCMOS33")), @@ -23,11 +25,13 @@ _io = [ ("user_led", 6, Pins("N15"), IOStandard("LVCMOS33")), ("user_led", 7, Pins("P16"), IOStandard("LVCMOS33")), + # Switches ("user_dip_btn", 0, Pins("N2"), IOStandard("LVCMOS33")), ("user_dip_btn", 1, Pins("P1"), IOStandard("LVCMOS33")), ("user_dip_btn", 2, Pins("M3"), IOStandard("LVCMOS33")), ("user_dip_btn", 3, Pins("N1"), IOStandard("LVCMOS33")), + # Serial ("serial", 0, Subsignal("tx", Pins("C11"), IOStandard("LVCMOS33")), Subsignal("rx", Pins("A11"), IOStandard("LVCMOS33")), diff --git a/litex/boards/platforms/minispartan6.py b/litex/boards/platforms/minispartan6.py index d2686a009..7a217dfee 100644 --- a/litex/boards/platforms/minispartan6.py +++ b/litex/boards/platforms/minispartan6.py @@ -11,6 +11,11 @@ from litex.build.xilinx.programmer import XC3SProg # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst + ("clk32", 0, Pins("J4"), IOStandard("LVCMOS33")), + ("clk50", 0, Pins("K3"), IOStandard("LVCMOS33")), + + # Leds ("user_led", 0, Pins("P11"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("N9"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("M9"), IOStandard("LVCMOS33")), @@ -20,14 +25,14 @@ _io = [ ("user_led", 6, Pins("P8"), IOStandard("LVCMOS33")), ("user_led", 7, Pins("P7"), IOStandard("LVCMOS33")), + # Switches ("user_sw", 0, Pins("L1"), IOStandard("LVCMOS33"), Misc("PULLUP")), ("user_sw", 1, Pins("L3"), IOStandard("LVCMOS33"), Misc("PULLUP")), ("user_sw", 2, Pins("L4"), IOStandard("LVCMOS33"), Misc("PULLUP")), ("user_sw", 3, Pins("L5"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("clk32", 0, Pins("J4"), IOStandard("LVCMOS33")), - ("clk50", 0, Pins("K3"), IOStandard("LVCMOS33")), + # SPIFlash ("spiflash", 0, Subsignal("cs_n", Pins("T3"), IOStandard("LVCMOS33")), Subsignal("clk", Pins("R11"), IOStandard("LVCMOS33")), @@ -35,6 +40,26 @@ _io = [ Subsignal("miso", Pins("P10"), IOStandard("LVCMOS33")) ), + # Serial + ("serial", 0, + Subsignal("tx", Pins("N6"), IOStandard("LVCMOS33")), # FTDI D1 + Subsignal("rx", Pins("M7"), IOStandard("LVCMOS33")) # FTDI D0 + ), + + # USB FIFO + ("usb_fifo", 0, + Subsignal("data", Pins("M7 N6 M6 P5 N5 P4 P2 P1")), + Subsignal("rxf_n", Pins("N3")), + Subsignal("txe_n", Pins("N1")), + Subsignal("rd_n", Pins("M1")), + Subsignal("wr_n", Pins("M2")), + Subsignal("siwua", Pins("M3")), + Misc("SLEW=FAST"), + Drive(8), + IOStandard("LVCMOS33"), + ), + + # ADC ("adc", 0, Subsignal("cs_n", Pins("F6"), IOStandard("LVCMOS33")), Subsignal("clk", Pins("G6"), IOStandard("LVCMOS33")), @@ -42,16 +67,13 @@ _io = [ Subsignal("miso", Pins("H5"), IOStandard("LVCMOS33")) ), - ("serial", 0, - Subsignal("tx", Pins("N6"), IOStandard("LVCMOS33")), # FTDI D1 - Subsignal("rx", Pins("M7"), IOStandard("LVCMOS33")) # FTDI D0 - ), - + # Audio ("audio", 0, Subsignal("a0", Pins("B8"), IOStandard("LVCMOS33")), Subsignal("a1", Pins("A8"), IOStandard("LVCMOS33")) ), + # SDR SDRAM ("sdram_clock", 0, Pins("G16"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")), ("sdram", 0, Subsignal("a", Pins( @@ -71,18 +93,7 @@ _io = [ IOStandard("LVCMOS33"), ), - ("usb_fifo", 0, - Subsignal("data", Pins("M7 N6 M6 P5 N5 P4 P2 P1")), - Subsignal("rxf_n", Pins("N3")), - Subsignal("txe_n", Pins("N1")), - Subsignal("rd_n", Pins("M1")), - Subsignal("wr_n", Pins("M2")), - Subsignal("siwua", Pins("M3")), - Misc("SLEW=FAST"), - Drive(8), - IOStandard("LVCMOS33"), - ), - + # SDCard ("spisdcard", 0, Subsignal("clk", Pins("L12")), Subsignal("mosi", Pins("K11"), Misc("PULLUP")), @@ -91,7 +102,6 @@ _io = [ Misc("SLEW=FAST"), IOStandard("LVCMOS33"), ), - ("sdcard", 0, Subsignal("data", Pins("M10 L10 J11 K12"), Misc("PULLUP")), Subsignal("cmd", Pins("K11"), Misc("PULLUP")), @@ -100,6 +110,7 @@ _io = [ IOStandard("LVCMOS33"), ), + # DVI In ("dvi_in", 0, Subsignal("clk_p", Pins("C9"), IOStandard("TMDS_33")), Subsignal("clk_n", Pins("A9"), IOStandard("TMDS_33")), @@ -109,6 +120,7 @@ _io = [ Subsignal("sda", Pins("B1"), IOStandard("LVCMOS33")) ), + # DVI Out ("dvi_out", 0, Subsignal("clk_p", Pins("B14"), IOStandard("TMDS_33")), Subsignal("clk_n", Pins("A14"), IOStandard("TMDS_33")), diff --git a/litex/boards/platforms/netv2.py b/litex/boards/platforms/netv2.py index a7817c9da..1f350144a 100644 --- a/litex/boards/platforms/netv2.py +++ b/litex/boards/platforms/netv2.py @@ -11,10 +11,10 @@ from litex.build.openocd import OpenOCD # IOs ---------------------------------------------------------------------------------------------- _io = [ - # clock + # Clk / Rst ("clk50", 0, Pins("J19"), IOStandard("LVCMOS33")), - # leds + # Leds ("user_led", 0, Pins("M21"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("N20"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("L21"), IOStandard("LVCMOS33")), @@ -22,31 +22,29 @@ _io = [ ("user_led", 4, Pins("R19"), IOStandard("LVCMOS33")), ("user_led", 5, Pins("M16"), IOStandard("LVCMOS33")), - # spiflash - ("flash", 0, + # SPIFlash + ("spiflash", 0, Subsignal("cs_n", Pins("T19")), Subsignal("mosi", Pins("P22")), Subsignal("miso", Pins("R22")), - Subsignal("wp", Pins("P21")), + Subsignal("vpp", Pins("P21")), Subsignal("hold", Pins("R21")), IOStandard("LVCMOS33") ), - - # spiflash4x ("spiflash4x", 0, Subsignal("cs_n", Pins("T19")), Subsignal("dq", Pins("P22 R22 P21 R21")), IOStandard("LVCMOS33") ), - # serial + # Serial ("serial", 0, Subsignal("tx", Pins("E14")), Subsignal("rx", Pins("E13")), IOStandard("LVCMOS33"), ), - # dram + # DDR3 SDRAM ("ddram", 0, Subsignal("a", Pins( "U6 V4 W5 V5 AA1 Y2 AB1 AB3", @@ -75,7 +73,7 @@ _io = [ Misc("SLEW=FAST"), ), - # pcie + # PCIe ("pcie_x1", 0, Subsignal("rst_n", Pins("E18"), IOStandard("LVCMOS33")), Subsignal("clk_p", Pins("F10")), @@ -85,7 +83,6 @@ _io = [ 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")), @@ -95,7 +92,6 @@ _io = [ 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")), @@ -106,12 +102,11 @@ _io = [ Subsignal("tx_n", Pins("C5 A6 C7 A4")) ), - # ethernet + # RMII Ethernet ("eth_clocks", 0, Subsignal("ref_clk", Pins("D17")), IOStandard("LVCMOS33"), ), - ("eth", 0, Subsignal("rst_n", Pins("F16")), Subsignal("rx_data", Pins("A20 B18")), @@ -125,14 +120,7 @@ _io = [ IOStandard("LVCMOS33") ), - # sdcard - ("sdcard", 0, - Subsignal("clk", Pins("K18")), - Subsignal("cmd", Pins("L13"), Misc("PULLUP True")), - Subsignal("data", Pins("L15 L16 K14 M13"), Misc("PULLUP True")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ), - + # SDCard ("spisdcard", 0, Subsignal("clk", Pins("K18")), Subsignal("cs_n", Pins("M13")), @@ -141,8 +129,14 @@ _io = [ Misc("SLEW=FAST"), IOStandard("LVCMOS33") ), + ("sdcard", 0, + Subsignal("clk", Pins("K18")), + Subsignal("cmd", Pins("L13"), Misc("PULLUP True")), + Subsignal("data", Pins("L15 L16 K14 M13"), Misc("PULLUP True")), + IOStandard("LVCMOS33"), Misc("SLEW=FAST") + ), - # hdmi in + # HDMI In ("hdmi_in", 0, Subsignal("clk_p", Pins("L19"), IOStandard("TMDS_33"), Inverted()), Subsignal("clk_n", Pins("L20"), IOStandard("TMDS_33"), Inverted()), @@ -152,12 +146,9 @@ _io = [ 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"), Inverted(), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("V18"), Inverted(), IOStandard("LVCMOS33")), - Subsignal("sda_pu", Pins("G20"), IOStandard("LVCMOS33")), - Subsignal("sda_pd", Pins("F20"), IOStandard("LVCMOS33")), + 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()), @@ -171,7 +162,7 @@ _io = [ Subsignal("sda", Pins("R17"), IOStandard("LVCMOS33")), ), - # hdmi out + # HDMI Out ("hdmi_out", 0, Subsignal("clk_p", Pins("W19"), IOStandard("TMDS_33"), Inverted()), Subsignal("clk_n", Pins("W20"), IOStandard("TMDS_33"), Inverted()), @@ -182,7 +173,6 @@ _io = [ 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()), diff --git a/litex/boards/platforms/nexys4ddr.py b/litex/boards/platforms/nexys4ddr.py index bcb20a5e5..4d5dec586 100644 --- a/litex/boards/platforms/nexys4ddr.py +++ b/litex/boards/platforms/nexys4ddr.py @@ -11,6 +11,11 @@ from litex.build.openocd import OpenOCD # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst + ("clk100", 0, Pins("E3"), IOStandard("LVCMOS33")), + ("cpu_reset", 0, Pins("C12"), IOStandard("LVCMOS33")), + + # Leds ("user_led", 0, Pins("H17"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("K15"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("J13"), IOStandard("LVCMOS33")), @@ -28,6 +33,7 @@ _io = [ ("user_led", 14, Pins("V12"), IOStandard("LVCMOS33")), ("user_led", 15, Pins("V11"), IOStandard("LVCMOS33")), + # Switches ("user_sw", 0, Pins("J15"), IOStandard("LVCMOS33")), ("user_sw", 1, Pins("L16"), IOStandard("LVCMOS33")), ("user_sw", 2, Pins("M13"), IOStandard("LVCMOS33")), @@ -45,22 +51,21 @@ _io = [ ("user_sw", 14, Pins("U11"), IOStandard("LVCMOS33")), ("user_sw", 15, Pins("V10"), IOStandard("LVCMOS33")), + # Buttons ("user_btn", 0, Pins("N17"), IOStandard("LVCMOS33")), ("user_btn", 1, Pins("P18"), IOStandard("LVCMOS33")), ("user_btn", 2, Pins("P17"), IOStandard("LVCMOS33")), ("user_btn", 3, Pins("M17"), IOStandard("LVCMOS33")), ("user_btn", 4, Pins("M18"), IOStandard("LVCMOS33")), - ("clk100", 0, Pins("E3"), IOStandard("LVCMOS33")), - - ("cpu_reset", 0, Pins("C12"), IOStandard("LVCMOS33")), - + # Serial ("serial", 0, Subsignal("tx", Pins("D4")), Subsignal("rx", Pins("C4")), IOStandard("LVCMOS33"), ), + # SDCard ("spisdcard", 0, Subsignal("rst", Pins("E2")), Subsignal("clk", Pins("B1")), @@ -70,7 +75,6 @@ _io = [ Misc("SLEW=FAST"), IOStandard("LVCMOS33"), ), - ("sdcard", 0, Subsignal("rst", Pins("E2"), Misc("PULLUP True")), Subsignal("data", Pins("C2 E1 F1 D2"), Misc("PULLUP True")), @@ -81,6 +85,7 @@ _io = [ IOStandard("LVCMOS33"), ), + # DDR2 SDRAM ("ddram", 0, Subsignal("a", Pins( "M4 P4 M6 T1 L3 P5 M2 N1", @@ -106,6 +111,7 @@ _io = [ Misc("SLEW=FAST"), ), + # RMII Ethernet ("eth_clocks", 0, Subsignal("ref_clk", Pins("D5")), IOStandard("LVCMOS33"), diff --git a/litex/boards/platforms/nexys_video.py b/litex/boards/platforms/nexys_video.py index 1773207da..f1b7e5493 100644 --- a/litex/boards/platforms/nexys_video.py +++ b/litex/boards/platforms/nexys_video.py @@ -11,10 +11,11 @@ from litex.build.openocd import OpenOCD # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst ("clk100", 0, Pins("R4"), IOStandard("LVCMOS33")), - ("cpu_reset", 0, Pins("G4"), IOStandard("LVCMOS15")), + # Leds ("user_led", 0, Pins("T14"), IOStandard("LVCMOS25")), ("user_led", 1, Pins("T15"), IOStandard("LVCMOS25")), ("user_led", 2, Pins("T16"), IOStandard("LVCMOS25")), @@ -24,6 +25,7 @@ _io = [ ("user_led", 6, Pins("W15"), IOStandard("LVCMOS25")), ("user_led", 7, Pins("Y13"), IOStandard("LVCMOS25")), + # Switches ("user_sw", 0, Pins("E22"), IOStandard("LVCMOS25")), ("user_sw", 1, Pins("F21"), IOStandard("LVCMOS25")), ("user_sw", 2, Pins("G21"), IOStandard("LVCMOS25")), @@ -33,7 +35,7 @@ _io = [ ("user_sw", 6, Pins("K13"), IOStandard("LVCMOS25")), ("user_sw", 7, Pins("M17"), IOStandard("LVCMOS25")), - + # Buttons ("user_btn", 0, Pins("B22"), IOStandard("LVCMOS25")), ("user_btn", 1, Pins("D22"), IOStandard("LVCMOS25")), ("user_btn", 2, Pins("C22"), IOStandard("LVCMOS25")), @@ -41,8 +43,7 @@ _io = [ ("user_btn", 4, Pins("F15"), IOStandard("LVCMOS25")), ("user_btn", 5, Pins("G4"), IOStandard("LVCMOS25")), - ("vadj", 0, Pins("AA13 AB17"), IOStandard("LVCMOS25")), - + # OLED ("oled", 0, Subsignal("dc", Pins("W22")), Subsignal("res", Pins("U21")), @@ -53,12 +54,14 @@ _io = [ IOStandard("LVCMOS33") ), + # Serial ("serial", 0, Subsignal("tx", Pins("AA19")), Subsignal("rx", Pins("V18")), IOStandard("LVCMOS33"), ), + # USB FIFO ("usb_fifo", 0, # Can be used when FT2232H's Channel A configured to ASYNC FIFO 245 mode Subsignal("data", Pins("U20 P14 P15 U17 R17 P16 R18 N14")), Subsignal("rxf_n", Pins("N17")), @@ -72,6 +75,7 @@ _io = [ IOStandard("LVCMOS33"), ), + # SDCard ("spisdcard", 0, Subsignal("rst", Pins("V20")), Subsignal("clk", Pins("W19")), @@ -91,6 +95,7 @@ _io = [ IOStandard("LVCMOS33"), ), + # DDR3 SDRAM ("ddram", 0, Subsignal("a", Pins( "M2 M5 M3 M1 L6 P1 N3 N2", @@ -116,6 +121,7 @@ _io = [ Misc("SLEW=FAST"), ), + # MII Ethernet ("eth_clocks", 0, Subsignal("tx", Pins("AA14")), Subsignal("rx", Pins("V13")), @@ -133,6 +139,7 @@ _io = [ IOStandard("LVCMOS25") ), + # HDMI In ("hdmi_in", 0, Subsignal("clk_p", Pins("V4"), IOStandard("TMDS_33")), Subsignal("clk_n", Pins("W4"), IOStandard("TMDS_33")), @@ -149,6 +156,7 @@ _io = [ Subsignal("txen", Pins("R3"), IOStandard("LVCMOS33")), # FIXME ), + # HDMI Out ("hdmi_out", 0, Subsignal("clk_p", Pins("T1"), IOStandard("TMDS_33")), Subsignal("clk_n", Pins("U1"), IOStandard("TMDS_33")), @@ -163,6 +171,9 @@ _io = [ Subsignal("cec", Pins("AA4"), IOStandard("LVCMOS33")), # FIXME Subsignal("hdp", Pins("AB13"), IOStandard("LVCMOS25")), # FIXME ), + + # Others + ("vadj", 0, Pins("AA13 AB17"), IOStandard("LVCMOS25")), ] # Connectors --------------------------------------------------------------------------------------- diff --git a/litex/boards/platforms/pcie_screamer.py b/litex/boards/platforms/pcie_screamer.py deleted file mode 100644 index 9e16cf4b6..000000000 --- a/litex/boards/platforms/pcie_screamer.py +++ /dev/null @@ -1,99 +0,0 @@ -# -# This file is part of LiteX. -# -# Copyright (c) 2016-2019 Florent Kermarrec -# Copyright (c) 2019 Pierre-Olivier Vauboin -# SPDX-License-Identifier: BSD-2-Clause - - -from migen import * - -from litex.build.generic_platform import * -from litex.build.xilinx import XilinxPlatform - -# IOs ---------------------------------------------------------------------------------------------- - -_io = [ - ("clk100", 0, Pins("R4"), IOStandard("LVCMOS33")), - - ("user_led", 0, Pins("AB1"), IOStandard("LVCMOS33")), - ("user_led", 1, Pins("AB8"), IOStandard("LVCMOS33")), - - ("user_btn", 0, Pins("AA1"), IOStandard("LVCMOS33")), - ("user_btn", 1, Pins("AB6"), IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("T1")), - Subsignal("rx", Pins("U1")), - IOStandard("LVCMOS33"), - ), - - ("ddram", 0, - Subsignal("a", Pins( - "M2 M5 M3 M1 L6 P1 N3 N2", - "M6 R1 L5 N5 N4 P2 P6"), - IOStandard("SSTL15")), - Subsignal("ba", Pins("L3 K6 L4"), IOStandard("SSTL15")), - Subsignal("ras_n", Pins("J4"), IOStandard("SSTL15")), - Subsignal("cas_n", Pins("K3"), IOStandard("SSTL15")), - Subsignal("we_n", Pins("L1"), IOStandard("SSTL15")), - Subsignal("dm", Pins("G3 F1"), IOStandard("SSTL15")), - Subsignal("dq", Pins( - "G2 H4 H5 J1 K1 H3 H2 J5", - "E3 B2 F3 D2 C2 A1 E2 B1"), - IOStandard("SSTL15"), - Misc("IN_TERM=UNTUNED_SPLIT_50")), - Subsignal("dqs_p", Pins("K2 E1"), IOStandard("DIFF_SSTL15")), - Subsignal("dqs_n", Pins("J2 D1"), IOStandard("DIFF_SSTL15")), - Subsignal("clk_p", Pins("P5"), IOStandard("DIFF_SSTL15")), - Subsignal("clk_n", Pins("P4"), IOStandard("DIFF_SSTL15")), - Subsignal("cke", Pins("J6"), IOStandard("SSTL15")), - Subsignal("odt", Pins("K4"), IOStandard("SSTL15")), - Subsignal("reset_n", Pins("G1"), IOStandard("SSTL15")), - Misc("SLEW=FAST"), - ), - - ("pcie_x1", 0, - Subsignal("rst_n", Pins("AB7"), IOStandard("LVCMOS33")), - Subsignal("clk_p", Pins("F6")), - Subsignal("clk_n", Pins("E6")), - Subsignal("rx_p", Pins("B10")), - Subsignal("rx_n", Pins("A10")), - Subsignal("tx_p", Pins("B6")), - Subsignal("tx_n", Pins("A6")) - ), - - ("usb_fifo_clock", 0, Pins("D17"), IOStandard("LVCMOS33")), - ("usb_fifo", 0, - Subsignal("rst", Pins("K22")), - Subsignal("data", Pins( - "A16 F14 A15 F13 A14 E14 A13 E13", - "B13 C15 C13 C14 B16 E17 B15 F16", - "A20 E18 B20 F18 D19 D21 E19 E21", - "A21 B21 A19 A18 F20 F19 B18 B17")), - Subsignal("be", Pins("K16 L16 G20 H20")), - Subsignal("rxf_n", Pins("M13")), - Subsignal("txe_n", Pins("L13")), - Subsignal("rd_n", Pins("K19")), - Subsignal("wr_n", Pins("M15")), - Subsignal("oe_n", Pins("K18")), - Subsignal("siwua", Pins("M16")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ), -] - -# Platform ----------------------------------------------------------------------------------------- - -class Platform(XilinxPlatform): - default_clk_name = "clk100" - default_clk_period = 1e9/100e6 - - def __init__(self): - XilinxPlatform.__init__(self, "xc7a35t-fgg484-2", _io, toolchain="vivado") - self.toolchain.bitstream_commands = \ - ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]", - "set_property BITSTREAM.CONFIG.CONFIGRATE 40 [current_design]"] - self.toolchain.additional_commands = \ - ["write_cfgmem -force -format bin -interface spix4 -size 16 " - "-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"] - self.add_platform_command("set_property INTERNAL_VREF 0.750 [get_iobanks 35]") diff --git a/litex/boards/platforms/tinyfpga_bx.py b/litex/boards/platforms/tinyfpga_bx.py index bdd26eb55..dcd10be8b 100644 --- a/litex/boards/platforms/tinyfpga_bx.py +++ b/litex/boards/platforms/tinyfpga_bx.py @@ -12,8 +12,13 @@ from litex.build.lattice.programmer import TinyProgProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst + ("clk16", 0, Pins("B2"), IOStandard("LVCMOS33")), + + # Leds ("user_led", 0, Pins("B3"), IOStandard("LVCMOS33")), + # USB ("usb", 0, Subsignal("d_p", Pins("B4")), Subsignal("d_n", Pins("A4")), @@ -21,6 +26,7 @@ _io = [ IOStandard("LVCMOS33") ), + # SPIFlash ("spiflash", 0, Subsignal("cs_n", Pins("F7"), IOStandard("LVCMOS33")), Subsignal("clk", Pins("G7"), IOStandard("LVCMOS33")), @@ -29,14 +35,11 @@ _io = [ Subsignal("wp", Pins("H4"), IOStandard("LVCMOS33")), Subsignal("hold", Pins("J8"), IOStandard("LVCMOS33")) ), - ("spiflash4x", 0, Subsignal("cs_n", Pins("F7"), IOStandard("LVCMOS33")), Subsignal("clk", Pins("G7"), IOStandard("LVCMOS33")), Subsignal("dq", Pins("G6 H7 H4 J8"), IOStandard("LVCMOS33")) ), - - ("clk16", 0, Pins("B2"), IOStandard("LVCMOS33")) ] # Connectors --------------------------------------------------------------------------------------- diff --git a/litex/boards/platforms/ulx3s.py b/litex/boards/platforms/ulx3s.py index faf26ca75..e77251a05 100644 --- a/litex/boards/platforms/ulx3s.py +++ b/litex/boards/platforms/ulx3s.py @@ -10,10 +10,12 @@ from litex.build.lattice.programmer import UJProg # IOs ---------------------------------------------------------------------------------------------- -_io = [ +_io_common = [ + # Clk / Rst ("clk25", 0, Pins("G2"), IOStandard("LVCMOS33")), ("rst", 0, Pins("R1"), IOStandard("LVCMOS33")), + # Leds ("user_led", 0, Pins("B2"), IOStandard("LVCMOS33")), ("user_led", 1, Pins("C2"), IOStandard("LVCMOS33")), ("user_led", 2, Pins("C1"), IOStandard("LVCMOS33")), @@ -23,28 +25,13 @@ _io = [ ("user_led", 6, Pins("E1"), IOStandard("LVCMOS33")), ("user_led", 7, Pins("H3"), IOStandard("LVCMOS33")), + # Serial ("serial", 0, Subsignal("tx", Pins("L4"), IOStandard("LVCMOS33")), Subsignal("rx", Pins("M1"), IOStandard("LVCMOS33")) ), - ("spisdcard", 0, - Subsignal("clk", Pins("J1")), - Subsignal("mosi", Pins("J3"), Misc("PULLMODE=UP")), - Subsignal("cs_n", Pins("H1"), Misc("PULLMODE=UP")), - Subsignal("miso", Pins("K2"), Misc("PULLMODE=UP")), - Misc("SLEWRATE=FAST"), - IOStandard("LVCMOS33"), - ), - - ("sdcard", 0, - Subsignal("clk", Pins("J1")), - Subsignal("cmd", Pins("J3"), Misc("PULLMODE=UP")), - Subsignal("data", Pins("K2 K1 H2 H1"), Misc("PULLMODE=UP")), - Misc("SLEWRATE=FAST"), - IOStandard("LVCMOS33"), - ), - + # SDR SDRAM ("sdram_clock", 0, Pins("F19"), IOStandard("LVCMOS33")), ("sdram", 0, Subsignal("a", Pins( @@ -64,11 +51,7 @@ _io = [ Misc("SLEWRATE=FAST"), ), - ("wifi_gpio0", 0, Pins("L2"), IOStandard("LVCMOS33")), - - ("ext0p", 0, Pins("B11"), IOStandard("LVCMOS33")), - ("ext1p", 0, Pins("A10"), IOStandard("LVCMOS33")), - + # GPIOs ("gpio", 0, Subsignal("p", Pins("B11")), Subsignal("n", Pins("C11")), @@ -90,12 +73,15 @@ _io = [ IOStandard("LVCMOS33") ), + # USB ("usb", 0, Subsignal("d_p", Pins("D15")), Subsignal("d_n", Pins("E15")), Subsignal("pullup", Pins("B12 C12")), IOStandard("LVCMOS33") ), + + # OLED ("oled_spi", 0, Subsignal("clk", Pins("P4")), Subsignal("mosi", Pins("P3")), @@ -107,6 +93,51 @@ _io = [ Subsignal("csn", Pins("N2")), IOStandard("LVCMOS33"), ), + + # Others + ("wifi_gpio0", 0, Pins("L2"), IOStandard("LVCMOS33")), + ("ext0p", 0, Pins("B11"), IOStandard("LVCMOS33")), + ("ext1p", 0, Pins("A10"), IOStandard("LVCMOS33")), +] + +_io_1_7 = [ + # SDCard + ("spisdcard", 0, + Subsignal("clk", Pins("J1")), + Subsignal("mosi", Pins("J3"), Misc("PULLMODE=UP")), + Subsignal("cs_n", Pins("H1"), Misc("PULLMODE=UP")), + Subsignal("miso", Pins("K2"), Misc("PULLMODE=UP")), + Misc("SLEWRATE=FAST"), + IOStandard("LVCMOS33"), + ), + ("sdcard", 0, + Subsignal("clk", Pins("J1")), + Subsignal("cmd", Pins("J3"), Misc("PULLMODE=UP")), + Subsignal("data", Pins("K2 K1 H2 H1"), Misc("PULLMODE=UP")), + Misc("SLEWRATE=FAST"), + IOStandard("LVCMOS33"), + ), +] + +_io_2_0 = [ + # SDCard + ("spisdcard", 0, + Subsignal("clk", Pins("H2")), + Subsignal("mosi", Pins("J1"), Misc("PULLMODE=UP")), + Subsignal("cs_n", Pins("K2"), Misc("PULLMODE=UP")), + Subsignal("miso", Pins("J3"), Misc("PULLMODE=UP")), + Misc("SLEWRATE=FAST"), + IOStandard("LVCMOS33"), + ), + ("sdcard", 0, + Subsignal("clk", Pins("H2")), + Subsignal("cmd", Pins("J1"), Misc("PULLMODE=UP")), + Subsignal("data", Pins("J3 H1 K1 K2"), Misc("PULLMODE=UP")), + Subsignal("cd", Pins("N5")), + Subsignal("wp", Pins("P5")), + Misc("SLEWRATE=FAST"), + IOStandard("LVCMOS33"), + ), ] # Platform ----------------------------------------------------------------------------------------- @@ -115,8 +146,10 @@ class Platform(LatticePlatform): default_clk_name = "clk25" default_clk_period = 1e9/25e6 - def __init__(self, device="LFE5U-45F", **kwargs): - assert device in ["LFE5U-25F", "LFE5U-45F", "LFE5U-85F"] + def __init__(self, device="LFE5U-45F", revision="2.0", **kwargs): + assert device in ["LFE5U-12F", "LFE5U-25F", "LFE5U-45F", "LFE5U-85F"] + assert revision in ["1.7", "2.0"] + _io = _io_common + {"1.7": _io_1_7, "2.0": _io_2_0}[revision] LatticePlatform.__init__(self, device + "-6BG381C", _io, **kwargs) def create_programmer(self): diff --git a/litex/boards/platforms/versa_ecp5.py b/litex/boards/platforms/versa_ecp5.py index 9feacb283..89c234420 100644 --- a/litex/boards/platforms/versa_ecp5.py +++ b/litex/boards/platforms/versa_ecp5.py @@ -12,9 +12,11 @@ from litex.build.lattice.programmer import OpenOCDJTAGProgrammer # IOs ---------------------------------------------------------------------------------------------- _io = [ + # Clk / Rst ("clk100", 0, Pins("P3"), IOStandard("LVDS")), ("rst_n", 0, Pins("T1"), IOStandard("LVCMOS33")), + # Leds ("user_led", 0, Pins("E16"), IOStandard("LVCMOS25")), ("user_led", 1, Pins("D17"), IOStandard("LVCMOS25")), ("user_led", 2, Pins("D18"), IOStandard("LVCMOS25")), @@ -24,6 +26,7 @@ _io = [ ("user_led", 6, Pins("E17"), IOStandard("LVCMOS25")), ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), + # Switches ("user_dip_btn", 0, Pins("H2"), IOStandard("LVCMOS15")), ("user_dip_btn", 1, Pins("K3"), IOStandard("LVCMOS15")), ("user_dip_btn", 2, Pins("G3"), IOStandard("LVCMOS15")), @@ -33,11 +36,13 @@ _io = [ ("user_dip_btn", 6, Pins("K19"), IOStandard("LVCMOS25")), ("user_dip_btn", 7, Pins("K20"), IOStandard("LVCMOS25")), + # Serial ("serial", 0, Subsignal("rx", Pins("C11"), IOStandard("LVCMOS33")), Subsignal("tx", Pins("A11"), IOStandard("LVCMOS33")), ), + # SPIFlash ("spiflash", 0, # clock needs to be accessed through USRMCLK Subsignal("cs_n", Pins("R2")), Subsignal("mosi", Pins("W2")), @@ -46,13 +51,14 @@ _io = [ Subsignal("hold", Pins("W1")), IOStandard("LVCMOS33"), ), - ("spiflash4x", 0, # clock needs to be accessed through USRMCLK Subsignal("cs_n", Pins("R2")), Subsignal("dq", Pins("W2 V2 Y2 W1")), IOStandard("LVCMOS33") ), + + # DDR3 SDRAM ("ddram", 0, Subsignal("a", Pins( "P2 C4 E5 F5 B3 F4 B5 E4", @@ -79,6 +85,7 @@ _io = [ Misc("SLEWRATE=FAST"), ), + # RGMII Ethernet ("eth_clocks", 0, Subsignal("tx", Pins("P19")), Subsignal("rx", Pins("L20")), @@ -94,7 +101,6 @@ _io = [ Subsignal("tx_data", Pins("N19 N20 P18 P20")), IOStandard("LVCMOS25") ), - ("eth_clocks", 1, Subsignal("tx", Pins("C20")), Subsignal("rx", Pins("J19")), @@ -111,12 +117,7 @@ _io = [ IOStandard("LVCMOS25") ), - ("ext_clk", 0, - Subsignal("p", Pins("A4")), - Subsignal("n", Pins("A5")), - IOStandard("LVDS") - ), - + # PCIe ("pcie_x1", 0, Subsignal("clk_p", Pins("Y11")), Subsignal("clk_n", Pins("Y12")), @@ -127,6 +128,14 @@ _io = [ Subsignal("perst", Pins("A6"), IOStandard("LVCMOS33")), ), + # External Clock + ("ext_clk", 0, + Subsignal("p", Pins("A4")), + Subsignal("n", Pins("A5")), + IOStandard("LVDS") + ), + + # Ref Clock ("refclk_en", 0, Pins("C12"), IOStandard("LVCMOS33")), ("refclk_rst_n", 0, Pins("R1"), IOStandard("LVCMOS33")), ("refclk", 0, @@ -138,6 +147,7 @@ _io = [ Subsignal("n", Pins("W20")), ), + # SMA ("sma_tx", 0, Subsignal("p", Pins("W8")), Subsignal("n", Pins("W9")), @@ -148,6 +158,7 @@ _io = [ ), ] +# ECP5-hat extension (https://github.com/daveshah1/ecp5-hat) --------------------------------------- _ecp5_soc_hat_io = [ ("sdram_clock", 0, Pins("E14"), IOStandard("LVCMOS33")), diff --git a/litex/boards/targets/arty.py b/litex/boards/targets/arty.py index 7888b66ae..f6602bb23 100755 --- a/litex/boards/targets/arty.py +++ b/litex/boards/targets/arty.py @@ -30,25 +30,26 @@ from liteeth.phy.mii import LiteEthPHYMII class _CRG(Module): def __init__(self, platform, sys_clk_freq, toolchain): + self.rst = Signal() 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_idelay = ClockDomain() self.clock_domains.cd_eth = ClockDomain() # # # if toolchain == "vivado": self.submodules.pll = pll = S7PLL(speedgrade=-1) - self.comb += pll.reset.eq(~platform.request("cpu_reset")) + self.comb += pll.reset.eq(~platform.request("cpu_reset") | self.rst) 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_idelay, 200e6) pll.create_clkout(self.cd_eth, 25e6) - self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) self.comb += platform.request("eth_ref_clk").eq(self.cd_eth.clk) elif toolchain == "symbiflow": # FIXME @@ -58,7 +59,7 @@ class _CRG(Module): self.specials += Instance("BUFG", i_I=clk100_ibuf, o_O=clk100_buf) self.submodules.pll = pll = S7PLL(speedgrade=-1) - self.comb += pll.reset.eq(~platform.request("cpu_reset")) + self.comb += pll.reset.eq(~platform.request("cpu_reset") | self.rst) pll.register_clkin(clk100_buf, 100e6) pll.create_clkout(self.cd_sys, sys_clk_freq) diff --git a/litex/boards/targets/de0nano.py b/litex/boards/targets/de0nano.py index b786ac78c..87eddd431 100755 --- a/litex/boards/targets/de0nano.py +++ b/litex/boards/targets/de0nano.py @@ -29,6 +29,7 @@ from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY class _CRG(Module): def __init__(self, platform, sys_clk_freq, sdram_rate="1:1"): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() if sdram_rate == "1:2": self.clock_domains.cd_sys2x = ClockDomain() @@ -43,6 +44,7 @@ class _CRG(Module): # PLL self.submodules.pll = pll = CycloneIVPLL(speedgrade="-6") + self.comb += pll.reset.eq(self.rst) pll.register_clkin(clk50, 50e6) pll.create_clkout(self.cd_sys, sys_clk_freq) if sdram_rate == "1:2": diff --git a/litex/boards/targets/genesys2.py b/litex/boards/targets/genesys2.py index 69cfc2a41..a097e9852 100755 --- a/litex/boards/targets/genesys2.py +++ b/litex/boards/targets/genesys2.py @@ -28,20 +28,21 @@ from liteeth.phy.s7rgmii import LiteEthPHYRGMII class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_idelay = ClockDomain() # # # self.submodules.pll = pll = S7MMCM(speedgrade=-2) - self.comb += pll.reset.eq(~platform.request("cpu_reset_n")) + self.comb += pll.reset.eq(~platform.request("cpu_reset_n") | self.rst) pll.register_clkin(platform.request("clk200"), 200e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq) - pll.create_clkout(self.cd_clk200, 200e6) + pll.create_clkout(self.cd_idelay, 200e6) - self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) # BaseSoC ------------------------------------------------------------------------------------------ diff --git a/litex/boards/targets/icebreaker.py b/litex/boards/targets/icebreaker.py index 25598e833..94a565050 100755 --- a/litex/boards/targets/icebreaker.py +++ b/litex/boards/targets/icebreaker.py @@ -29,7 +29,9 @@ from litex.soc.cores.up5kspram import Up5kSPRAM from litex.soc.cores.spi_flash import SpiFlash from litex.soc.cores.clock import iCE40PLL from litex.soc.integration.soc_core import * +from litex.soc.integration.soc import SoCRegion from litex.soc.integration.builder import * +from litex.soc.cores.led import LedChaser kB = 1024 mB = 1024*kB @@ -38,42 +40,39 @@ mB = 1024*kB class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_por = ClockDomain() + self.clock_domains.cd_por = ClockDomain(reset_less=True) # # # - # Clocking + # Clk/Rst clk12 = platform.request("clk12") rst_n = platform.request("user_btn_n") - if sys_clk_freq == 12e6: - self.comb += self.cd_sys.clk.eq(clk12) - else: - self.submodules.pll = pll = iCE40PLL(primitive="SB_PLL40_PAD") - pll.register_clkin(clk12, 12e6) - pll.create_clkout(self.cd_sys, sys_clk_freq) - platform.add_period_constraint(self.cd_sys.clk, 1e9/sys_clk_freq) # Power On Reset - por_cycles = 4096 - por_counter = Signal(log2_int(por_cycles), reset=por_cycles-1) - self.comb += self.cd_por.clk.eq(self.cd_sys.clk) - platform.add_period_constraint(self.cd_por.clk, 1e9/sys_clk_freq) - self.sync.por += If(por_counter != 0, por_counter.eq(por_counter - 1)) - self.specials += AsyncResetSynchronizer(self.cd_por, ~rst_n) - self.specials += AsyncResetSynchronizer(self.cd_sys, (por_counter != 0)) + por_count = Signal(16, reset=2**16-1) + por_done = Signal() + self.comb += self.cd_por.clk.eq(ClockSignal()) + self.comb += por_done.eq(por_count == 0) + self.sync.por += If(~por_done, por_count.eq(por_count - 1)) + + # PLL + self.submodules.pll = pll = iCE40PLL(primitive="SB_PLL40_PAD") + self.comb += pll.reset.eq(~rst_n | self.rst) + pll.register_clkin(clk12, 12e6) + pll.create_clkout(self.cd_sys, sys_clk_freq, with_reset=False) + self.specials += AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked) + platform.add_period_constraint(self.cd_sys.clk, 1e9/sys_clk_freq) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - SoCCore.mem_map = { - "sram": 0x10000000, - "spiflash": 0x20000000, - "csr": 0xf0000000, - } + mem_map = {**SoCCore.mem_map, **{"spiflash": 0x80000000}} def __init__(self, bios_flash_offset, **kwargs): sys_clk_freq = int(24e6) platform = icebreaker.Platform() + platform.add_extension(icebreaker.break_off_pmod) # Disable Integrated ROM/SRAM since too large for iCE40 and UP5K has specific SPRAM. kwargs["integrated_sram_size"] = 0 @@ -92,30 +91,32 @@ class BaseSoC(SoCCore): self.submodules.crg = _CRG(platform, sys_clk_freq) # 128KB SPRAM (used as SRAM) --------------------------------------------------------------- - self.submodules.spram = Up5kSPRAM(size=64*kB) - self.register_mem("sram", self.mem_map["sram"], self.spram.bus, 64*kB) + self.submodules.spram = Up5kSPRAM(size=128*kB) + self.bus.add_slave("sram", self.spram.bus, SoCRegion(size=128*kB)) # SPI Flash -------------------------------------------------------------------------------- - self.submodules.spiflash = SpiFlash(platform.request("spiflash4x"), dummy=6, endianness="little") - self.register_mem("spiflash", self.mem_map["spiflash"], self.spiflash.bus, size=16*mB) - self.add_csr("spiflash") + self.add_spi_flash(mode="1x", dummy_cycles=8) # Add ROM linker region -------------------------------------------------------------------- - self.add_memory_region("rom", self.mem_map["spiflash"] + bios_flash_offset, 32*kB, type="cached+linker") + self.bus.add_region("rom", SoCRegion( + origin = self.mem_map["spiflash"] + bios_flash_offset, + size = 32*kB, + linker = True) + ) # Leds ------------------------------------------------------------------------------------- - counter = Signal(32) - self.sync += counter.eq(counter + 1) - self.comb += platform.request("user_ledr_n").eq(counter[26]) - self.comb += platform.request("user_ledg_n").eq(~counter[26]) + self.submodules.leds = LedChaser( + pads = platform.request_all("user_led"), + sys_clk_freq = sys_clk_freq) + self.add_csr("leds") # Flash -------------------------------------------------------------------------------------------- def flash(bios_flash_offset): from litex.build.lattice.programmer import IceStormProgrammer prog = IceStormProgrammer() - prog.flash(bios_flash_offset, "soc_basesoc_icebreaker/software/bios/bios.bin") - prog.flash(0x00000000, "soc_basesoc_icebreaker/gateware/top.bin") + prog.flash(bios_flash_offset, "build/icebreaker/software/bios/bios.bin") + prog.flash(0x00000000, "build/icebreaker/gateware/icebreaker.bin") exit() # Build -------------------------------------------------------------------------------------------- diff --git a/litex/boards/targets/kc705.py b/litex/boards/targets/kc705.py index 320d0ca78..3c00c53c2 100755 --- a/litex/boards/targets/kc705.py +++ b/litex/boards/targets/kc705.py @@ -30,25 +30,26 @@ from liteeth.phy import LiteEthPHY class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_idelay = ClockDomain() # # # self.submodules.pll = pll = S7MMCM(speedgrade=-2) - self.comb += pll.reset.eq(platform.request("cpu_reset")) + self.comb += pll.reset.eq(platform.request("cpu_reset") | self.rst) pll.register_clkin(platform.request("clk200"), 200e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq) - pll.create_clkout(self.cd_clk200, 200e6) + pll.create_clkout(self.cd_idelay, 200e6) - self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - def __init__(self, sys_clk_freq=int(125e6), with_ethernet=False, **kwargs): + def __init__(self, sys_clk_freq=int(125e6), with_ethernet=False, with_sata=False, **kwargs): platform = kc705.Platform() # SoCCore ---------------------------------------------------------------------------------- @@ -86,6 +87,41 @@ class BaseSoC(SoCCore): self.add_csr("ethphy") self.add_ethernet(phy=self.ethphy) + # SATA ------------------------------------------------------------------------------------- + if with_sata: + from litex.build.generic_platform import Subsignal, Pins + from litesata.phy import LiteSATAPHY + + # IOs + _sata_io = [ + # SFP 2 SATA Adapter / https://shop.trenz-electronic.de/en/TE0424-01-SFP-2-SATA-Adapter + ("sfp2sata", 0, + Subsignal("tx_p", Pins("H2")), + Subsignal("tx_n", Pins("H1")), + Subsignal("rx_p", Pins("G4")), + Subsignal("rx_n", Pins("G3")), + ), + ] + platform.add_extension(_sata_io) + + # RefClk, Generate 150MHz from PLL. + self.clock_domains.cd_sata_refclk = ClockDomain() + self.crg.pll.create_clkout(self.cd_sata_refclk, 150e6) + sata_refclk = ClockSignal("sata_refclk") + platform.add_platform_command("set_property SEVERITY {{Warning}} [get_drc_checks REQP-52]") + + # PHY + self.submodules.sata_phy = LiteSATAPHY(platform.device, + refclk = sata_refclk, + pads = platform.request("sfp2sata"), + gen = "gen2", + clk_freq = sys_clk_freq, + data_width = 16) + self.add_csr("sata_phy") + + # Core + self.add_sata(phy=self.sata_phy, mode="read+write") + # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser( pads = platform.request_all("user_led"), @@ -101,9 +137,10 @@ def main(): builder_args(parser) soc_sdram_args(parser) parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support") + parser.add_argument("--with-sata", action="store_true", help="Enable SATA support (over SFP2SATA)") args = parser.parse_args() - soc = BaseSoC(with_ethernet=args.with_ethernet, **soc_sdram_argdict(args)) + soc = BaseSoC(with_ethernet=args.with_ethernet, with_sata=args.with_sata, **soc_sdram_argdict(args)) builder = Builder(soc, **builder_argdict(args)) builder.build(run=args.build) diff --git a/litex/boards/targets/kcu105.py b/litex/boards/targets/kcu105.py index 83a4e684f..88ef5b6b7 100755 --- a/litex/boards/targets/kcu105.py +++ b/litex/boards/targets/kcu105.py @@ -28,19 +28,20 @@ from liteeth.phy.ku_1000basex import KU_1000BASEX class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys4x = ClockDomain(reset_less=True) self.clock_domains.cd_pll4x = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_idelay = ClockDomain() self.clock_domains.cd_eth = ClockDomain() # # # self.submodules.pll = pll = USMMCM(speedgrade=-2) - self.comb += pll.reset.eq(platform.request("cpu_reset")) + self.comb += pll.reset.eq(platform.request("cpu_reset") | self.rst) pll.register_clkin(platform.request("clk125"), 125e6) pll.create_clkout(self.cd_pll4x, sys_clk_freq*4, buf=None, with_reset=False) - pll.create_clkout(self.cd_clk200, 200e6, with_reset=False) + pll.create_clkout(self.cd_idelay, 200e6, with_reset=False) pll.create_clkout(self.cd_eth, 200e6) self.specials += [ @@ -49,10 +50,10 @@ class _CRG(Module): i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys.clk), Instance("BUFGCE", name="main_bufgce", i_CE=1, i_I=self.cd_pll4x.clk, o_O=self.cd_sys4x.clk), - AsyncResetSynchronizer(self.cd_clk200, ~pll.locked), + AsyncResetSynchronizer(self.cd_idelay, ~pll.locked), ] - self.submodules.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_clk200, cd_sys=self.cd_sys) + self.submodules.idelayctrl = USIDELAYCTRL(cd_ref=self.cd_idelay, cd_sys=self.cd_sys) # BaseSoC ------------------------------------------------------------------------------------------ diff --git a/litex/boards/targets/minispartan6.py b/litex/boards/targets/minispartan6.py index df2094fcb..a309552e2 100755 --- a/litex/boards/targets/minispartan6.py +++ b/litex/boards/targets/minispartan6.py @@ -32,6 +32,7 @@ from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY class _CRG(Module): def __init__(self, platform, sys_clk_freq, sdram_rate="1:1"): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() if sdram_rate == "1:2": self.clock_domains.cd_sys2x = ClockDomain() @@ -46,6 +47,7 @@ class _CRG(Module): # PLL self.submodules.pll = pll = S6PLL(speedgrade=-1) + self.comb += pll.reset.eq(self.rst) pll.register_clkin(clk32, 32e6) pll.create_clkout(self.cd_sys, sys_clk_freq) if sdram_rate == "1:2": diff --git a/litex/boards/targets/netv2.py b/litex/boards/targets/netv2.py index d5e4d31a1..f636e5731 100755 --- a/litex/boards/targets/netv2.py +++ b/litex/boards/targets/netv2.py @@ -28,25 +28,27 @@ from liteeth.phy.rmii import LiteEthPHYRMII class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() 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_idelay = ClockDomain() self.clock_domains.cd_clk100 = ClockDomain() self.clock_domains.cd_eth = ClockDomain() # # # self.submodules.pll = pll = S7PLL(speedgrade=-1) + self.comb += pll.reset.eq(self.rst) pll.register_clkin(platform.request("clk50"), 50e6) 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_idelay, 200e6) pll.create_clkout(self.cd_clk100, 100e6) pll.create_clkout(self.cd_eth, 50e6) - self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) # BaseSoC ------------------------------------------------------------------------------------------ diff --git a/litex/boards/targets/nexys4ddr.py b/litex/boards/targets/nexys4ddr.py index 06f70139e..b71c403b7 100755 --- a/litex/boards/targets/nexys4ddr.py +++ b/litex/boards/targets/nexys4ddr.py @@ -28,24 +28,25 @@ from liteeth.phy.rmii import LiteEthPHYRMII class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_sys2x = ClockDomain(reset_less=True) self.clock_domains.cd_sys2x_dqs = ClockDomain(reset_less=True) - self.clock_domains.cd_clk200 = ClockDomain() + self.clock_domains.cd_idelay = ClockDomain() self.clock_domains.cd_eth = ClockDomain() # # # self.submodules.pll = pll = S7MMCM(speedgrade=-1) - self.comb += pll.reset.eq(~platform.request("cpu_reset")) + self.comb += pll.reset.eq(~platform.request("cpu_reset") | self.rst) pll.register_clkin(platform.request("clk100"), 100e6) pll.create_clkout(self.cd_sys, sys_clk_freq) pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq) pll.create_clkout(self.cd_sys2x_dqs, 2*sys_clk_freq, phase=90) - pll.create_clkout(self.cd_clk200, 200e6) + pll.create_clkout(self.cd_idelay, 200e6) pll.create_clkout(self.cd_eth, 50e6) - self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) # BaseSoC ------------------------------------------------------------------------------------------ diff --git a/litex/boards/targets/nexys_video.py b/litex/boards/targets/nexys_video.py index a0fdc2e51..fa3ffe8b5 100755 --- a/litex/boards/targets/nexys_video.py +++ b/litex/boards/targets/nexys_video.py @@ -28,29 +28,30 @@ from liteeth.phy.s7rgmii import LiteEthPHYRGMII class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() 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_idelay = ClockDomain() self.clock_domains.cd_clk100 = ClockDomain() # # # self.submodules.pll = pll = S7MMCM(speedgrade=-1) - self.comb += pll.reset.eq(~platform.request("cpu_reset")) + self.comb += pll.reset.eq(~platform.request("cpu_reset") | self.rst) 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_idelay, 200e6) pll.create_clkout(self.cd_clk100, 100e6) - self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_clk200) + self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay) # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - def __init__(self, sys_clk_freq=int(100e6), with_ethernet=False, **kwargs): + def __init__(self, sys_clk_freq=int(100e6), with_ethernet=False, with_sata=False, **kwargs): platform = nexys_video.Platform() # SoCCore ---------------------------------------------------------------------------------- @@ -87,6 +88,36 @@ class BaseSoC(SoCCore): self.add_csr("ethphy") self.add_ethernet(phy=self.ethphy) + # SATA ------------------------------------------------------------------------------------- + if with_sata: + from litex.build.generic_platform import Subsignal, Pins + from litesata.phy import LiteSATAPHY + + # IOs + _sata_io = [ + # AB09-FMCRAID / https://www.dgway.com/AB09-FMCRAID_E.html + ("fmc2sata", 0, + Subsignal("clk_p", Pins("LPC:GBTCLK0_M2C_P")), + Subsignal("clk_n", Pins("LPC:GBTCLK0_M2C_N")), + Subsignal("tx_p", Pins("LPC:DP0_C2M_P")), + Subsignal("tx_n", Pins("LPC:DP0_C2M_N")), + Subsignal("rx_p", Pins("LPC:DP0_M2C_P")), + Subsignal("rx_n", Pins("LPC:DP0_M2C_N")) + ), + ] + platform.add_extension(_sata_io) + + # PHY + self.submodules.sata_phy = LiteSATAPHY(platform.device, + pads = platform.request("fmc2sata"), + gen = "gen2", + clk_freq = sys_clk_freq, + data_width = 16) + self.add_csr("sata_phy") + + # Core + self.add_sata(phy=self.sata_phy, mode="read+write") + # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser( pads = platform.request_all("user_led"), @@ -101,12 +132,13 @@ def main(): parser.add_argument("--load", action="store_true", help="Load bitstream") builder_args(parser) soc_sdram_args(parser) - parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support") + parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support") parser.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support") - parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support") + parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support") + parser.add_argument("--with-sata", action="store_true", help="Enable SATA support (over FMCRAID)") args = parser.parse_args() - soc = BaseSoC(with_ethernet=args.with_ethernet, **soc_sdram_argdict(args)) + soc = BaseSoC(with_ethernet=args.with_ethernet, with_sata=args.with_sata, **soc_sdram_argdict(args)) assert not (args.with_spi_sdcard and args.with_sdcard) if args.with_spi_sdcard: soc.add_spi_sdcard() diff --git a/litex/boards/targets/ulx3s.py b/litex/boards/targets/ulx3s.py index 6a5404021..fb68a6226 100755 --- a/litex/boards/targets/ulx3s.py +++ b/litex/boards/targets/ulx3s.py @@ -35,6 +35,7 @@ from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY class _CRG(Module): def __init__(self, platform, sys_clk_freq, with_usb_pll=False, sdram_rate="1:1"): + self.rst = Signal() self.clock_domains.cd_sys = ClockDomain() if sdram_rate == "1:2": self.clock_domains.cd_sys2x = ClockDomain() @@ -50,7 +51,7 @@ class _CRG(Module): # PLL self.submodules.pll = pll = ECP5PLL() - self.comb += pll.reset.eq(rst) + self.comb += pll.reset.eq(rst | self.rst) pll.register_clkin(clk25, 25e6) pll.create_clkout(self.cd_sys, sys_clk_freq) if sdram_rate == "1:2": @@ -58,11 +59,11 @@ class _CRG(Module): pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) # Idealy 90° but needs to be increased. else: pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90) - self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll.locked | rst) # USB PLL if with_usb_pll: self.submodules.usb_pll = usb_pll = ECP5PLL() + self.comb += usb_pll.reset.eq(rst | self.rst) usb_pll.register_clkin(clk25, 25e6) self.clock_domains.cd_usb_12 = ClockDomain() self.clock_domains.cd_usb_48 = ClockDomain() @@ -79,10 +80,10 @@ class _CRG(Module): # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - def __init__(self, device="LFE5U-45F", toolchain="trellis", + def __init__(self, device="LFE5U-45F", revision="2.0", toolchain="trellis", sys_clk_freq=int(50e6), sdram_module_cls="MT48LC16M16", sdram_rate="1:1", **kwargs): - platform = ulx3s.Platform(device=device, toolchain=toolchain) + platform = ulx3s.Platform(device=device, revision=revision, toolchain=toolchain) # SoCCore ---------------------------------------------------------------------------------- SoCCore.__init__(self, platform, sys_clk_freq, @@ -132,6 +133,7 @@ def main(): parser.add_argument("--load", action="store_true", help="Load bitstream") parser.add_argument("--toolchain", default="trellis", help="Gateware toolchain to use, trellis (default) or diamond") parser.add_argument("--device", dest="device", default="LFE5U-45F", help="FPGA device, ULX3S can be populated with LFE5U-45F (default) or LFE5U-85F") + parser.add_argument("--revision", default="2.0", type=str, help="Board revision 2.0 (default), 1.7") parser.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency (default=50MHz)") parser.add_argument("--sdram-module", default="MT48LC16M16", help="SDRAM module: MT48LC16M16, AS4C32M16 or AS4C16M16 (default=MT48LC16M16)") parser.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support") @@ -143,7 +145,7 @@ def main(): trellis_args(parser) args = parser.parse_args() - soc = BaseSoC(device=args.device, toolchain=args.toolchain, + soc = BaseSoC(device=args.device, revision=args.revision, toolchain=args.toolchain, sys_clk_freq = int(float(args.sys_clk_freq)), sdram_module_cls = args.sdram_module, sdram_rate = args.sdram_rate, diff --git a/litex/boards/targets/versa_ecp5.py b/litex/boards/targets/versa_ecp5.py index 5f6a083c4..136bdb1b1 100755 --- a/litex/boards/targets/versa_ecp5.py +++ b/litex/boards/targets/versa_ecp5.py @@ -32,6 +32,7 @@ from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII class _CRG(Module): def __init__(self, platform, sys_clk_freq): + self.rst = Signal() self.clock_domains.cd_init = ClockDomain() self.clock_domains.cd_por = ClockDomain(reset_less=True) self.clock_domains.cd_sys = ClockDomain() @@ -56,6 +57,7 @@ class _CRG(Module): # PLL self.submodules.pll = pll = ECP5PLL() + self.comb += pll.reset.eq(~por_done | ~rst_n | self.rst) pll.register_clkin(clk100, 100e6) pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq) pll.create_clkout(self.cd_init, 25e6) @@ -70,15 +72,14 @@ class _CRG(Module): i_CLKI = self.cd_sys2x.clk, i_RST = self.reset, o_CDIVX = self.cd_sys.clk), - AsyncResetSynchronizer(self.cd_init, ~por_done | ~pll.locked | ~rst_n), - AsyncResetSynchronizer(self.cd_sys, ~por_done | ~pll.locked | ~rst_n | self.reset), - AsyncResetSynchronizer(self.cd_sys2x, ~por_done | ~pll.locked | ~rst_n | self.reset), + AsyncResetSynchronizer(self.cd_sys, ~pll.locked | self.reset), + AsyncResetSynchronizer(self.cd_sys2x, ~pll.locked | self.reset), ] # BaseSoC ------------------------------------------------------------------------------------------ class BaseSoC(SoCCore): - def __init__(self, sys_clk_freq=int(75e6), device="LFE5UM5G", with_ethernet=False, toolchain="trellis", **kwargs): + def __init__(self, sys_clk_freq=int(75e6), device="LFE5UM5G", with_ethernet=False, with_etherbone=False, eth_phy=0, toolchain="trellis", **kwargs): platform = versa_ecp5.Platform(toolchain=toolchain, device=device) # FIXME: adapt integrated rom size for Microwatt @@ -112,13 +113,16 @@ class BaseSoC(SoCCore): l2_cache_reverse = True ) - # Ethernet --------------------------------------------------------------------------------- - if with_ethernet: + # Ethernet / Etherbone --------------------------------------------------------------------- + if with_ethernet or with_etherbone: self.submodules.ethphy = LiteEthPHYRGMII( - clock_pads = self.platform.request("eth_clocks"), - pads = self.platform.request("eth")) + clock_pads = self.platform.request("eth_clocks", eth_phy), + pads = self.platform.request("eth", eth_phy)) self.add_csr("ethphy") - self.add_ethernet(phy=self.ethphy) + if with_ethernet: + self.add_ethernet(phy=self.ethphy) + if with_etherbone: + self.add_etherbone(phy=self.ethphy) # Leds ------------------------------------------------------------------------------------- self.submodules.leds = LedChaser( @@ -136,15 +140,20 @@ def main(): builder_args(parser) soc_sdram_args(parser) trellis_args(parser) - parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency (default=75MHz)") - parser.add_argument("--device", default="LFE5UM5G", help="ECP5 device (LFE5UM5G (default) or LFE5UM)") - parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support") + parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency (default=75MHz)") + parser.add_argument("--device", default="LFE5UM5G", help="ECP5 device (LFE5UM5G (default) or LFE5UM)") + parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support") + parser.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support") + parser.add_argument("--eth-phy", default=0, type=int, help="Ethernet PHY 0 or 1 (default=0)") args = parser.parse_args() + assert not (args.with_ethernet and args.with_etherbone) soc = BaseSoC(sys_clk_freq=int(float(args.sys_clk_freq)), - device = args.device, - with_ethernet = args.with_ethernet, - toolchain = args.toolchain, + device = args.device, + with_ethernet = args.with_ethernet, + with_etherbone = args.with_etherbone, + eth_phy = args.eth_phy, + toolchain = args.toolchain, **soc_sdram_argdict(args)) builder = Builder(soc, **builder_argdict(args)) builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {} diff --git a/litex/build/altera/quartus.py b/litex/build/altera/quartus.py index b1aff126b..ad8e2e2c2 100644 --- a/litex/build/altera/quartus.py +++ b/litex/build/altera/quartus.py @@ -10,6 +10,7 @@ import os import subprocess import sys import math +from shutil import which from migen.fhdl.structure import _Fragment @@ -156,8 +157,13 @@ def _run_script(script): else: shell = ["bash"] + if which("quartus_map") is None: + msg = "Unable to find Quartus toolchain, please:\n" + msg += "- Add Quartus toolchain to your $PATH." + raise OSError(msg) + if subprocess.call(shell + [script]) != 0: - raise OSError("Subprocess failed") + raise OSError("Error occured during Quartus's script execution.") # AlteraQuartusToolchain --------------------------------------------------------------------------- diff --git a/litex/build/gowin/gowin.py b/litex/build/gowin/gowin.py index ea486a187..337d2ab93 100644 --- a/litex/build/gowin/gowin.py +++ b/litex/build/gowin/gowin.py @@ -7,6 +7,7 @@ import os import subprocess +from shutil import which from migen.fhdl.structure import _Fragment @@ -26,7 +27,7 @@ def _build_cst(named_sc, named_pc): for name, pin, other in flat_sc: lines.append(f"IO_LOC \"{name}\" {pin};") - + for c in other: if isinstance(c, IOStandard): lines.append(f"IO_PORT \"{name}\" IO_TYPE={c.name};") @@ -97,7 +98,7 @@ class GowinToolchain(): v_file = build_name + ".v" v_output.write(v_file) platform.add_source(v_file) - + if platform.verilog_include_paths: self.options['include_path'] = '{' + ';'.join(platform.verilog_include_paths) + '}' @@ -115,7 +116,13 @@ class GowinToolchain(): # Run if run: - subprocess.run(["gw_sh", "run.tcl"]) + if which("gw_sh") is None: + msg = "Unable to find Gowin toolchain, please:\n" + msg += "- Add Gowin toolchain to your $PATH." + raise OSError(msg) + + if subprocess.call(["gw_sh", "run.tcl"]) != 0: + raise OSError("Error occured during Gowin's script execution.") os.chdir(cwd) diff --git a/litex/build/lattice/diamond.py b/litex/build/lattice/diamond.py index 9868d1117..d330d0c31 100644 --- a/litex/build/lattice/diamond.py +++ b/litex/build/lattice/diamond.py @@ -12,6 +12,7 @@ import sys import math import subprocess import shutil +from shutil import which from migen.fhdl.structure import _Fragment @@ -147,8 +148,13 @@ def _run_script(script): else: shell = ["bash"] + if which("diamondc") is None: + msg = "Unable to find Diamond toolchain, please:\n" + msg += "- Add Diamond toolchain to your $PATH.\n" + raise OSError(msg) + if subprocess.call(shell + [script]) != 0: - raise OSError("Subprocess failed") + raise OSError("Error occured during Diamond's script execution.") def _check_timing(build_name): lines = open("impl/{}_impl.par".format(build_name), "r").readlines() diff --git a/litex/build/lattice/icestorm.py b/litex/build/lattice/icestorm.py index 15724a96f..1336acb20 100644 --- a/litex/build/lattice/icestorm.py +++ b/litex/build/lattice/icestorm.py @@ -9,6 +9,7 @@ import os import sys import subprocess +from shutil import which from migen.fhdl.structure import _Fragment @@ -132,8 +133,13 @@ def _run_script(script): else: shell = ["bash"] + if which("yosys") is None or which("nextpnr-ice40") is None: + msg = "Unable to find Yosys/Nextpnr toolchain, please:\n" + msg += "- Add Yosys/Nextpnr toolchain to your $PATH." + raise OSError(msg) + if subprocess.call(shell + [script]) != 0: - raise OSError("Subprocess failed") + raise OSError("Error occured during Yosys/Nextpnr's script execution.") # LatticeIceStormToolchain ------------------------------------------------------------------------- diff --git a/litex/build/lattice/radiant.py b/litex/build/lattice/radiant.py index a2ad21937..2aa2380d2 100644 --- a/litex/build/lattice/radiant.py +++ b/litex/build/lattice/radiant.py @@ -13,6 +13,7 @@ import sys import math import subprocess import shutil +from shutil import which from migen.fhdl.structure import _Fragment @@ -22,6 +23,55 @@ from litex.build.generic_platform import * from litex.build import tools from litex.build.lattice import common +# Mixed Radiant+Yosys support + +def _run_yosys(device, sources, vincpaths, build_name): + ys_contents = "" + incflags = "" + for path in vincpaths: + incflags += " -I" + path + for filename, language, library in sources: + assert language != "vhdl" + ys_contents += "read_{}{} {}\n".format(language, incflags, filename) + + ys_contents += """\ +hierarchy -top {build_name} + +# Map keep to keep=1 for yosys +log +log XX. Converting (* keep = "xxxx" *) attribute for Yosys +log +attrmap -tocase keep -imap keep="true" keep=1 -imap keep="false" keep=0 -remove keep=0 +select -list a:keep=1 + +# Add keep=1 for yosys to objects which have dont_touch="true" attribute. +log +log XX. Converting (* dont_touch = "true" *) attribute for Yosys +log +select -list a:dont_touch=true +setattr -set keep 1 a:dont_touch=true + +# Convert (* async_reg = "true" *) to async registers for Yosys. +# (* async_reg = "true", dont_touch = "true" *) reg xilinxmultiregimpl0_regs1 = 1'd0; +log +log XX. Converting (* async_reg = "true" *) attribute to async registers for Yosys +log +select -list a:async_reg=true +setattr -set keep 1 a:async_reg=true + +synth_nexus -top {build_name} -vm {build_name}_yosys.vm +""".format(build_name=build_name) + + ys_name = build_name + ".ys" + tools.write_to_file(ys_name, ys_contents) + + if which("yosys") is None: + msg = "Unable to find Yosys toolchain, please:\n" + msg += "- Add Yosys toolchain to your $PATH." + raise OSError(msg) + + if subprocess.call(["yosys", ys_name]) != 0: + raise OSError("Subprocess failed") # Constraints (.ldc) ------------------------------------------------------------------------------- @@ -48,7 +98,7 @@ def _build_pdc(named_sc, named_pc, clocks, vns, build_name): for sig, pins, others, resname in named_sc: if len(pins) > 1: for i, p in enumerate(pins): - pdc.append(_format_ldc(sig + "[" + str(i) + "]", p, others, resname)) + pdc.append(_format_ldc("{" + sig + "[" + str(i) + "]}", p, others, resname)) else: pdc.append(_format_ldc(sig, pins[0], others, resname)) if named_pc: @@ -68,7 +118,7 @@ def _build_pdc(named_sc, named_pc, clocks, vns, build_name): # Project (.tcl) ----------------------------------------------------------------------------------- -def _build_tcl(device, sources, vincpaths, build_name, pdc_file): +def _build_tcl(device, sources, vincpaths, build_name, pdc_file, synth_mode): tcl = [] # Create project tcl.append(" ".join([ @@ -86,8 +136,17 @@ def _build_tcl(device, sources, vincpaths, build_name, pdc_file): tcl.append("prj_set_impl_opt {include path} {\"" + vincpath + "\"}") # Add sources - for filename, language, library in sources: - tcl.append("prj_add_source \"{}\" -work {}".format(tcl_path(filename), library)) + if synth_mode == "yosys": + # NOTE: it is seemingly impossible to skip synthesis using the Tcl flow + # so we give Synplify the structural netlist from Yosys which it won't actually touch + # The other option is to call the low level Radiant commands starting from 'map' + # with the structural netlist from Yosys, but this would be harder to do in a cross + # platform way. + tcl.append("prj_add_source \"{}_yosys.vm\" -work work".format(build_name)) + library = "work" + else: + for filename, language, library in sources: + tcl.append("prj_add_source \"{}\" -work {}".format(tcl_path(filename), library)) tcl.append("prj_add_source \"{}\" -work {}".format(tcl_path(pdc_file), library)) @@ -142,11 +201,18 @@ def _build_script(build_name, device): def _run_script(script): if sys.platform in ("win32", "cygwin"): shell = ["cmd", "/c"] + tool = "pnmainc" else: shell = ["bash"] + tool = "radiantc" + + if which(tool) is None: + msg = "Unable to find Radiant toolchain, please:\n" + msg += "- Add Radiant toolchain to your $PATH." + raise OSError(msg) if subprocess.call(shell + [script]) != 0: - raise OSError("Subprocess failed") + raise OSError("Error occured during Radiant's script execution.") def _check_timing(build_name): lines = open("impl/{}_impl.par".format(build_name), "r").readlines() @@ -203,6 +269,7 @@ class LatticeRadiantToolchain: build_name = "top", run = True, timingstrict = True, + synth_mode = "radiant", **kwargs): # Create build directory @@ -227,13 +294,15 @@ class LatticeRadiantToolchain: pdc_file = build_dir + "\\" + build_name + ".pdc" # Generate design script file (.tcl) - _build_tcl(platform.device, platform.sources, platform.verilog_include_paths, build_name, pdc_file) + _build_tcl(platform.device, platform.sources, platform.verilog_include_paths, build_name, pdc_file, synth_mode) # Generate build script script = _build_script(build_name, platform.device) # Run if run: + if synth_mode == "yosys": + _run_yosys(platform.device, platform.sources, platform.verilog_include_paths, build_name) _run_script(script) if timingstrict: _check_timing(build_name) @@ -256,3 +325,10 @@ class LatticeRadiantToolchain: to.attr.add("keep") if (to, from_) not in self.false_paths: self.false_paths.add((from_, to)) + +def radiant_build_args(parser): + parser.add_argument("--synth-mode", default="vivado", help="synthesis mode (synplify or yosys, default=synplify)") + + +def radiant_build_argdict(args): + return {"synth_mode": args.synth_mode} diff --git a/litex/build/lattice/trellis.py b/litex/build/lattice/trellis.py index e4e4f5b76..39793fc18 100644 --- a/litex/build/lattice/trellis.py +++ b/litex/build/lattice/trellis.py @@ -9,6 +9,7 @@ import os import subprocess import sys +from shutil import which from migen.fhdl.structure import _Fragment @@ -160,8 +161,13 @@ def _run_script(script): else: shell = ["bash"] + if which("yosys") is None or which("nextpnr-ecp5") is None: + msg = "Unable to find Yosys/Nextpnr toolchain, please:\n" + msg += "- Add Yosys/Nextpnr toolchain to your $PATH." + raise OSError(msg) + if subprocess.call(shell + [script]) != 0: - raise OSError("Subprocess failed") + raise OSError("Error occured during Yosys/Nextpnr's script execution.") # LatticeTrellisToolchain -------------------------------------------------------------------------- diff --git a/litex/build/sim/verilator.py b/litex/build/sim/verilator.py index 4005b8924..37b4058aa 100644 --- a/litex/build/sim/verilator.py +++ b/litex/build/sim/verilator.py @@ -8,6 +8,7 @@ import os import sys import subprocess +from shutil import which from migen.fhdl.structure import _Fragment from litex import get_data_mod @@ -226,6 +227,11 @@ class SimVerilatorToolchain: # Run if run: + if which("verilator") is None: + msg = "Unable to find Verilator toolchain, please either:\n" + msg += "- Install Verilator.\n" + msg += "- Add Verilator toolchain to your $PATH." + raise OSError(msg) _compile_sim(build_name, verbose) run_as_root = False if sim_config.has_module("ethernet"): diff --git a/litex/build/xilinx/ise.py b/litex/build/xilinx/ise.py index 34fab5f1e..8607383ea 100644 --- a/litex/build/xilinx/ise.py +++ b/litex/build/xilinx/ise.py @@ -13,6 +13,7 @@ import os import subprocess import sys +from shutil import which from migen.fhdl.structure import _Fragment @@ -159,9 +160,16 @@ bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit{fail_stmt} build_script_file = "build_" + build_name + script_ext tools.write_to_file(build_script_file, build_script_contents, force_unix=False) command = shell + [build_script_file] - r = tools.subprocess_call_filtered(command, common.colors) - if r != 0: - raise OSError("Subprocess failed") + + if which("ise") is None: + msg = "Unable to find or source ISE toolchain, please either:\n" + msg += "- Source ISE's settings manually.\n" + msg += "- Or set LITEX_ISE_VIVADO environment variant to ISE's settings path.\n" + msg += "- Or add ISE toolchain to your $PATH." + raise OSError(msg) + + if tools.subprocess_call_filtered(command, common.colors) != 0: + raise OSError("Error occured during ISE's script execution.") # XilinxISEToolchain -------------------------------------------------------------------------------- diff --git a/litex/build/xilinx/symbiflow.py b/litex/build/xilinx/symbiflow.py index ebcc07b87..b764a6cb3 100644 --- a/litex/build/xilinx/symbiflow.py +++ b/litex/build/xilinx/symbiflow.py @@ -11,6 +11,7 @@ import sys import math from typing import NamedTuple, Union, List import re +from shutil import which from migen.fhdl.structure import _Fragment, wrap, Constant from migen.fhdl.specials import Instance @@ -94,8 +95,13 @@ class _MakefileGenerator: def _run_make(): - if tools.subprocess_call_filtered("make", []) != 0: - raise OSError("Subprocess failed") + if which("symbiflow_synth") is None: + msg = "Unable to find Symbiflow toolchain, please:\n" + msg += "- Add Symbiflow toolchain to your $PATH." + raise OSError(msg) + + if tools.subprocess_call_filtered(shell + [script], common.colors) != 0: + raise OSError("Error occured during Symbiflow's script execution.") # SymbiflowToolchain ------------------------------------------------------------------------------- diff --git a/litex/build/xilinx/vivado.py b/litex/build/xilinx/vivado.py index 071879d3b..26e9f6563 100644 --- a/litex/build/xilinx/vivado.py +++ b/litex/build/xilinx/vivado.py @@ -8,6 +8,7 @@ import os import subprocess import sys import math +from shutil import which from migen.fhdl.structure import _Fragment @@ -89,8 +90,15 @@ def _run_script(script): else: shell = ["bash"] + if which("vivado") is None: + msg = "Unable to find or source Vivado toolchain, please either:\n" + msg += "- Source Vivado's settings manually.\n" + msg += "- Or set LITEX_ENV_VIVADO environment variant to Vivado's settings path.\n" + msg += "- Or add Vivado toolchain to your $PATH." + raise OSError(msg) + if tools.subprocess_call_filtered(shell + [script], common.colors) != 0: - raise OSError("Subprocess failed") + raise OSError("Error occured during Vivado's script execution.") # XilinxVivadoToolchain ---------------------------------------------------------------------------- diff --git a/litex/soc/cores/clock.py b/litex/soc/cores/clock.py index 9a42a0de5..17194fe6f 100644 --- a/litex/soc/cores/clock.py +++ b/litex/soc/cores/clock.py @@ -98,7 +98,7 @@ class XilinxClocking(Module, AutoCSR): clkout = Signal() self.clkouts[self.nclkouts] = (clkout, freq, phase, margin) if with_reset: - self.specials += AsyncResetSynchronizer(cd, ~self.locked | self.reset) + self.specials += AsyncResetSynchronizer(cd, ~self.locked) if buf is None: self.comb += cd.clk.eq(clkout) else: @@ -193,8 +193,15 @@ class XilinxClocking(Module, AutoCSR): self.comb += self.drp_locked.status.eq(self.locked) self.logger.info("Exposing DRP interface.") + def add_reset_delay(self, cycles): + for i in range(cycles): + reset = Signal() + self.specials += Instance("FD", i_C=self.clkin, i_D=self.reset, o_Q=reset) + self.reset = reset + def do_finalize(self): assert hasattr(self, "clkin") + self.add_reset_delay(cycles=8) # Prevents interlock when reset driven from sys_clk. # Xilinx / Spartan6 -------------------------------------------------------------------------------- @@ -679,7 +686,7 @@ class iCE40PLL(Module): clkout = Signal() self.clkouts[self.nclkouts] = (clkout, freq, 0, margin) if with_reset: - self.specials += AsyncResetSynchronizer(cd, ~self.locked | self.reset) + self.specials += AsyncResetSynchronizer(cd, ~self.locked) self.comb += cd.clk.eq(clkout) create_clkout_log(self.logger, cd.name, freq, margin, self.nclkouts) self.nclkouts += 1 @@ -781,7 +788,7 @@ class ECP5PLL(Module): clkout = Signal() self.clkouts[self.nclkouts] = (clkout, freq, phase, margin) if with_reset: - self.specials += AsyncResetSynchronizer(cd, ~self.locked | self.reset) + self.specials += AsyncResetSynchronizer(cd, ~self.locked) self.comb += cd.clk.eq(clkout) create_clkout_log(self.logger, cd.name, freq, margin, self.nclkouts) self.nclkouts += 1 @@ -958,7 +965,7 @@ class IntelClocking(Module, AutoCSR): clkout = Signal() self.clkouts[self.nclkouts] = (clkout, freq, phase, margin) if with_reset: - self.specials += AsyncResetSynchronizer(cd, ~self.locked | self.reset) + self.specials += AsyncResetSynchronizer(cd, ~self.locked) self.comb += cd.clk.eq(clkout) create_clkout_log(self.logger, cd.name, freq, margin, self.nclkouts) self.nclkouts += 1 diff --git a/litex/soc/cores/code_8b10b.py b/litex/soc/cores/code_8b10b.py index f6bb0cf4f..0d4fc5e24 100644 --- a/litex/soc/cores/code_8b10b.py +++ b/litex/soc/cores/code_8b10b.py @@ -2,7 +2,7 @@ # This file is part of LiteX. # # Copyright (c) 2016-2017 Sebastien Bourdeauducq -# Copyright (c) 2019 Florent Kermarrec +# Copyright (c) 2019-2020 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause """ @@ -24,6 +24,12 @@ from operator import add from migen import * +from litex.soc.interconnect import stream + +# Helpers ------------------------------------------------------------------------------------------ + +def K(x, y): + return (y << 5) | x def disparity(word, nbits): n0 = 0 @@ -68,7 +74,7 @@ def reverse_table(inputs, nbits): return outputs -# 5b6b +# 5b6b --------------------------------------------------------------------------------------------- table_5b6b = [ 0b011000, @@ -109,11 +115,11 @@ table_5b6b_flip = list(table_5b6b_unbalanced) table_5b6b_flip[7] = True table_6b5b = reverse_table_flip(table_5b6b, table_5b6b_flip, 6) -# K.28 -table_6b5b[0b001111] = 0b11100 -table_6b5b[0b110000] = 0b11100 -# 3b4b +table_6b5b[0b001111] = 0b11100 # K.28 +table_6b5b[0b110000] = 0b11100 # K.28 + +# 3b4b --------------------------------------------------------------------------------------------- table_3b4b = [ 0b0100, @@ -142,7 +148,9 @@ table_4b3b_kn[0b1000] = 0b111 table_4b3b_kp[0b1110] = 0b000 table_4b3b_kp[0b0111] = 0b111 +# Single Encoder ----------------------------------------------------------------------------------- +@CEInserter() class SingleEncoder(Module): def __init__(self, lsb_first=False): self.d = Signal(8) @@ -240,20 +248,23 @@ class SingleEncoder(Module): else: self.comb += self.output.eq(output_msb_first) +# Encoder ------------------------------------------------------------------------------------------ class Encoder(Module): def __init__(self, nwords=1, lsb_first=False): - self.d = [Signal(8) for _ in range(nwords)] - self.k = [Signal() for _ in range(nwords)] - self.output = [Signal(10, reset_less=True) for _ in range(nwords)] + self.ce = Signal(reset=1) + self.d = [Signal(8) for _ in range(nwords)] + self.k = [Signal() for _ in range(nwords)] + self.output = [Signal(10, reset_less=True) for _ in range(nwords)] self.disparity = [Signal() for _ in range(nwords)] # # # encoders = [SingleEncoder(lsb_first) for _ in range(nwords)] + self.comb += [encoder.ce.eq(self.ce) for encoder in encoders] self.submodules += encoders - self.sync += encoders[0].disp_in.eq(encoders[-1].disp_out) + self.sync += If(self.ce, encoders[0].disp_in.eq(encoders[-1].disp_out)) for e1, e2 in zip(encoders, encoders[1:]): self.comb += e2.disp_in.eq(e1.disp_out) @@ -264,17 +275,19 @@ class Encoder(Module): encoder.k.eq(k) ] output.reset_less = True - self.sync += [ + self.sync += If(self.ce, output.eq(encoder.output), disparity.eq(encoder.disp_out) - ] + ) +# Decoder ------------------------------------------------------------------------------------------ class Decoder(Module): def __init__(self, lsb_first=False): - self.input = Signal(10) - self.d = Signal(8) - self.k = Signal() + self.ce = Signal(reset=1) + self.input = Signal(10) + self.d = Signal(8) + self.k = Signal() self.invalid = Signal() # # # @@ -292,11 +305,12 @@ class Decoder(Module): code3b = Signal(3, reset_less=True) mem_6b5b = Memory(5, len(table_6b5b), init=table_6b5b) - port_6b5b = mem_6b5b.get_port() + port_6b5b = mem_6b5b.get_port(has_re=True) self.specials += mem_6b5b, port_6b5b self.comb += port_6b5b.adr.eq(code6b) + self.comb += port_6b5b.re.eq(self.ce) - self.sync += [ + self.sync += If(self.ce, self.k.eq(0), If(code6b == 0b001111, self.k.eq(1), @@ -315,12 +329,61 @@ class Decoder(Module): ), code3b.eq(Array(table_4b3b)[code4b]) ), - ] + ) self.comb += code5b.eq(port_6b5b.dat_r) self.comb += self.d.eq(Cat(code5b, code3b)) # Basic invalid symbols detection: check that we have 4,5 or 6 ones in the symbol. This does # not report all invalid symbols but still allow detecting issues with the link. ones = Signal(4, reset_less=True) - self.sync += ones.eq(reduce(add, [self.input[i] for i in range(10)])) + self.sync += If(self.ce, ones.eq(reduce(add, [self.input[i] for i in range(10)]))) self.comb += self.invalid.eq((ones != 4) & (ones != 5) & (ones != 6)) + + +# Stream Encoder ----------------------------------------------------------------------------------- + +class StreamEncoder(stream.PipelinedActor): + def __init__(self, nwords=1): + self.sink = sink = stream.Endpoint([("d", nwords*8), ("k", nwords)]) + self.source = source = stream.Endpoint([("data", nwords*10)]) + stream.PipelinedActor.__init__(self, latency=2) + + # # # + + encoder = Encoder(nwords, True) + self.submodules += encoder + + # Control + self.comb += encoder.ce.eq(self.pipe_ce) + + # Datapath + for i in range(nwords): + self.comb += [ + encoder.k[i].eq(sink.k[i]), + encoder.d[i].eq(sink.d[8*i:8*(i+1)]), + source.data[10*i:10*(i+1)].eq(encoder.output[i]) + ] + +# Stream Encoder ----------------------------------------------------------------------------------- + +class StreamDecoder(stream.PipelinedActor): + def __init__(self, nwords=1): + self.sink = sink = stream.Endpoint([("data", nwords*10)]) + self.source = source = stream.Endpoint([("d", nwords*8), ("k", nwords)]) + stream.PipelinedActor.__init__(self, latency=1) + + # # # + + decoders = [Decoder(True) for _ in range(nwords)] + self.submodules += decoders + + # Control + self.comb += [decoders[i].ce.eq(self.pipe_ce) for i in range(nwords)] + + # Datapath + for i in range(nwords): + self.comb += [ + decoders[i].input.eq(sink.data[10*i:10*(i+1)]), + source.k[i].eq(decoders[i].k), + source.d[8*i:8*(i+1)].eq(decoders[i].d) + ] \ No newline at end of file diff --git a/litex/soc/cores/cpu/microwatt/core.py b/litex/soc/cores/cpu/microwatt/core.py index 61f20a580..d91088e24 100644 --- a/litex/soc/cores/cpu/microwatt/core.py +++ b/litex/soc/cores/cpu/microwatt/core.py @@ -3,6 +3,7 @@ # # Copyright (c) 2019 Florent Kermarrec # Copyright (c) 2019 Benjamin Herrenschmidt +# Copyright (c) 2020 Raptor Engineering # SPDX-License-Identifier: BSD-2-Clause import os @@ -11,11 +12,134 @@ from migen import * from litex import get_data_mod from litex.soc.interconnect import wishbone +from litex.soc.interconnect.csr import * +from litex.gen.common import reverse_bytes from litex.soc.cores.cpu import CPU CPU_VARIANTS = ["standard", "standard+ghdl"] +class XICSSlave(Module, AutoCSR): + def __init__(self, platform, core_irq_out=Signal(), int_level_in=Signal(16), endianness="big", variant="standard"): + self.variant = variant + + self.icp_bus = icp_bus = wishbone.Interface(data_width=32, adr_width=12) + self.ics_bus = ics_bus = wishbone.Interface(data_width=32, adr_width=12) + + # Bus endianness handlers + self.icp_dat_w = Signal(32) + self.icp_dat_r = Signal(32) + self.comb += self.icp_dat_w.eq(icp_bus.dat_w if endianness == "big" else reverse_bytes(icp_bus.dat_w)) + self.comb += icp_bus.dat_r.eq(self.icp_dat_r if endianness == "big" else reverse_bytes(self.icp_dat_r)) + self.ics_dat_w = Signal(32) + self.ics_dat_r = Signal(32) + self.comb += self.ics_dat_w.eq(ics_bus.dat_w if endianness == "big" else reverse_bytes(ics_bus.dat_w)) + self.comb += ics_bus.dat_r.eq(self.ics_dat_r if endianness == "big" else reverse_bytes(self.ics_dat_r)) + + # XICS signals + self.ics_icp_xfer_src = Signal(4) + self.ics_icp_xfer_pri = Signal(8) + + self.icp_params = dict( + # Clock / Reset + i_clk = ClockSignal(), + i_rst = ResetSignal(), + + # Wishbone bus + o_wishbone_dat_r = self.icp_dat_r, + o_wishbone_ack = icp_bus.ack, + + i_wishbone_adr = icp_bus.adr, + i_wishbone_dat_w = self.icp_dat_w, + i_wishbone_cyc = icp_bus.cyc, + i_wishbone_stb = icp_bus.stb, + i_wishbone_sel = icp_bus.sel, + i_wishbone_we = icp_bus.we, + + i_ics_in_src = self.ics_icp_xfer_src, + i_ics_in_pri = self.ics_icp_xfer_pri, + + o_core_irq_out = core_irq_out, + ) + + self.ics_params = dict( + # Clock / Reset + i_clk = ClockSignal(), + i_rst = ResetSignal(), + + # Wishbone bus + o_wishbone_dat_r = self.ics_dat_r, + o_wishbone_ack = ics_bus.ack, + + i_wishbone_adr = ics_bus.adr, + i_wishbone_dat_w = self.ics_dat_w, + i_wishbone_cyc = ics_bus.cyc, + i_wishbone_stb = ics_bus.stb, + i_wishbone_sel = ics_bus.sel, + i_wishbone_we = ics_bus.we, + + i_int_level_in = int_level_in, + + o_icp_out_src = self.ics_icp_xfer_src, + o_icp_out_pri = self.ics_icp_xfer_pri, + ) + + # add vhdl sources + self.add_sources(platform, use_ghdl_yosys_plugin="ghdl" in self.variant) + + @staticmethod + def add_sources(platform, use_ghdl_yosys_plugin=False): + sources = [ + # Common / Types / Helpers + "decode_types.vhdl", + "wishbone_types.vhdl", + "utils.vhdl", + "common.vhdl", + "helpers.vhdl", + + # XICS controller + "xics.vhdl", + ] + sdir = get_data_mod("cpu", "microwatt").data_location + cdir = os.path.dirname(__file__) + if use_ghdl_yosys_plugin: + from litex.build import tools + import subprocess + + # ICP + ys = [] + ys.append("ghdl --ieee=synopsys -fexplicit -frelaxed-rules --std=08 \\") + for source in sources: + ys.append(os.path.join(sdir, source) + " \\") + ys.append(os.path.join(os.path.dirname(__file__), "xics_wrapper.vhdl") + " \\") + ys.append("-e xics_icp_wrapper") + ys.append("chformal -assert -remove") + ys.append("write_verilog {}".format(os.path.join(cdir, "xics_icp.v"))) + tools.write_to_file(os.path.join(cdir, "xics_icp.ys"), "\n".join(ys)) + if subprocess.call(["yosys", "-q", "-m", "ghdl", os.path.join(cdir, "xics_icp.ys")]): + raise OSError("Unable to convert Microwatt XICS ICP controller to verilog, please check your GHDL-Yosys-plugin install") + platform.add_source(os.path.join(cdir, "xics_icp.v")) + + # ICS + ys = [] + ys.append("ghdl --ieee=synopsys -fexplicit -frelaxed-rules --std=08 \\") + for source in sources: + ys.append(os.path.join(sdir, source) + " \\") + ys.append(os.path.join(os.path.dirname(__file__), "xics_wrapper.vhdl") + " \\") + ys.append("-e xics_ics_wrapper") + ys.append("chformal -assert -remove") + ys.append("write_verilog {}".format(os.path.join(cdir, "xics_ics.v"))) + tools.write_to_file(os.path.join(cdir, "xics_ics.ys"), "\n".join(ys)) + if subprocess.call(["yosys", "-q", "-m", "ghdl", os.path.join(cdir, "xics_ics.ys")]): + raise OSError("Unable to convert Microwatt XICS ICP controller to verilog, please check your GHDL-Yosys-plugin install") + platform.add_source(os.path.join(cdir, "xics_ics.v")) + else: + platform.add_sources(sdir, *sources) + platform.add_source(os.path.join(os.path.dirname(__file__), "xics_wrapper.vhdl")) + + def do_finalize(self): + self.specials += Instance("xics_icp_wrapper", **self.icp_params) + self.specials += Instance("xics_ics_wrapper", **self.ics_params) class Microwatt(CPU): name = "microwatt" @@ -56,6 +180,8 @@ class Microwatt(CPU): self.wb_data = wb_data = wishbone.Interface(data_width=64, adr_width=29) self.periph_buses = [wb_insn, wb_data] self.memory_buses = [] + self.interrupt = Signal(16) + self.core_ext_irq = Signal() # # # @@ -95,16 +221,30 @@ class Microwatt(CPU): i_dmi_req = 0, i_dmi_wr = 0, #o_dmi_ack =, + + # Interrupt controller + i_core_ext_irq = self.core_ext_irq, ) # add vhdl sources self.add_sources(platform, use_ghdl_yosys_plugin="ghdl" in self.variant) + # add XICS controller + self.add_xics() + def set_reset_address(self, reset_address): assert not hasattr(self, "reset_address") self.reset_address = reset_address assert reset_address == 0x00000000 + def add_xics(self): + self.submodules.xics = XICSSlave( + platform = self.platform, + variant = self.variant, + core_irq_out = self.core_ext_irq, + int_level_in = self.interrupt, + endianness = self.endianness) + @staticmethod def add_sources(platform, use_ghdl_yosys_plugin=False): sources = [ diff --git a/litex/soc/cores/cpu/microwatt/crt0.S b/litex/soc/cores/cpu/microwatt/crt0.S index cfd670170..ad6e4e71d 100644 --- a/litex/soc/cores/cpu/microwatt/crt0.S +++ b/litex/soc/cores/cpu/microwatt/crt0.S @@ -1,4 +1,5 @@ /* Copyright 2013-2014 IBM Corp. + * Copyright 2020 Raptor Engineering, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -81,10 +82,27 @@ _start: bl main b . -#define EXCEPTION(nr) \ - .= nr; \ +#define REDZONE_SIZE (512) +#define REG_SAVE_SIZE ((32 + 5)*8) +#define STACK_FRAME_C_MINIMAL 64 + +#define SAVE_NIA (32*8) +#define SAVE_LR (33*8) +#define SAVE_CTR (34*8) +#define SAVE_CR (35*8) +#define SAVE_SRR1 (36*8) + +#define EXCEPTION(nr) \ + .= nr; \ b . +#define FORWARD_EXCEPTION(nr) \ + . = nr; \ + stdu %r1,-(REG_SAVE_SIZE+REDZONE_SIZE)(%r1); \ + std %r0, 1*8(%r1); \ + LOAD_IMM64(%r0, nr); \ + b __isr + /* More exception stubs */ EXCEPTION(0x100) EXCEPTION(0x200) @@ -92,11 +110,11 @@ _start: EXCEPTION(0x380) EXCEPTION(0x400) EXCEPTION(0x480) - EXCEPTION(0x500) + FORWARD_EXCEPTION(0x500) EXCEPTION(0x600) EXCEPTION(0x700) EXCEPTION(0x800) - EXCEPTION(0x900) + FORWARD_EXCEPTION(0x900) EXCEPTION(0x980) EXCEPTION(0xa00) EXCEPTION(0xb00) @@ -122,5 +140,130 @@ _start: EXCEPTION(0x1600) #endif +// Exception handler +__isr: +/* + * Assume where we are coming from has a stack and can save there. + * We save the full register set. Since we are calling out to C, we + * could just save the ABI volatile registers + */ +/* + * The first two lines below are executed in the exception handler, so that r0 + * can be used to store the origin exception vector + */ +// stdu %r1,-(REG_SAVE_SIZE+REDZONE_SIZE)(%r1) +// std %r0, 1*8(%r1) +// std %r1, 1*8(%r1) + std %r2, 2*8(%r1) + std %r3, 3*8(%r1) + std %r4, 4*8(%r1) + std %r5, 5*8(%r1) + std %r6, 6*8(%r1) + std %r7, 7*8(%r1) + std %r8, 8*8(%r1) + std %r9, 9*8(%r1) + std %r10, 10*8(%r1) + std %r11, 11*8(%r1) + std %r12, 12*8(%r1) + std %r13, 13*8(%r1) + std %r14, 14*8(%r1) + std %r15, 15*8(%r1) + std %r16, 16*8(%r1) + std %r17, 17*8(%r1) + std %r18, 18*8(%r1) + std %r19, 19*8(%r1) + std %r20, 20*8(%r1) + std %r21, 21*8(%r1) + std %r22, 22*8(%r1) + std %r23, 23*8(%r1) + std %r24, 24*8(%r1) + std %r25, 25*8(%r1) + std %r26, 26*8(%r1) + std %r27, 27*8(%r1) + std %r28, 28*8(%r1) + std %r29, 29*8(%r1) + std %r30, 30*8(%r1) + std %r31, 31*8(%r1) + mr %r10, %r0 + mfsrr0 %r0 + std %r0, SAVE_NIA(%r1) + mflr %r0 + std %r0, SAVE_LR(%r1) + mfctr %r0 + std %r0, SAVE_CTR(%r1) + mfcr %r0 + std %r0, SAVE_CR(%r1) + mfsrr1 %r0 + std %r0, SAVE_SRR1(%r1) + + stdu %r1,-STACK_FRAME_C_MINIMAL(%r1) + + /* Load IRQ handler address from SRAM */ + LOAD_IMM64(%r3, __isr_address) + ld %r3, 0(%r3) + + mtctr %r3, + mr %r3, %r10 + bctrl + nop + ld %r1, 0(%r1) + + ld %r0, 1*8(%r1) +// ld %r1, 1*8(%r1) // do this at rfid + ld %r2, 2*8(%r1) +// ld %r3, 3*8(%r1) // do this at rfid + ld %r4, 4*8(%r1) + ld %r5, 5*8(%r1) + ld %r6, 6*8(%r1) + ld %r7, 7*8(%r1) + ld %r8, 8*8(%r1) + ld %r9, 9*8(%r1) + ld %r10, 10*8(%r1) + ld %r11, 11*8(%r1) + ld %r12, 12*8(%r1) + ld %r13, 13*8(%r1) + ld %r14, 14*8(%r1) + ld %r15, 15*8(%r1) + ld %r16, 16*8(%r1) + ld %r17, 17*8(%r1) + ld %r18, 18*8(%r1) + ld %r19, 19*8(%r1) + ld %r20, 20*8(%r1) + ld %r21, 21*8(%r1) + ld %r22, 22*8(%r1) + ld %r23, 23*8(%r1) + ld %r24, 24*8(%r1) + ld %r25, 25*8(%r1) + ld %r26, 26*8(%r1) + ld %r27, 27*8(%r1) + ld %r28, 28*8(%r1) + ld %r29, 29*8(%r1) + ld %r30, 30*8(%r1) + ld %r31, 31*8(%r1) + + ld %r3, SAVE_LR(%r1) + mtlr %r3 + ld %r3, SAVE_CTR(%r1) + mtctr %r3 + ld %r3, SAVE_CR(%r1) + mtcr %r3 + ld %r3, SAVE_SRR1(%r1) + mtsrr1 %r3 + ld %r3, SAVE_NIA(%r1) + mtsrr0 %r3 + + /* restore %r3 */ + ld %r3, 3*8(%r1) + + /* do final fixup r1 */ + ld %r1, 0*8(%r1) + + rfid + .text + .globl __isr_address + .data + .align 8 +__isr_address: + .long isr \ No newline at end of file diff --git a/litex/soc/cores/cpu/microwatt/irq.h b/litex/soc/cores/cpu/microwatt/irq.h index 7374cf506..7f7fa6dcb 100644 --- a/litex/soc/cores/cpu/microwatt/irq.h +++ b/litex/soc/cores/cpu/microwatt/irq.h @@ -1,4 +1,161 @@ +// (c) 2020 Raptor Engineering, LLC + #ifndef __IRQ_H #define __IRQ_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +// Address of exception / IRQ handler routine +extern void * __rom_isr_address; +void isr(uint64_t vec); + +// External interrupt enable bit +#define PPC_MSR_EE_SHIFT 15 + +// XICS registers +#define PPC_XICS_XIRR_POLL 0x0 +#define PPC_XICS_XIRR 0x4 +#define PPC_XICS_RESV 0x8 +#define PPC_XICS_MFRR 0xc + +// Must match corresponding XICS ICS HDL parameter +#define PPC_XICS_SRC_NUM 16 + +// Default external interrupt priority set by software during IRQ enable +#define PPC_EXT_INTERRUPT_PRIO 0x08 + +uint8_t inline xics_icp_readb(int reg) +{ + return *((uint8_t*)(HOSTXICSICP_BASE + reg)); +} + +void inline xics_icp_writeb(int reg, uint8_t value) +{ + *((uint8_t*)(HOSTXICSICP_BASE + reg)) = value; +} + +uint32_t inline xics_icp_readw(int reg) +{ + return *((uint32_t*)(HOSTXICSICP_BASE + reg)); +} + +void inline xics_icp_writew(int reg, uint32_t value) +{ + *((uint32_t*)(HOSTXICSICP_BASE + reg)) = value; +} + +uint32_t inline xics_ics_read_xive(int irq_number) +{ + return *((uint32_t*)(HOSTXICSICS_BASE + 0x800 + (irq_number << 2))); +} + +void inline xics_ics_write_xive(int irq_number, uint32_t priority) +{ + *((uint32_t*)(HOSTXICSICS_BASE + 0x800 + (irq_number << 2))) = priority; +} + +void inline mtmsrd(uint64_t val) +{ + __asm__ volatile("mtmsrd %0" : : "r" (val) : "memory"); +} + +uint64_t inline mfmsr(void) +{ + uint64_t rval; + __asm__ volatile("mfmsr %0" : "=r" (rval) : : "memory"); + return rval; +} + +void inline mtdec(uint64_t val) +{ + __asm__ volatile("mtdec %0" : : "r" (val) : "memory"); +} + +uint64_t inline mfdec(void) +{ + uint64_t rval; + __asm__ volatile("mfdec %0" : "=r" (rval) : : "memory"); + return rval; +} + +static inline unsigned int irq_getie(void) +{ + return (mfmsr() & (1 << PPC_MSR_EE_SHIFT)) != 0; +} + +static inline void irq_setie(unsigned int ie) +{ + if (ie) + { + // Unmask all IRQs + xics_icp_writeb(PPC_XICS_XIRR, 0xff); + + // Enable DEC + external interrupts + mtmsrd(mfmsr() | (1 << PPC_MSR_EE_SHIFT)); + } + else + { + // Disable DEC + external interrupts + mtmsrd(mfmsr() & ~(1 << PPC_MSR_EE_SHIFT)); + + // Mask all IRQs + xics_icp_writeb(PPC_XICS_XIRR, 0x00); + } +} + +static inline unsigned int irq_getmask(void) +{ + // Compute mask from enabled external interrupts in ICS + uint32_t mask; + int irq; + mask = 0; + for (irq = PPC_XICS_SRC_NUM - 1; irq >= 0; irq--) { + mask = mask << 1; + if ((xics_ics_read_xive(irq) & 0xff) != 0xff) + mask |= 0x1; + } + return mask; +} + +static inline void irq_setmask(unsigned int mask) +{ + int irq; + + // Enable all interrupts at a fixed priority level for now + int priority_level = PPC_EXT_INTERRUPT_PRIO; + + // Iterate over IRQs configured in mask, and enable / mask in ICS + for (irq = 0; irq < PPC_XICS_SRC_NUM; irq++) { + if ((mask >> irq) & 0x1) + xics_ics_write_xive(irq, priority_level); + else + xics_ics_write_xive(irq, 0xff); + } +} + +static inline unsigned int irq_pending(void) +{ + // Compute pending interrupt bitmask from asserted external interrupts in ICS + uint32_t pending; + int irq; + pending = 0; + for (irq = PPC_XICS_SRC_NUM - 1; irq >= 0; irq--) { + pending = pending << 1; + if ((xics_ics_read_xive(irq) & (0x1 << 31)) != 0) + pending |= 0x1; + } + return pending; +} + +#ifdef __cplusplus +} +#endif + #endif /* __IRQ_H */ diff --git a/litex/soc/cores/cpu/microwatt/microwatt_wrapper.vhdl b/litex/soc/cores/cpu/microwatt/microwatt_wrapper.vhdl index 54aecc18b..ee134c339 100644 --- a/litex/soc/cores/cpu/microwatt/microwatt_wrapper.vhdl +++ b/litex/soc/cores/cpu/microwatt/microwatt_wrapper.vhdl @@ -2,6 +2,7 @@ -- This file is part of LiteX. -- -- Copyright (c) 2019 Florent Kermarrec +-- Copyright (c) 2020 Raptor Engineering, LLC -- SPDX-License-Identifier: BSD-2-Clause library ieee; @@ -50,6 +51,8 @@ entity microwatt_wrapper is dmi_wr : in std_ulogic; dmi_ack : out std_ulogic; + core_ext_irq : in std_ulogic; + terminated_out : out std_logic ); end microwatt_wrapper; @@ -62,8 +65,6 @@ architecture rtl of microwatt_wrapper is signal wishbone_data_in : wishbone_slave_out; signal wishbone_data_out : wishbone_master_out; - signal core_ext_irq : std_ulogic; - begin -- wishbone_insn mapping @@ -90,9 +91,6 @@ begin wishbone_data_sel <= wishbone_data_out.sel; wishbone_data_we <= wishbone_data_out.we; - -- core_ext_irq mapping - core_ext_irq <= '0'; - microwatt_core : entity work.core generic map ( SIM => SIM, diff --git a/litex/soc/cores/cpu/microwatt/xics_wrapper.vhdl b/litex/soc/cores/cpu/microwatt/xics_wrapper.vhdl new file mode 100644 index 000000000..d7d06850e --- /dev/null +++ b/litex/soc/cores/cpu/microwatt/xics_wrapper.vhdl @@ -0,0 +1,182 @@ +-- This file is Copyright (c) 2019 Florent Kermarrec +-- Copyright (c) 2020 Raptor Engineering, LLC +-- License: BSD + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.common.all; +use work.wishbone_types.all; + +entity xics_icp_wrapper is + port ( + clk : in std_logic; + rst : in std_logic; + + wishbone_dat_r : out std_ulogic_vector(31 downto 0); + wishbone_ack : out std_ulogic; + wishbone_stall : out std_ulogic; + + wishbone_adr : in std_ulogic_vector(29 downto 0); + wishbone_dat_w : in std_ulogic_vector(31 downto 0); + wishbone_cyc : in std_ulogic; + wishbone_stb : in std_ulogic; + wishbone_sel : in std_ulogic_vector(3 downto 0); + wishbone_we : in std_ulogic; + + ics_in_src : in std_ulogic_vector(3 downto 0); + ics_in_pri : in std_ulogic_vector(7 downto 0); + + core_irq_out : out std_ulogic + ); +end xics_icp_wrapper; + +architecture rtl of xics_icp_wrapper is + + signal wishbone_in : wb_io_master_out; + signal wishbone_out : wb_io_slave_out; + + signal ics_in : ics_to_icp_t; + +begin + -- wishbone mapping + wishbone_dat_r <= wishbone_out.dat; + wishbone_ack <= wishbone_out.ack; + wishbone_stall <= wishbone_out.stall; + + wishbone_in.adr <= wishbone_adr(27 downto 0) & "00"; + wishbone_in.dat <= wishbone_dat_w; + wishbone_in.cyc <= wishbone_cyc; + wishbone_in.stb <= wishbone_stb; + wishbone_in.sel <= wishbone_sel; + wishbone_in.we <= wishbone_we; + + ics_in.src <= ics_in_src; + ics_in.pri <= ics_in_pri; + + xics_icp : entity work.xics_icp + port map ( + clk => clk, + rst => rst, + + wb_in => wishbone_in, + wb_out => wishbone_out, + + ics_in => ics_in, + + core_irq_out => core_irq_out + ); + +end rtl; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.common.all; +use work.wishbone_types.all; + +entity xics_ics_wrapper is + port ( + clk : in std_logic; + rst : in std_logic; + + wishbone_dat_r : out std_ulogic_vector(31 downto 0); + wishbone_ack : out std_ulogic; + wishbone_stall : out std_ulogic; + + wishbone_adr : in std_ulogic_vector(29 downto 0); + wishbone_dat_w : in std_ulogic_vector(31 downto 0); + wishbone_cyc : in std_ulogic; + wishbone_stb : in std_ulogic; + wishbone_sel : in std_ulogic_vector(3 downto 0); + wishbone_we : in std_ulogic; + + int_level_in : in std_ulogic_vector(31 downto 0); + + icp_out_src : out std_ulogic_vector(3 downto 0); + icp_out_pri : out std_ulogic_vector(7 downto 0) + ); +end xics_ics_wrapper; + +architecture rtl of xics_ics_wrapper is + + signal wishbone_in : wb_io_master_out; + signal wishbone_out : wb_io_slave_out; + + signal icp_out : ics_to_icp_t; + signal int_level_uw : std_ulogic_vector(255 downto 0); + +begin + -- wishbone mapping + wishbone_dat_r <= wishbone_out.dat; + wishbone_ack <= wishbone_out.ack; + wishbone_stall <= wishbone_out.stall; + + wishbone_in.adr <= wishbone_adr(27 downto 0) & "00"; + wishbone_in.dat <= wishbone_dat_w; + wishbone_in.cyc <= wishbone_cyc; + wishbone_in.stb <= wishbone_stb; + wishbone_in.sel <= wishbone_sel; + wishbone_in.we <= wishbone_we; + + icp_out_src <= icp_out.src; + icp_out_pri <= icp_out.pri; + + -- Assign external interrupts + interrupts: process(all) + begin + int_level_uw <= (others => '0'); + int_level_uw(0) <= int_level_in(0); + int_level_uw(1) <= int_level_in(1); + int_level_uw(2) <= int_level_in(2); + int_level_uw(3) <= int_level_in(3); + int_level_uw(4) <= int_level_in(4); + int_level_uw(5) <= int_level_in(5); + int_level_uw(6) <= int_level_in(6); + int_level_uw(7) <= int_level_in(7); + int_level_uw(8) <= int_level_in(8); + int_level_uw(9) <= int_level_in(9); + int_level_uw(10) <= int_level_in(10); + int_level_uw(11) <= int_level_in(11); + int_level_uw(12) <= int_level_in(12); + int_level_uw(13) <= int_level_in(13); + int_level_uw(14) <= int_level_in(14); + int_level_uw(15) <= int_level_in(15); + int_level_uw(16) <= int_level_in(16); + int_level_uw(17) <= int_level_in(17); + int_level_uw(18) <= int_level_in(18); + int_level_uw(19) <= int_level_in(19); + int_level_uw(20) <= int_level_in(20); + int_level_uw(21) <= int_level_in(21); + int_level_uw(22) <= int_level_in(22); + int_level_uw(23) <= int_level_in(23); + int_level_uw(24) <= int_level_in(24); + int_level_uw(25) <= int_level_in(25); + int_level_uw(26) <= int_level_in(26); + int_level_uw(27) <= int_level_in(27); + int_level_uw(28) <= int_level_in(28); + int_level_uw(29) <= int_level_in(29); + int_level_uw(30) <= int_level_in(30); + int_level_uw(31) <= int_level_in(31); + end process; + + xics_ics : entity work.xics_ics + generic map ( + SRC_NUM => 16 + ) + port map ( + clk => clk, + rst => rst, + + wb_in => wishbone_in, + wb_out => wishbone_out, + + int_level_in => int_level_uw, + icp_out => icp_out + ); + +end rtl; \ No newline at end of file diff --git a/litex/soc/cores/cpu/zynq7000/core.py b/litex/soc/cores/cpu/zynq7000/core.py index 79fc04994..6319a393d 100644 --- a/litex/soc/cores/cpu/zynq7000/core.py +++ b/litex/soc/cores/cpu/zynq7000/core.py @@ -215,7 +215,7 @@ class Zynq7000(CPU): assert len(self.axi_hp_slaves) < 4 n = len(self.axi_hp_slaves) axi_hpn = axi.AXIInterface(data_width=64, address_width=32, id_width=6) - self.axi_hp_masters.append(axi_hpn) + self.axi_hp_slaves.append(axi_hpn) self.cpu_params.update({ # AXI HP0 clk f"i_S_AXI_HP{n}_ACLK" : ClockSignal("ps7"), diff --git a/litex/soc/cores/icap.py b/litex/soc/cores/icap.py index c59180047..10000e2bf 100644 --- a/litex/soc/cores/icap.py +++ b/litex/soc/cores/icap.py @@ -1,7 +1,7 @@ # # This file is part of LiteX. # -# Copyright (c) 2019 Florent Kermarrec +# Copyright (c) 2019-2020 Florent Kermarrec # SPDX-License-Identifier: BSD-2-Clause from migen import * @@ -76,6 +76,10 @@ class ICAP(Module, AutoCSR): ) ] + # CSR + if with_csr: + self.add_csr() + def add_csr(self): self._addr = CSRStorage(5, reset_less=True, description="ICAP Write Address.") self._data = CSRStorage(32, reset_less=True, description="ICAP Write Data.") diff --git a/litex/soc/integration/builder.py b/litex/soc/integration/builder.py index dab008aac..e3a91584d 100644 --- a/litex/soc/integration/builder.py +++ b/litex/soc/integration/builder.py @@ -37,7 +37,9 @@ soc_software_packages = [ "liblitedram", "libliteeth", "liblitespi", + "libfatfs", "liblitesdcard", + "liblitesata", "bios" ] diff --git a/litex/soc/integration/export.py b/litex/soc/integration/export.py index c1957703b..2a6c01484 100644 --- a/litex/soc/integration/export.py +++ b/litex/soc/integration/export.py @@ -347,9 +347,9 @@ def get_csr_svd(soc, vendor="litex", name="soc", description=None): interrupts[csr] = irq documented_regions = [] - for name, region in soc.csr.regions.items(): + for region_name, region in soc.csr.regions.items(): documented_regions.append(DocumentedCSRRegion( - name = name, + name = region_name, region = region, csr_data_width = soc.csr.data_width) ) @@ -431,9 +431,9 @@ def get_csr_svd(soc, vendor="litex", name="soc", description=None): if len(soc.mem_regions) > 0: svd.append(' ') svd.append(' ') - for name, region in soc.mem_regions.items(): + for region_name, region in soc.mem_regions.items(): svd.append(' ') - svd.append(' {}'.format(name.upper())) + svd.append(' {}'.format(region_name.upper())) svd.append(' 0x{:08X}'.format(region.origin)) svd.append(' 0x{:08X}'.format(region.size)) svd.append(' ') diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index b57d3984a..d3212a404 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -914,6 +914,12 @@ class SoC(Module): "axi-lite": axi.AXILiteInterconnectShared, }[self.bus.standard] + # SoC Reset -------------------------------------------------------------------------------- + # Connect SoCController's reset to CRG's reset if presents. + if hasattr(self, "ctrl") and hasattr(self, "crg"): + if hasattr(self.ctrl, "_reset") and hasattr(self.crg, "rst"): + self.comb += self.crg.rst.eq(self.ctrl._reset.re) + # SoC CSR bridge --------------------------------------------------------------------------- # FIXME: for now, use registered CSR bridge when SDRAM is present; find the best compromise. self.add_csr_bridge(self.mem_map["csr"], register=hasattr(self, "sdram")) @@ -1135,7 +1141,7 @@ class LiteXSoC(SoC): self.bus.add_master(name="uartbone", master=self.uartbone.wishbone) # Add SDRAM ------------------------------------------------------------------------------------ - def add_sdram(self, name, phy, module, origin, size=None, with_soc_interconnect=True, + def add_sdram(self, name, phy, module, origin, size=None, with_bist=False, with_soc_interconnect=True, l2_cache_size = 8192, l2_cache_min_data_width = 128, l2_cache_reverse = True, @@ -1147,6 +1153,7 @@ class LiteXSoC(SoC): from litedram.core import LiteDRAMCore from litedram.frontend.wishbone import LiteDRAMWishbone2Native from litedram.frontend.axi import LiteDRAMAXI2Native + from litedram.frontend.bist import LiteDRAMBISTGenerator, LiteDRAMBISTChecker # LiteDRAM core self.submodules.sdram = LiteDRAMCore( @@ -1177,6 +1184,13 @@ class LiteXSoC(SoC): contents = mem, ) + # LiteDRAM BIST + if with_bist: + self.submodules.sdram_generator = LiteDRAMBISTGenerator(self.sdram.crossbar.get_port()) + self.add_csr("sdram_generator") + self.submodules.sdram_checker = LiteDRAMBISTChecker(self.sdram.crossbar.get_port()) + self.add_csr("sdram_checker") + if not with_soc_interconnect: return # Compute/Check SDRAM size @@ -1288,6 +1302,7 @@ class LiteXSoC(SoC): port = port, base_address = self.bus.regions["main_ram"].origin) + # Add Ethernet --------------------------------------------------------------------------------- def add_ethernet(self, name="ethmac", phy=None): # Imports @@ -1424,3 +1439,56 @@ class LiteXSoC(SoC): dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus dma_bus.add_master("sdmem2block", master=bus) self.csr.add("sdmem2block", use_loc_if_exists=True) + + # Add SATA ------------------------------------------------------------------------------------- + def add_sata(self, name="sata", phy=None, mode="read+write"): + # Imports + from litesata.core import LiteSATACore + from litesata.frontend.arbitration import LiteSATACrossbar + from litesata.frontend.dma import LiteSATASector2MemDMA, LiteSATAMem2SectorDMA + + # Checks + assert mode in ["read", "write", "read+write"] + sata_clk_freqs = { + "gen1": 75e6, + "gen2": 150e6, + "gen3": 300e6, + } + sata_clk_freq = sata_clk_freqs[phy.gen] + assert self.clk_freq >= sata_clk_freq/2 # FIXME: /2 for 16-bit data-width, add support for 32-bit. + + # Core + self.submodules.sata_core = LiteSATACore(phy) + + # Crossbar + self.submodules.sata_crossbar = LiteSATACrossbar(self.sata_core) + + # Sector2Mem DMA + if "read" in mode: + bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width) + self.submodules.sata_sector2mem = LiteSATASector2MemDMA( + port = self.sata_crossbar.get_port(), + bus = bus, + endianness = self.cpu.endianness) + dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus + dma_bus.add_master("sata_sector2mem", master=bus) + self.csr.add("sata_sector2mem", use_loc_if_exists=True) + + # Mem2Sector DMA + if "write" in mode: + bus = wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width) + self.submodules.sata_mem2sector = LiteSATAMem2SectorDMA( + bus = bus, + port = self.sata_crossbar.get_port(), + endianness = self.cpu.endianness) + dma_bus = self.bus if not hasattr(self, "dma_bus") else self.dma_bus + dma_bus.add_master("sata_mem2sector", master=bus) + self.csr.add("sata_mem2sector", use_loc_if_exists=True) + + # Timing constraints + self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_tx.clk, 1e9/sata_clk_freq) + self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_rx.clk, 1e9/sata_clk_freq) + self.platform.add_false_path_constraints( + self.crg.cd_sys.clk, + self.sata_phy.crg.cd_sata_tx.clk, + self.sata_phy.crg.cd_sata_rx.clk) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 95d268720..d96fb5347 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -7,6 +7,7 @@ # This file is Copyright (c) 2019 Gabriel L. Somlo # This file is Copyright (c) 2019 Ilia Sergachev # This file is Copyright (c) 2018 Jean-François Nguyen +# This file is Copyright (c) 2020 Raptor Engineering, LLC # This file is Copyright (c) 2015 Robert Jordens # This file is Copyright (c) 2018 Sean Cross # This file is Copyright (c) 2018 Stafford Horne @@ -84,6 +85,8 @@ class SoCCore(LiteXSoC): csr_address_width = 14, csr_paging = 0x800, csr_ordering = "big", + # Interrupt parameters + irq_n_irqs = 32, # Identifier parameters ident = "", ident_version = False, @@ -114,7 +117,7 @@ class SoCCore(LiteXSoC): csr_ordering = csr_ordering, csr_reserved_csrs = self.csr_map, - irq_n_irqs = 32, + irq_n_irqs = irq_n_irqs, irq_reserved_irqs = {}, ) diff --git a/litex/soc/interconnect/csr.py b/litex/soc/interconnect/csr.py index 7320311a5..89f38d144 100644 --- a/litex/soc/interconnect/csr.py +++ b/litex/soc/interconnect/csr.py @@ -190,7 +190,7 @@ class CSRField(Signal): """ def __init__(self, name, size=1, offset=None, reset=0, description=None, pulse=False, access=None, values=None): - assert access is None or (access in CSRAccess.values()) + assert access is None or (access in CSRAccess.__members__.values()) self.name = name self.size = size self.offset = offset diff --git a/litex/soc/interconnect/stream.py b/litex/soc/interconnect/stream.py index 377c177f8..1621d69cb 100644 --- a/litex/soc/interconnect/stream.py +++ b/litex/soc/interconnect/stream.py @@ -70,7 +70,7 @@ class Endpoint(Record): Record.__init__(self, self.description.get_full_layout(), name, **kwargs) set_reset_less(self.first) set_reset_less(self.last) - set_reset_less(self.payload) + #set_reset_less(self.payload) # FIXME: cause issues with LiteSATA, understand why and uncomment. set_reset_less(self.param) def __getattr__(self, name): @@ -568,6 +568,30 @@ class Gearbox(Module): else: self.comb += source.data.eq(o_data[::-1]) +# Shifter ------------------------------------------------------------------------------------------ + +class Shifter(PipelinedActor): + def __init__(self, dw, shift=None): + self.shift = Signal(max=dw) if shift is None else shift + self.sink = sink = Endpoint([("data", dw)]) + self.source = source = Endpoint([("data", dw)]) + PipelinedActor.__init__(self, latency=2) + + # # # + + # Accumulate current/last sink.data. + r = Signal(2*dw) + self.sync += If(self.pipe_ce, + r[:dw].eq(r[dw:]), + r[dw:].eq(sink.data) + ) + + # Select output data based on shift. + cases = {} + for i in range(dw): + cases[i] = self.source.data.eq(r[i:dw+i]) + self.comb += Case(self.shift, cases) + # Monitor ------------------------------------------------------------------------------------------ class Monitor(Module, AutoCSR): diff --git a/litex/soc/software/bios/Makefile b/litex/soc/software/bios/Makefile index 67eea2159..4ad3692e4 100755 --- a/litex/soc/software/bios/Makefile +++ b/litex/soc/software/bios/Makefile @@ -18,6 +18,7 @@ OBJECTS = isr.o \ cmd_litedram.o \ cmd_liteeth.o \ cmd_litesdcard.o \ + cmd_litesata.o \ main.o ifneq "$(or $(TERM_NO_COMPLETE),$(TERM_MINI))" "" @@ -60,7 +61,9 @@ bios.elf: $(BIOS_DIRECTORY)/linker.ld $(OBJECTS) ../liblitedram/liblitedram.a \ ../libliteeth/libliteeth.a \ ../liblitespi/liblitespi.a \ - ../liblitesdcard/liblitesdcard.a + ../libfatfs/libfatfs.a \ + ../liblitesdcard/liblitesdcard.a \ + ../liblitesata/liblitesata.a $(LD) $(LDFLAGS) -T $(BIOS_DIRECTORY)/linker.ld -N -o $@ \ ../libbase/crt0.o \ $(OBJECTS) \ @@ -69,8 +72,10 @@ bios.elf: $(BIOS_DIRECTORY)/linker.ld $(OBJECTS) -L../liblitedram \ -L../libliteeth \ -L../liblitespi \ + -L../libfatfs \ -L../liblitesdcard \ - -llitedram -lliteeth -llitespi -llitesdcard -lbase-nofloat -lcompiler_rt + -L../liblitesata \ + -llitedram -lliteeth -llitespi -lfatfs -llitesdcard -llitesata -lbase-nofloat -lcompiler_rt ifneq ($(OS),Windows_NT) chmod -x $@ diff --git a/litex/soc/software/bios/boot.c b/litex/soc/software/bios/boot.c index 7a8198b2c..51e482169 100644 --- a/litex/soc/software/bios/boot.c +++ b/litex/soc/software/bios/boot.c @@ -33,7 +33,8 @@ #include #include -#include +#include +#include /*-----------------------------------------------------------------------*/ /* Helpers */ @@ -674,3 +675,173 @@ void sdcardboot(void) printf("SDCard boot failed.\n"); } #endif + +/*-----------------------------------------------------------------------*/ +/* SATA Boot */ +/*-----------------------------------------------------------------------*/ + +#if defined(CSR_SATA_SECTOR2MEM_BASE) + +static int copy_file_from_sata_to_ram(const char * filename, unsigned long ram_address) +{ + FRESULT fr; + FATFS fs; + FIL file; + uint32_t br; + uint32_t offset; + uint32_t length; + + fr = f_mount(&fs, "", 1); + if (fr != FR_OK) + return 0; + fr = f_open(&file, filename, FA_READ); + if (fr != FR_OK) { + printf("%s file not found.\n", filename); + f_mount(0, "", 0); + return 0; + } + + length = f_size(&file); + printf("Copying %s to 0x%08x (%d bytes)...\n", filename, ram_address, length); + init_progression_bar(length); + offset = 0; + for (;;) { + fr = f_read(&file, (void*) ram_address + offset, 0x8000, &br); + if (fr != FR_OK) { + printf("file read error.\n"); + f_close(&file); + f_mount(0, "", 0); + return 0; + } + if (br == 0) + break; + offset += br; + show_progress(offset); + } + show_progress(offset); + printf("\n"); + + f_close(&file); + f_mount(0, "", 0); + + return 1; +} + +static void sataboot_from_json(const char * filename) +{ + FRESULT fr; + FATFS fs; + FIL file; + + uint8_t i; + uint8_t count; + uint32_t length; + uint32_t result; + + /* FIXME: modify/increase if too limiting */ + char json_buffer[1024]; + char json_name[32]; + char json_value[32]; + + unsigned long boot_r1 = 0; + unsigned long boot_r2 = 0; + unsigned long boot_r3 = 0; + unsigned long boot_addr = 0; + + uint8_t image_found = 0; + uint8_t boot_addr_found = 0; + + /* Read JSON file */ + fr = f_mount(&fs, "", 1); + if (fr != FR_OK) + return; + fr = f_open(&file, filename, FA_READ); + if (fr != FR_OK) { + printf("%s file not found.\n", filename); + f_mount(0, "", 0); + return; + } + + fr = f_read(&file, json_buffer, sizeof(json_buffer), &length); + + /* Close JSON file */ + f_close(&file); + f_mount(0, "", 0); + + /* Parse JSON file */ + jsmntok_t t[32]; + jsmn_parser p; + jsmn_init(&p); + count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t)); + for (i=0; i"); + return; + } + + value = strtoul(params[0], &c, 0); + if (*c != 0) { + printf("Incorrect value"); + return; + } + + printf("Settings Leds to 0x%x", value); + leds_out_write(value); +} + +define_command(leds, leds_handler, "Set Leds value", SYSTEM_CMDS); +#endif /** * Command "trace" diff --git a/litex/soc/software/bios/cmds/cmd_boot.c b/litex/soc/software/bios/cmds/cmd_boot.c index e945be742..e46e8e97b 100644 --- a/litex/soc/software/bios/cmds/cmd_boot.c +++ b/litex/soc/software/bios/cmds/cmd_boot.c @@ -72,3 +72,13 @@ define_command(netboot, netboot, "Boot via Ethernet (TFTP)", BOOT_CMDS); define_command(sdcardboot, sdcardboot, "Boot from SDCard", BOOT_CMDS); #endif +/** + * Command "sataboot" + * + * Boot software from SATA + * + */ +#if defined(CSR_SATA_SECTOR2MEM_BASE) +define_command(sataboot, sataboot, "Boot from SATA", BOOT_CMDS); +#endif + diff --git a/litex/soc/software/bios/cmds/cmd_litedram.c b/litex/soc/software/bios/cmds/cmd_litedram.c index 234814e4d..71a931321 100644 --- a/litex/soc/software/bios/cmds/cmd_litedram.c +++ b/litex/soc/software/bios/cmds/cmd_litedram.c @@ -11,6 +11,7 @@ #include #include +#include #include "../command.h" #include "../helpers.h" @@ -55,6 +56,37 @@ static void sdram_test_handler(int nb_params, char **params) define_command(sdram_test, sdram_test_handler, "Test SDRAM", LITEDRAM_CMDS); #endif +/** + * Command "sdram_bist" + * + * Run SDRAM Build-In Self-Test + * + */ +#if defined(CSR_SDRAM_GENERATOR_BASE) && defined(CSR_SDRAM_CHECKER_BASE) +static void sdram_bist_handler(int nb_params, char **params) +{ + char *c; + int burst_length; + int random; + if (nb_params < 2) { + printf("sdram_bist "); + return; + } + burst_length = strtoul(params[0], &c, 0); + if (*c != 0) { + printf("Incorrect burst_length"); + return; + } + random = strtoul(params[1], &c, 0); + if (*c != 0) { + printf("Incorrect random"); + return; + } + sdram_bist(burst_length, random); +} +define_command(sdram_bist, sdram_bist_handler, "Run SDRAM Build-In Self-Test", LITEDRAM_CMDS); +#endif + #ifdef CSR_DDRPHY_RDPHASE_ADDR /** * Command "sdram_force_rdphase" diff --git a/litex/soc/software/bios/cmds/cmd_litesata.c b/litex/soc/software/bios/cmds/cmd_litesata.c new file mode 100644 index 000000000..fcb96b9e9 --- /dev/null +++ b/litex/soc/software/bios/cmds/cmd_litesata.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: BSD-Source-Code + +#include +#include + +#include + +#include + +#include "../command.h" +#include "../helpers.h" + +/** + * Command "sata_init" + * + * Initialize SATA + * + */ +#ifdef CSR_SATA_PHY_BASE +static void sata_init_handler(int nb_params, char **params) +{ + printf("Initialize SATA... "); + if (sata_init()) + printf("Successful.\n"); + else + printf("Failed.\n"); +} + +define_command(sata_init, sata_init_handler, "Initialize SATA", LITESATA_CMDS); +#endif + +/** + * Command "sata_read" + * + * Perform SATA sector read + * + */ +#ifdef CSR_SATA_SECTOR2MEM_BASE +static void sata_read_handler(int nb_params, char **params) +{ + unsigned int sector; + char *c; + uint8_t buf[512]; + + if (nb_params < 1) { + printf("sata_read "); + return; + } + + sector = strtoul(params[0], &c, 0); + if (*c != 0) { + printf("Incorrect sector number"); + return; + } + + sata_read(sector, 1, buf); + dump_bytes((uint32_t *)buf, 512, (unsigned long) buf); +} + +define_command(sata_read, sata_read_handler, "Read SATA sector", LITESATA_CMDS); +#endif + +/** + * Command "sata_write" + * + * Perform SATA sector write + * + */ +#ifdef CSR_SATA_MEM2SECTOR_BASE +static void sata_write_handler(int nb_params, char **params) +{ + int i; + uint8_t buf[512]; + unsigned int sector; + char *c; + + if (nb_params < 2) { + printf("sata_write "); + return; + } + + sector = strtoul(params[0], &c, 0); + if (*c != 0) { + printf("Incorrect sector number"); + return; + } + + c = params[1]; + if (params[1] != NULL) { + for(i=0; i<512; i++) { + buf[i] = *c; + if(*(++c) == 0) { + c = params[1]; + } + } + } + dump_bytes((uint32_t *)buf, 512, (unsigned long) buf); + sata_write(sector, 1, buf); +} + +define_command(sata_write, sata_write_handler, "Write SATA sector", LITESATA_CMDS); +#endif diff --git a/litex/soc/software/bios/command.h b/litex/soc/software/bios/command.h index 319119b5b..5124d24c8 100644 --- a/litex/soc/software/bios/command.h +++ b/litex/soc/software/bios/command.h @@ -17,7 +17,8 @@ #define LITEDRAM_CMDS 5 #define LITEETH_CMDS 6 #define LITESDCARD_CMDS 7 -#define NB_OF_GROUPS 8 +#define LITESATA_CMDS 8 +#define NB_OF_GROUPS 9 typedef void (*cmd_handler)(int nb_params, char **params); diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c index dafa2c184..e7bf91afc 100644 --- a/litex/soc/software/bios/isr.c +++ b/litex/soc/software/bios/isr.c @@ -1,5 +1,6 @@ // This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq // This file is Copyright (c) 2019 Gabriel L. Somlo +// This file is Copyright (c) 2020 Raptor Engineering, LLC // License: BSD @@ -9,7 +10,12 @@ #include #include +#if defined(__microwatt__) +void isr(uint64_t vec); +void isr_dec(void); +#else void isr(void); +#endif #ifdef CONFIG_CPU_HAS_INTERRUPT @@ -96,6 +102,47 @@ void isr(void) #endif } } +#elif defined(__microwatt__) + +void isr(uint64_t vec) +{ + if (vec == 0x900) + return isr_dec(); + + if (vec == 0x500) { + // Read interrupt source + uint32_t xirr = xics_icp_readw(PPC_XICS_XIRR); + uint32_t irq_source = xirr & 0x00ffffff; + + __attribute__((unused)) unsigned int irqs; + + // Handle IPI interrupts separately + if (irq_source == 2) { + // IPI interrupt + xics_icp_writeb(PPC_XICS_MFRR, 0xff); + } + else { + // External interrupt + irqs = irq_pending() & irq_getmask(); + +#ifndef UART_POLLING + if(irqs & (1 << UART_INTERRUPT)) + uart_isr(); +#endif + } + + // Clear interrupt + xics_icp_writew(PPC_XICS_XIRR, xirr); + + return; + } +} + +void isr_dec(void) +{ + // For now, just set DEC back to a large enough value to slow the flood of DEC-initiated timer interrupts + mtdec(0x000000000ffffff); +} #else void isr(void) @@ -113,6 +160,10 @@ void isr(void) #else +#if defined(__microwatt__) +void isr(uint64_t vec){}; +#else void isr(void){}; +#endif #endif diff --git a/litex/soc/software/bios/main.c b/litex/soc/software/bios/main.c index d19951bde..f1e3dd271 100644 --- a/litex/soc/software/bios/main.c +++ b/litex/soc/software/bios/main.c @@ -45,6 +45,7 @@ #include #include +#include static void boot_sequence(void) { @@ -58,6 +59,9 @@ static void boot_sequence(void) #if defined(CSR_SPISDCARD_BASE) || defined(CSR_SDCORE_BASE) sdcardboot(); #endif +#if defined(CSR_SATA_SECTOR2MEM_BASE) + sataboot(); +#endif #ifdef CSR_ETHMAC_BASE #ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR eth_mode(); diff --git a/litex/soc/software/include/base/stdint.h b/litex/soc/software/include/base/stdint.h index 594d9034f..bff5d0983 100644 --- a/litex/soc/software/include/base/stdint.h +++ b/litex/soc/software/include/base/stdint.h @@ -26,7 +26,22 @@ typedef signed int int_least32_t; typedef unsigned int uint_least32_t; typedef signed long long int_least64_t; typedef unsigned long long uint_least64_t; - + +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647 +#define INT64_MAX 9223372036854775807LL + +#define INT8_MIN -128 +#define INT16_MIN -32768 +#define INT32_MIN (-INT32_MAX - 1) +#define INT64_MIN (-INT64_MAX - 1LL) + +#define UINT8_MAX 255 +#define UINT16_MAX 65535 +#define UINT32_MAX 4294967295U +#define UINT64_MAX 18446744073709551615ULL + #define __int_c_join(a, b) a ## b #define __int_c(v, suffix) __int_c_join(v, suffix) #define __uint_c(v, suffix) __int_c_join(v##U, suffix) diff --git a/litex/soc/software/libfatfs/Makefile b/litex/soc/software/libfatfs/Makefile new file mode 100644 index 000000000..93f14fbe6 --- /dev/null +++ b/litex/soc/software/libfatfs/Makefile @@ -0,0 +1,23 @@ +include ../include/generated/variables.mak +include $(SOC_DIRECTORY)/software/common.mak + +OBJECTS=ffunicode.o ff.o + +all: libfatfs.a + +libfatfs.a: $(OBJECTS) + $(AR) crs libfatfs.a $(OBJECTS) + +# pull in dependency info for *existing* .o files +-include $(OBJECTS:.o=.d) + +%.o: $(LIBFATFS_DIRECTORY)/%.c + $(compile) + +%.o: %.S + $(assemble) + +.PHONY: all clean + +clean: + $(RM) $(OBJECTS) libfatfs.a .*~ *~ diff --git a/litex/soc/software/liblitesdcard/fat/diskio.h b/litex/soc/software/libfatfs/diskio.h similarity index 100% rename from litex/soc/software/liblitesdcard/fat/diskio.h rename to litex/soc/software/libfatfs/diskio.h diff --git a/litex/soc/software/liblitesdcard/fat/ff.c b/litex/soc/software/libfatfs/ff.c similarity index 100% rename from litex/soc/software/liblitesdcard/fat/ff.c rename to litex/soc/software/libfatfs/ff.c diff --git a/litex/soc/software/liblitesdcard/fat/ff.h b/litex/soc/software/libfatfs/ff.h similarity index 100% rename from litex/soc/software/liblitesdcard/fat/ff.h rename to litex/soc/software/libfatfs/ff.h diff --git a/litex/soc/software/liblitesdcard/fat/ffconf.h b/litex/soc/software/libfatfs/ffconf.h similarity index 100% rename from litex/soc/software/liblitesdcard/fat/ffconf.h rename to litex/soc/software/libfatfs/ffconf.h diff --git a/litex/soc/software/liblitesdcard/fat/ffunicode.c b/litex/soc/software/libfatfs/ffunicode.c similarity index 100% rename from litex/soc/software/liblitesdcard/fat/ffunicode.c rename to litex/soc/software/libfatfs/ffunicode.c diff --git a/litex/soc/software/liblitedram/Makefile b/litex/soc/software/liblitedram/Makefile index c541e3f65..56f4a5445 100644 --- a/litex/soc/software/liblitedram/Makefile +++ b/litex/soc/software/liblitedram/Makefile @@ -1,7 +1,7 @@ include ../include/generated/variables.mak include $(SOC_DIRECTORY)/software/common.mak -OBJECTS = sdram.o +OBJECTS = sdram.o bist.o all: liblitedram.a diff --git a/litex/soc/software/liblitedram/bist.c b/litex/soc/software/liblitedram/bist.c new file mode 100644 index 000000000..65e2dcf4c --- /dev/null +++ b/litex/soc/software/liblitedram/bist.c @@ -0,0 +1,181 @@ +// This file is Copyright (c) 2018-2020 Florent Kermarrec +// License: BSD + +#include +#if defined(CSR_SDRAM_GENERATOR_BASE) && defined(CSR_SDRAM_CHECKER_BASE) +#include +#include +#include +#include +#include +#include + +#include "bist.h" + +#define SDRAM_TEST_BASE 0x00000000 +#define SDRAM_TEST_DATA_BYTES (CSR_SDRAM_DFII_PI0_RDDATA_SIZE*4) + +uint32_t wr_ticks; +uint32_t wr_length; +uint32_t rd_ticks; +uint32_t rd_length; +uint32_t rd_errors; + +__attribute__((unused)) static void cdelay(int i) +{ +#ifndef CONFIG_SIM_DISABLE_DELAYS + while(i > 0) { + __asm__ volatile(CONFIG_CPU_NOP); + i--; + } +#endif +} + +static uint32_t pseudo_random_bases[128] = { + 0x000e4018,0x0003338d,0x00233429,0x001f589d, + 0x001c922b,0x0011dc60,0x000d1e8f,0x000b20cf, + 0x00360188,0x00041174,0x0003d065,0x000bfe34, + 0x001bfc54,0x001dc7d5,0x00036587,0x00197383, + 0x0035b2d3,0x001c3765,0x00397fae,0x00239bc0, + 0x0000d4f3,0x00146fb7,0x0036183a,0x002b8d54, + 0x00239149,0x0013e6c0,0x001b8f66,0x002b1587, + 0x000d1539,0x000bdf18,0x0030a175,0x000c6133, + 0x002df309,0x002c06bd,0x0021dbd1,0x00058fc8, + 0x003ace6f,0x000ffa4d,0x003073d0,0x000a161f, + 0x002586dd,0x002e4a0e,0x00189ce9,0x0008e72e, + 0x0005dd92,0x001d2bc5,0x00250aaa,0x000a369f, + 0x001dcc17,0x000ced9d,0x0030a7f9,0x002394a3, + 0x003a0959,0x002eb2d2,0x0014d1d9,0x002f6217, + 0x002d7982,0x001ad120,0x00222c54,0x000923b7, + 0x0015e7df,0x001f55f6,0x0014ea5f,0x003b2b57, + 0x003091fe,0x00228da6,0x001c1c59,0x00298218, + 0x000728f9,0x001d5172,0x00041bdc,0x002860c3, + 0x0033595e,0x00224555,0x000878de,0x001b017c, + 0x0028475d,0x001b3758,0x003fe6cf,0x0032a410, + 0x003abba8,0x0012499d,0x0021e797,0x0011df68, + 0x001f917d,0x0021a184,0x0036d6eb,0x00331f8e, + 0x002e55e6,0x001c12b3,0x0011b4da,0x003f2b86, + 0x000ba2eb,0x000607e8,0x000e08fb,0x0013904d, + 0x00147a4a,0x00360956,0x000821ad,0x0031400e, + 0x0030d8e6,0x003be90f,0x00202e56,0x00017835, + 0x000ea9a1,0x00222753,0x002b8ade,0x000e4757, + 0x00259169,0x0037a663,0x00143e83,0x003a139e, + 0x00006a57,0x0021b6bb,0x0016de10,0x000d9ede, + 0x00263370,0x001975eb,0x0013903c,0x002fdc68, + 0x0014ada3,0x000012bd,0x00297df2,0x003e8aa1, + 0x00027e36,0x000e51ae,0x002e7627,0x00275c9f, +}; + +void sdram_bist_loop(uint32_t loop, uint32_t burst_length, uint32_t random) { + int i; + uint32_t base; + uint32_t length; + length = burst_length*SDRAM_TEST_DATA_BYTES; + + rd_errors = 0; + for(i=0; i<128; i++) { + if (random) + base = SDRAM_TEST_BASE + pseudo_random_bases[(i+loop)%128]*SDRAM_TEST_DATA_BYTES; + else + base = SDRAM_TEST_BASE + ((i+loop)%128)*SDRAM_TEST_DATA_BYTES; + if (i == 0) { + /* Prepare first write */ + sdram_generator_reset_write(1); + sdram_generator_reset_write(0); + sdram_generator_random_write(1); /* Random data */ + sdram_generator_base_write(base); + sdram_generator_end_write(base + length); + sdram_generator_length_write(length); + cdelay(100); + } + /* Start write */ + sdram_generator_start_write(1); + /* Prepare next read */ + sdram_checker_reset_write(1); + sdram_checker_reset_write(0); + sdram_checker_random_write(1); /* Random data */ + sdram_checker_base_write(base); + sdram_checker_end_write(base + length); + sdram_checker_length_write(length); + cdelay(100); + /* Wait write */ + while(sdram_generator_done_read() == 0); + /* Get write results */ + wr_length += length; + wr_ticks += sdram_generator_ticks_read(); + /* Start read */ + sdram_checker_start_write(1); + if (i != 127) { + if (random) + base = SDRAM_TEST_BASE + pseudo_random_bases[(i+1+loop)%128]*SDRAM_TEST_DATA_BYTES; + else + base = SDRAM_TEST_BASE + ((i+1+loop)%128)*SDRAM_TEST_DATA_BYTES; + /* Prepare next write */ + sdram_generator_reset_write(1); + sdram_generator_reset_write(0); + sdram_generator_random_write(1); /* Random data */ + sdram_generator_base_write(base); + sdram_generator_end_write(base + length); + sdram_generator_length_write(length); + cdelay(100); + } + /* Wait read */ + while(sdram_checker_done_read() == 0); + /* Get read results */ + rd_ticks += sdram_checker_ticks_read(); + rd_errors += sdram_checker_errors_read(); + rd_length += length; + } +} + +static uint32_t compute_speed_mibs(uint32_t length, uint32_t ticks) { + uint32_t speed; + //printf("(%lu, %lu)", length, ticks); + speed = length*(CONFIG_CLOCK_FREQUENCY/(1024*1024))/ticks; + return speed; +} + +void sdram_bist(uint32_t burst_length, uint32_t random) +{ + uint32_t i; + uint32_t total_length; + uint32_t total_errors; + + printf("Starting SDRAM BIST with burst_length=%d and random=%d\n", burst_length, random); + + i = 0; + total_length = 0; + total_errors = 0; + for(;;) { + /* Exit on key pressed */ + if (readchar_nonblock()) + break; + + /* Bist loop */ + sdram_bist_loop(i, burst_length, random); + + /* Results */ + if (i%1000 == 0) { + printf("WR-SPEED(MiB/s) RD-SPEED(MiB/s) TESTED(MiB) ERRORS\n"); + } + if (i%100 == 100-1) { + printf("%15u %15u %12u %12u\n", + compute_speed_mibs(wr_length, wr_ticks), + compute_speed_mibs(rd_length, rd_ticks), + total_length/(1024*1024), + total_errors); + total_length += wr_length; + total_errors += rd_errors; + + /* Clear length/ticks/errors */ + wr_length = 0; + wr_ticks = 0; + rd_length = 0; + rd_ticks = 0; + rd_errors = 0; + } + i++; + } +} + +#endif diff --git a/litex/soc/software/liblitedram/bist.h b/litex/soc/software/liblitedram/bist.h new file mode 100644 index 000000000..2f0ea1a37 --- /dev/null +++ b/litex/soc/software/liblitedram/bist.h @@ -0,0 +1,10 @@ +// This file is Copyright (c) 2018-2020 Florent Kermarrec +// License: BSD + +#ifndef __SDRAM_BIST_H +#define __SDRAM_BIST_H + +void sdram_bist_loop(uint32_t loop, uint32_t burst_length, uint32_t random); +void sdram_bist(uint32_t burst_length, uint32_t random); + +#endif /* __SDRAM_BIST_H */ diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index c8cfbb869..093bb7dc5 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -283,15 +283,15 @@ void sdram_write_leveling_rst_cmd_delay(int show) { } void sdram_write_leveling_force_cmd_delay(int taps, int show) { + int i; _sdram_write_leveling_cmd_scan = 0; _sdram_write_leveling_cmd_delay = taps; if (show) printf("Forcing Cmd delay to %d taps\n", taps); ddrphy_cdly_rst_write(1); - while (taps > 0) { + for (i=0; i +// License: BSD + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "sata.h" + +/*-----------------------------------------------------------------------*/ +/* SATA user functions */ +/*-----------------------------------------------------------------------*/ + +#ifdef CSR_SATA_PHY_BASE + +int sata_init(void) { + uint16_t timeout; + + + for (timeout=10; timeout>0; timeout--) { + /* Check SATA PHY status */ + if (sata_phy_status_read() & 0x1) + return 1; + + /* Reset SATA PHY */ + sata_phy_enable_write(0); + sata_phy_enable_write(1); + + /* Wait for 10ms */ + busy_wait(10); + } + + return 0; +} + +#endif + +#ifdef CSR_SATA_SECTOR2MEM_BASE + +void sata_read(uint32_t sector, uint32_t count, uint8_t* buf) +{ + uint32_t i; + + /* Write sectors */ + for (i=0; i +// License: BSD + +#ifndef __SATA_H +#define __SATA_H + +#include + +/*-----------------------------------------------------------------------*/ +/* SATA user functions */ +/*-----------------------------------------------------------------------*/ + +#ifdef CSR_SATA_PHY_BASE + +int sata_init(void); + +#endif + +#ifdef CSR_SATA_SECTOR2MEM_BASE + +void sata_read(uint32_t sector, uint32_t count, uint8_t* buf); + +#endif + +#ifdef CSR_SATA_MEM2SECTOR_BASE + +void sata_write(uint32_t sector, uint32_t count, uint8_t* buf); + +#endif + +#endif /* __SATA_H */ diff --git a/litex/soc/software/liblitesdcard/Makefile b/litex/soc/software/liblitesdcard/Makefile index 8c409f40f..48b39261e 100644 --- a/litex/soc/software/liblitesdcard/Makefile +++ b/litex/soc/software/liblitesdcard/Makefile @@ -1,7 +1,7 @@ include ../include/generated/variables.mak include $(SOC_DIRECTORY)/software/common.mak -OBJECTS=ffunicode.o ff.o sdcard.o spisdcard.o +OBJECTS=sdcard.o spisdcard.o all: liblitesdcard.a @@ -14,9 +14,6 @@ liblitesdcard.a: $(OBJECTS) %.o: $(LIBLITESDCARD_DIRECTORY)/%.c $(compile) -%.o: $(LIBLITESDCARD_DIRECTORY)/fat/%.c - $(compile) - %.o: %.S $(assemble) diff --git a/litex/soc/software/liblitesdcard/sdcard.c b/litex/soc/software/liblitesdcard/sdcard.c index 6951bab3b..009552250 100644 --- a/litex/soc/software/liblitesdcard/sdcard.c +++ b/litex/soc/software/liblitesdcard/sdcard.c @@ -13,8 +13,8 @@ #include #include -#include "fat/ff.h" -#include "fat/diskio.h" +#include +#include #include "sdcard.h" #ifdef CSR_SDCORE_BASE diff --git a/litex/soc/software/liblitesdcard/spisdcard.c b/litex/soc/software/liblitesdcard/spisdcard.c index eeb8dee5d..c95df8532 100644 --- a/litex/soc/software/liblitesdcard/spisdcard.c +++ b/litex/soc/software/liblitesdcard/spisdcard.c @@ -12,8 +12,8 @@ #include #include -#include "fat/ff.h" -#include "fat/diskio.h" +#include +#include #include "spisdcard.h" #ifdef CSR_SPISDCARD_BASE diff --git a/litex/tools/litex_client.py b/litex/tools/litex_client.py index 32b55407f..1437865c6 100644 --- a/litex/tools/litex_client.py +++ b/litex/tools/litex_client.py @@ -1,11 +1,14 @@ +#!/usr/bin/env python3 + # # This file is part of LiteX. # -# Copyright (c) 2015-2019 Florent Kermarrec +# Copyright (c) 2015-2020 Florent Kermarrec # Copyright (c) 2016 Tim 'mithro' Ansell # SPDX-License-Identifier: BSD-2-Clause import os +import argparse import socket from litex.tools.remote.etherbone import EtherbonePacket, EtherboneRecord @@ -13,6 +16,7 @@ from litex.tools.remote.etherbone import EtherboneReads, EtherboneWrites from litex.tools.remote.etherbone import EtherboneIPC from litex.tools.remote.csr_builder import CSRBuilder +# Remote Client ------------------------------------------------------------------------------------ class RemoteClient(EtherboneIPC, CSRBuilder): def __init__(self, host="localhost", port=1234, base_address=0, csr_csv=None, csr_data_width=None, debug=False): @@ -79,3 +83,50 @@ class RemoteClient(EtherboneIPC, CSRBuilder): if self.debug: for i, data in enumerate(datas): print("write {:08x} @ {:08x}".format(data, self.base_address + addr + 4*i)) + +# Utils -------------------------------------------------------------------------------------------- + +def dump_identifier(port): + wb = RemoteClient(port=port) + wb.open() + + fpga_identifier = "" + + for i in range(256): + c = chr(wb.read(wb.bases.identifier_mem + 4*i) & 0xff) + fpga_identifier += c + if c == "\0": + break + + print(fpga_identifier) + + wb.close() + +def dump_registers(port): + wb = RemoteClient(port=port) + wb.open() + + for name, register in wb.regs.__dict__.items(): + print("0x{:08x} : 0x{:08x} {}".format(register.addr, register.read(), name)) + + wb.close() + +# Run ---------------------------------------------------------------------------------------------- + +def main(): + parser = argparse.ArgumentParser(description="LiteX Client utility") + parser.add_argument("--port", default="1234", help="Host bind port") + parser.add_argument("--ident", action="store_true", help="Dump FPGA identifier") + parser.add_argument("--regs", action="store_true", help="Dump FPGA registers") + args = parser.parse_args() + + port = int(args.port, 0) + + if args.ident: + dump_identifier(port=port) + + if args.regs: + dump_registers(port=port) + +if __name__ == "__main__": + main() diff --git a/litex/tools/litex_sim.py b/litex/tools/litex_sim.py index 8585b1ed0..ca126931d 100755 --- a/litex/tools/litex_sim.py +++ b/litex/tools/litex_sim.py @@ -281,6 +281,7 @@ class SimSoC(SoCCore): # Analyzer --------------------------------------------------------------------------------- if with_analyzer: analyzer_signals = [ + # IBus (could also just added as self.cpu.ibus) self.cpu.ibus.stb, self.cpu.ibus.cyc, self.cpu.ibus.adr, @@ -289,6 +290,15 @@ class SimSoC(SoCCore): self.cpu.ibus.sel, self.cpu.ibus.dat_w, self.cpu.ibus.dat_r, + # DBus (could also just added as self.cpu.dbus) + self.cpu.dbus.stb, + self.cpu.dbus.cyc, + self.cpu.dbus.adr, + self.cpu.dbus.we, + self.cpu.dbus.ack, + self.cpu.dbus.sel, + self.cpu.dbus.dat_w, + self.cpu.dbus.dat_r, ] self.submodules.analyzer = LiteScopeAnalyzer(analyzer_signals, depth = 512, diff --git a/setup.py b/setup.py index efefa52a4..8414e8051 100755 --- a/setup.py +++ b/setup.py @@ -38,6 +38,7 @@ setup( # full names "litex_term=litex.tools.litex_term:main", "litex_server=litex.tools.litex_server:main", + "litex_cli=litex.tools.litex_client:main", "litex_jtag_uart=litex.tools.litex_jtag_uart:main", "litex_crossover_uart=litex.tools.litex_crossover_uart:main", "litex_sim=litex.tools.litex_sim:main", diff --git a/test/test_code_8b10b.py b/test/test_code_8b10b.py index a4c2fe121..3c217ea6b 100644 --- a/test/test_code_8b10b.py +++ b/test/test_code_8b10b.py @@ -337,3 +337,58 @@ class TestCode8B10B(unittest.TestCase): def test_roundtrip(self): self.assertEqual(self.input_sequence, decode_sequence(self.output_sequence)) + + def test_stream(self): + def data_generator(dut, endpoint, datas, commas, rand=True): + prng = random.Random(42) + for i, (data, comma) in enumerate(zip(datas, commas)): + if rand: + while prng.randrange(4): + yield + yield endpoint.valid.eq(1) + yield endpoint.d.eq(data) + yield endpoint.k.eq(comma) + yield + while (yield endpoint.ready) == 0: + yield + yield endpoint.valid.eq(0) + + def data_checker(dut, endpoint, datas, commas, rand=True): + prng = random.Random(42) + dut.errors = 0 + for i, (data_ref, comma_ref) in enumerate(zip(datas, commas)): + yield endpoint.ready.eq(1) + yield + while (yield endpoint.valid) == 0: + yield + data = (yield endpoint.d) + comma = (yield endpoint.k) + #print("data: 0x{:08x} vs 0x{:08x}".format(data, data_ref)) + #print("comma: 0b{:04b} vs 0b{:04b}".format(comma, comma_ref)) + if data != data_ref: + dut.errors += 1 + if comma != comma_ref: + dut.errors += 1 + yield endpoint.ready.eq(0) + if rand: + while prng.randrange(4): + yield + + + class DUT(Module): + def __init__(self): + self.submodules.encoder = code_8b10b.StreamEncoder(nwords=4) + self.submodules.decoder = code_8b10b.StreamDecoder(nwords=4) + self.comb += self.encoder.source.connect(self.decoder.sink) + + + prng = random.Random(42) + dut = DUT() + datas = [prng.randrange(2**32) for i in range(128)] + commas = [0 for i in range(128)] + generators = [ + data_generator(dut, dut.encoder.sink, datas, commas), + data_checker(dut, dut.decoder.source, datas, commas) + ] + run_simulation(dut, generators) + self.assertEqual(dut.errors, 0)