Merge remote-tracking branch 'origin/master'

This commit is contained in:
bunnie 2020-11-08 14:35:41 +08:00
commit b59711f89f
85 changed files with 2529 additions and 578 deletions

View File

@ -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
--------------------------

View File

@ -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")),

View File

@ -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")),

View File

@ -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",

View File

@ -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")),

View File

@ -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 ---------------------------------------------------------------------------------------

View File

@ -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 ---------------------------------------------------------------------------------------

View File

@ -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")),

View File

@ -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")),

View File

@ -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")),

View File

@ -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()),

View File

@ -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"),

View File

@ -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 ---------------------------------------------------------------------------------------

View File

@ -1,99 +0,0 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2016-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2019 Pierre-Olivier Vauboin <po@lambdaconcept>
# 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]")

View File

@ -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 ---------------------------------------------------------------------------------------

View File

@ -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):

View File

@ -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")),

View File

@ -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)

View File

@ -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":

View File

@ -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 ------------------------------------------------------------------------------------------

View File

@ -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 --------------------------------------------------------------------------------------------

View File

@ -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)

View File

@ -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 ------------------------------------------------------------------------------------------

View File

@ -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":

View File

@ -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 ------------------------------------------------------------------------------------------

View File

@ -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 ------------------------------------------------------------------------------------------

View File

@ -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()

View File

@ -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,

View File

@ -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 {}

View File

@ -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 ---------------------------------------------------------------------------

View File

@ -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)

View File

@ -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()

View File

@ -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 -------------------------------------------------------------------------

View File

@ -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}

View File

@ -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 --------------------------------------------------------------------------

View File

@ -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"):

View File

@ -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 --------------------------------------------------------------------------------

View File

@ -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 -------------------------------------------------------------------------------

View File

@ -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 ----------------------------------------------------------------------------

View File

@ -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

View File

@ -2,7 +2,7 @@
# This file is part of LiteX.
#
# Copyright (c) 2016-2017 Sebastien Bourdeauducq <sb@m-labs.hk>
# Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2019-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# 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)
]

View File

@ -3,6 +3,7 @@
#
# Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2019 Benjamin Herrenschmidt <benh@ozlabs.org>
# Copyright (c) 2020 Raptor Engineering <sales@raptorengineering.com>
# 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 = [

View File

@ -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

View File

@ -1,4 +1,161 @@
// (c) 2020 Raptor Engineering, LLC <sales@raptorengineering.com>
#ifndef __IRQ_H
#define __IRQ_H
#ifdef __cplusplus
extern "C" {
#endif
#include <system.h>
#include <generated/csr.h>
#include <generated/soc.h>
#include <generated/mem.h>
// 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 */

View File

@ -2,6 +2,7 @@
-- This file is part of LiteX.
--
-- Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
-- Copyright (c) 2020 Raptor Engineering, LLC <sales@raptorengineering.com>
-- 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,

View File

@ -0,0 +1,182 @@
-- This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
-- Copyright (c) 2020 Raptor Engineering, LLC <sales@raptorengineering.com>
-- 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;

View File

@ -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"),

View File

@ -1,7 +1,7 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2019-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# 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.")

View File

@ -37,7 +37,9 @@ soc_software_packages = [
"liblitedram",
"libliteeth",
"liblitespi",
"libfatfs",
"liblitesdcard",
"liblitesata",
"bios"
]

View File

@ -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(' <vendorExtensions>')
svd.append(' <memoryRegions>')
for name, region in soc.mem_regions.items():
for region_name, region in soc.mem_regions.items():
svd.append(' <memoryRegion>')
svd.append(' <name>{}</name>'.format(name.upper()))
svd.append(' <name>{}</name>'.format(region_name.upper()))
svd.append(' <baseAddress>0x{:08X}</baseAddress>'.format(region.origin))
svd.append(' <size>0x{:08X}</size>'.format(region.size))
svd.append(' </memoryRegion>')

View File

@ -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)

View File

@ -7,6 +7,7 @@
# This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
# This file is Copyright (c) 2019 Ilia Sergachev <ilia.sergachev@protonmail.ch>
# This file is Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
# This file is Copyright (c) 2020 Raptor Engineering, LLC <sales@raptorengineering.com>
# This file is Copyright (c) 2015 Robert Jordens <jordens@gmail.com>
# This file is Copyright (c) 2018 Sean Cross <sean@xobs.io>
# This file is Copyright (c) 2018 Stafford Horne <shorne@gmail.com>
@ -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 = {},
)

View File

@ -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

View File

@ -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):

View File

@ -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 $@

View File

@ -33,7 +33,8 @@
#include <liblitesdcard/spisdcard.h>
#include <liblitesdcard/sdcard.h>
#include <liblitesdcard/fat/ff.h>
#include <liblitesata/sata.h>
#include <libfatfs/ff.h>
/*-----------------------------------------------------------------------*/
/* 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<count-1; i++) {
memset(json_name, 0, sizeof(json_name));
memset(json_value, 0, sizeof(json_value));
/* Elements are JSON strings with 1 children */
if ((t[i].type == JSMN_STRING) && (t[i].size == 1)) {
/* Get Element's filename */
memcpy(json_name, json_buffer + t[i].start, t[i].end - t[i].start);
/* Get Element's address */
memcpy(json_value, json_buffer + t[i+1].start, t[i+1].end - t[i+1].start);
/* Skip bootargs (optional) */
if (strncmp(json_name, "bootargs", 8) == 0) {
continue;
}
/* Get boot addr (optional) */
else if (strncmp(json_name, "addr", 4) == 0) {
boot_addr = strtoul(json_value, NULL, 0);
boot_addr_found = 1;
}
/* Get boot r1 (optional) */
else if (strncmp(json_name, "r1", 2) == 0) {
memcpy(json_name, json_buffer + t[i].start, t[i].end - t[i].start);
boot_r1 = strtoul(json_value, NULL, 0);
}
/* Get boot r2 (optional) */
else if (strncmp(json_name, "r2", 2) == 0) {
boot_r2 = strtoul(json_value, NULL, 0);
}
/* Get boot r3 (optional) */
else if (strncmp(json_name, "r3", 2) == 0) {
boot_r3 = strtoul(json_value, NULL, 0);
/* Copy Image from SDCard to address */
} else {
result = copy_file_from_sata_to_ram(json_name, strtoul(json_value, NULL, 0));
if (result == 0)
return;
image_found = 1;
if (boot_addr_found == 0) /* Boot to last Image address if no bootargs.addr specified */
boot_addr = strtoul(json_value, NULL, 0);
}
}
}
/* Boot */
if (image_found)
boot(boot_r1, boot_r2, boot_r3, boot_addr);
}
static void sataboot_from_bin(const char * filename)
{
uint32_t result;
result = copy_file_from_sata_to_ram(filename, MAIN_RAM_BASE);
if (result == 0)
return;
boot(0, 0, 0, MAIN_RAM_BASE);
}
void sataboot(void)
{
printf("Booting from SATA...\n");
/* Boot from boot.json */
printf("Booting from boot.json...\n");
sataboot_from_json("boot.json");
/* Boot from boot.bin */
printf("Booting from boot.bin...\n");
sataboot_from_bin("boot.bin");
/* Boot failed if we are here... */
printf("SATA boot failed.\n");
}
#endif

View File

@ -6,5 +6,6 @@ void netboot(void);
void flashboot(void);
void romboot(void);
void sdcardboot(void);
void sataboot(void);
#endif /* __BOOT_H */

View File

@ -131,6 +131,35 @@ define_command(flush_cpu_dcache, flush_cpu_dcache, "Flush CPU data cache", SYSTE
define_command(flush_l2_cache, flush_l2_cache, "Flush L2 cache", SYSTEM_CMDS);
#endif
/**
* Command "leds"
*
* Set Leds value
*
*/
#ifdef CSR_LEDS_BASE
static void leds_handler(int nb_params, char **params)
{
char *c;
unsigned int value;
if (nb_params < 1) {
printf("leds <value>");
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"

View File

@ -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

View File

@ -11,6 +11,7 @@
#include <i2c.h>
#include <liblitedram/sdram.h>
#include <liblitedram/bist.h>
#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 <burst_length> <random>");
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"

View File

@ -0,0 +1,102 @@
// SPDX-License-Identifier: BSD-Source-Code
#include <stdio.h>
#include <stdlib.h>
#include <generated/csr.h>
#include <liblitesata/sata.h>
#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 <sector>");
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 <sector> <str>");
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

View File

@ -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);

View File

@ -1,5 +1,6 @@
// This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
// This file is Copyright (c) 2019 Gabriel L. Somlo <gsomlo@gmail.com>
// This file is Copyright (c) 2020 Raptor Engineering, LLC <sales@raptorengineering.com>
// License: BSD
@ -9,7 +10,12 @@
#include <uart.h>
#include <stdio.h>
#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

View File

@ -45,6 +45,7 @@
#include <liblitespi/spiflash.h>
#include <liblitesdcard/sdcard.h>
#include <liblitesata/sata.h>
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();

View File

@ -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)

View File

@ -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 .*~ *~

View File

@ -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

View File

@ -0,0 +1,181 @@
// This file is Copyright (c) 2018-2020 Florent Kermarrec <florent@enjoy-digital.fr>
// License: BSD
#include <generated/csr.h>
#if defined(CSR_SDRAM_GENERATOR_BASE) && defined(CSR_SDRAM_CHECKER_BASE)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <uart.h>
#include <time.h>
#include <console.h>
#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

View File

@ -0,0 +1,10 @@
// This file is Copyright (c) 2018-2020 Florent Kermarrec <florent@enjoy-digital.fr>
// 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 */

View File

@ -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<taps; i++) {
ddrphy_cdly_inc_write(1);
cdelay(1000);
taps--;
cdelay(100);
}
}
@ -331,8 +331,10 @@ static void sdram_write_leveling_rst_delay(int module) {
ddrphy_wdly_dq_rst_write(1);
ddrphy_wdly_dqs_rst_write(1);
#ifdef SDRAM_PHY_WRITE_LEVELING_REINIT
for(i=0; i<ddrphy_half_sys8x_taps_read(); i++)
for(i=0; i<ddrphy_half_sys8x_taps_read(); i++) {
ddrphy_wdly_dqs_inc_write(1);
cdelay(100);
}
#endif
/* unsel module */
@ -370,7 +372,6 @@ static int sdram_write_leveling_scan(int *delays, int loops, int show)
err_ddrphy_wdly = SDRAM_PHY_DELAYS - ddrphy_half_sys8x_taps_read();
sdram_write_leveling_on();
cdelay(100);
for(i=0;i<SDRAM_PHY_MODULES;i++) {
if (show)
printf(" m%d: |", i);
@ -388,7 +389,7 @@ static int sdram_write_leveling_scan(int *delays, int loops, int show)
#endif
for (k=0; k<loops; k++) {
ddrphy_wlevel_strobe_write(1);
cdelay(10);
cdelay(100);
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[0], buf, DFII_PIX_DATA_BYTES);
if (buf[SDRAM_PHY_MODULES-1-i] != 0)
one_count++;
@ -402,7 +403,7 @@ static int sdram_write_leveling_scan(int *delays, int loops, int show)
if (show_iter)
printf("%d", taps_scan[j]);
sdram_write_leveling_inc_delay(i);
cdelay(10);
cdelay(100);
}
if (show)
printf("|");
@ -482,7 +483,7 @@ static void sdram_write_leveling_find_cmd_delay(unsigned int *best_error, int *b
/* increment cdly to current value */
while (cdly_actual < cdly) {
ddrphy_cdly_inc_write(1);
cdelay(10);
cdelay(100);
cdly_actual++;
}
@ -562,7 +563,7 @@ int sdram_write_leveling(void)
ddrphy_cdly_rst_write(1);
for (int i = 0; i < best_cdly; ++i) {
ddrphy_cdly_inc_write(1);
cdelay(10);
cdelay(100);
}
}
@ -793,8 +794,10 @@ static void sdram_read_leveling_module(int module)
/* Set delay to the middle */
sdram_read_leveling_rst_delay(module);
for(i=0;i<(delay_min+delay_max)/2;i++)
for(i=0;i<(delay_min+delay_max)/2;i++) {
sdram_read_leveling_inc_delay(module);
cdelay(100);
}
}
#endif /* CSR_DDRPHY_BASE */

View File

@ -0,0 +1,23 @@
include ../include/generated/variables.mak
include $(SOC_DIRECTORY)/software/common.mak
OBJECTS=sata.o
all: liblitesata.a
liblitesata.a: $(OBJECTS)
$(AR) crs liblitesata.a $(OBJECTS)
# pull in dependency info for *existing* .o files
-include $(OBJECTS:.o=.d)
%.o: $(LIBLITESATA_DIRECTORY)/%.c
$(compile)
%.o: %.S
$(assemble)
.PHONY: all clean
clean:
$(RM) $(OBJECTS) liblitesata.a .*~ *~

View File

@ -0,0 +1,123 @@
// This file is Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
// License: BSD
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <generated/csr.h>
#include <generated/mem.h>
#include <system.h>
#include <libfatfs/ff.h>
#include <libfatfs/diskio.h>
#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<count; i++) {
uint8_t done = 0;
while (done == 0) {
sata_sector2mem_base_write((uint64_t) buf);
sata_sector2mem_sector_write(sector + i);
sata_sector2mem_start_write(1);
while ((sata_sector2mem_done_read() & 0x1) == 0);
done = ((sata_sector2mem_error_read() & 0x1) == 0);
busy_wait_us(10);
}
buf += 512;
}
#ifndef CONFIG_CPU_HAS_DMA_BUS
/* Flush CPU caches */
flush_cpu_dcache();
#ifdef CONFIG_L2_SIZE
flush_l2_cache();
#endif
#endif
}
#endif
#ifdef CSR_SATA_MEM2SECTOR_BASE
void sata_write(uint32_t sector, uint32_t count, uint8_t* buf)
{
uint32_t i;
/* Write sectors */
for (i=0; i<count; i++) {
uint8_t done = 0;
while (done == 0) {
sata_mem2sector_base_write((uint64_t) buf);
sata_mem2sector_sector_write(sector + i);
sata_mem2sector_start_write(1);
while ((sata_sector2mem_done_read() & 0x1) == 0);
done = ((sata_sector2mem_error_read() & 0x1) == 0);
busy_wait_us(10);
}
buf += 512;
}
}
#endif
/*-----------------------------------------------------------------------*/
/* SATA FatFs disk functions */
/*-----------------------------------------------------------------------*/
#ifdef CSR_SATA_SECTOR2MEM_BASE
static DSTATUS satastatus = STA_NOINIT;
DSTATUS disk_status(uint8_t drv) {
if (drv) return STA_NOINIT;
return satastatus;
}
DSTATUS disk_initialize(uint8_t drv) {
if (drv) return STA_NOINIT;
if (satastatus)
satastatus = sata_init() ? 0 : STA_NOINIT;
return satastatus;
}
DRESULT disk_read(uint8_t drv, uint8_t *buf, uint32_t sector, uint32_t count) {
sata_read(sector, count, buf);
return RES_OK;
}
#endif /* CSR_SATA_SECTOR2MEM_BASE */

View File

@ -0,0 +1,31 @@
// This file is Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
// License: BSD
#ifndef __SATA_H
#define __SATA_H
#include <generated/csr.h>
/*-----------------------------------------------------------------------*/
/* 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 */

View File

@ -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)

View File

@ -13,8 +13,8 @@
#include <generated/mem.h>
#include <system.h>
#include "fat/ff.h"
#include "fat/diskio.h"
#include <libfatfs/ff.h>
#include <libfatfs/diskio.h>
#include "sdcard.h"
#ifdef CSR_SDCORE_BASE

View File

@ -12,8 +12,8 @@
#include <generated/mem.h>
#include <system.h>
#include "fat/ff.h"
#include "fat/diskio.h"
#include <libfatfs/ff.h>
#include <libfatfs/diskio.h>
#include "spisdcard.h"
#ifdef CSR_SPISDCARD_BASE

View File

@ -1,11 +1,14 @@
#!/usr/bin/env python3
#
# This file is part of LiteX.
#
# Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2016 Tim 'mithro' Ansell <mithro@mithis.com>
# 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()

View File

@ -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,

View File

@ -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",

View File

@ -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)