|
| 1 | +import os |
| 2 | +import subprocess |
| 3 | +import shutil |
| 4 | + |
| 5 | +from nmigen.build import * |
| 6 | +from nmigen.vendor.lattice_ecp5 import * |
| 7 | +from .resources import * |
| 8 | + |
| 9 | + |
| 10 | +__all__ = ["ButterStickR1_0Platform"] |
| 11 | + |
| 12 | + |
| 13 | +class ButterStickR1_0Platform(LatticeECP5Platform): |
| 14 | + device = "LFE5U-25F" |
| 15 | + package = "BG381" |
| 16 | + speed = "8" |
| 17 | + default_clk = "clk" |
| 18 | + resources = [ |
| 19 | + Resource("clk", 0, Pins("B12", dir="i"), |
| 20 | + Clock(30e6), Attrs(IO_TYPE="LVCMOS33")), |
| 21 | + |
| 22 | + # Used to reload FPGA configuration. |
| 23 | + Resource("program", 0, PinsN("R3", dir="o"), Attrs(IO_TYPE="LVCMOS33")), |
| 24 | + |
| 25 | + # LED Anodes |
| 26 | + *LEDResources(pins="C13 D12 U2 T3 D13 E13", attrs=Attrs(IO_STANDARD="LVCMOS33")), |
| 27 | + # LED Cathodes. Use invert to default as on to allow LEDs to be used in white with single bit IO |
| 28 | + RGBLEDResource(0, r="T1", g="R1", b="U1", invert=True, attrs=Attrs(IO_TYPE="LVCMOS33")), |
| 29 | + |
| 30 | + *ButtonResources( |
| 31 | + pins={0: "U16", 1: "T17" }, invert=True, |
| 32 | + attrs=Attrs(IO_TYPE="SSTL135_I")), |
| 33 | + |
| 34 | + *SPIFlashResources(0, |
| 35 | + cs_n="R2", clk="U3", cipo="W2", copi="V2", wp_n="Y2", hold_n="W1", |
| 36 | + attrs=Attrs(IO_TYPE="LVCMOS33"), |
| 37 | + ), |
| 38 | + |
| 39 | + Resource("ddr3", 0, |
| 40 | + Subsignal("rst", PinsN("E17", dir="o")), |
| 41 | + Subsignal("clk", DiffPairs("C20 J19", "D19 K19", dir="o"), Attrs(IO_TYPE="SSTL135D_I")), |
| 42 | + Subsignal("clk_en", Pins("F18 J18", dir="o")), |
| 43 | + Subsignal("cs", PinsN("J20 J16", dir="o")), |
| 44 | + Subsignal("we", PinsN("G19", dir="o")), |
| 45 | + Subsignal("ras", PinsN("K18", dir="o")), |
| 46 | + Subsignal("cas", PinsN("J17", dir="o")), |
| 47 | + Subsignal("a", Pins("G16 E19 E20 F16 F19 E16 F17 L20 M20 E18 G18 D18 H18 C18 D17 G20 ", dir="o")), |
| 48 | + Subsignal("ba", Pins("H16 F20 H20", dir="o")), |
| 49 | + Subsignal("dqs", DiffPairs("T19 N16", "R18 M18", dir="io"), |
| 50 | + Attrs(IO_TYPE="SSTL135D_I", TERMINATION="OFF", |
| 51 | + DIFFRESISTOR="100")), |
| 52 | + Subsignal("dq", Pins("U19 T18 U18 R20 P18 P19 P20 N20 L19 L17 L16 R16 N18 R17 N17 P17", |
| 53 | + dir="io"), Attrs(TERMINATION="75")), |
| 54 | + Subsignal("dm", Pins("U20 L18", dir="o")), |
| 55 | + Subsignal("odt", Pins("K20 H17", dir="o")), |
| 56 | + Attrs(IO_TYPE="SSTL135_I", SLEWRATE="FAST") |
| 57 | + ), |
| 58 | + |
| 59 | + Resource("eth_rgmii", 0, |
| 60 | + Subsignal("rst", PinsN("B20", dir="o")), |
| 61 | + Subsignal("mdc", Pins("A19", dir="o")), |
| 62 | + Subsignal("mdio", Pins("D16", dir="io")), |
| 63 | + Subsignal("tx_clk", Pins("E15", dir="o")), |
| 64 | + Subsignal("tx_ctl", Pins("D15", dir="o")), |
| 65 | + Subsignal("tx_data", Pins("C15 B16 A18 B19", dir="o")), |
| 66 | + Subsignal("rx_clk", Pins("D11", dir="i")), |
| 67 | + Subsignal("rx_ctl", Pins("B18", dir="i")), |
| 68 | + Subsignal("rx_data", Pins("A16 C17 B17 A17", dir="i")), |
| 69 | + Attrs(IO_TYPE="LVCMOS25") |
| 70 | + ), |
| 71 | + ULPIResource(0, data="B9 C6 A7 E9 A8 D9 C10 C7", |
| 72 | + rst="C9", clk="B6", dir="A6", stp="C8", nxt="B8", |
| 73 | + clk_dir="i", rst_invert=True, attrs=Attrs(IOSTANDARD="LVCMOS18")), |
| 74 | + ] |
| 75 | + connectors = [ |
| 76 | + Connector("syzygy", 0, { |
| 77 | + "S0_D0_P": "G2", |
| 78 | + "S1_D1_P": "J3", |
| 79 | + "S2_D0_N": "F1", |
| 80 | + "S3_D1_N": "K3", |
| 81 | + "S4_D2_P": "J4", |
| 82 | + "S5_D3_P": "K2", |
| 83 | + "S6_D2_N": "J5", |
| 84 | + "S7_D3_N": "J1", |
| 85 | + "S8_D4_P": "N2", |
| 86 | + "S9_D5_P": "L3", |
| 87 | + "S10_D4_N": "M1", |
| 88 | + "S11_D5_N": "L2", |
| 89 | + "S12_D6_P": "N3", |
| 90 | + "S13_D7_P": "N4", |
| 91 | + "S14_D6_N": "M3", |
| 92 | + "S15_D7_N": "P5", |
| 93 | + "S16": "H1", |
| 94 | + "S17": "K5", |
| 95 | + "S18": "K4", |
| 96 | + "S19": "K1", |
| 97 | + "S20": "L4", |
| 98 | + "S21": "L1", |
| 99 | + "S22": "L5", |
| 100 | + "S23": "M4", |
| 101 | + "S24": "N1", |
| 102 | + "S25": "N5", |
| 103 | + "S26": "P3", |
| 104 | + "S28": "P4", |
| 105 | + "C2P_CLK_N": "P2", |
| 106 | + "C2P_CLK_P": "P1", |
| 107 | + "P2C_CLK_N": "G1", |
| 108 | + "P2C_CLK_P": "H2", |
| 109 | + }), |
| 110 | + Connector("syzygy", 1, { |
| 111 | + "S0_D0_P": "E4", |
| 112 | + "S1_D1_P": "A4", |
| 113 | + "S2_D0_N": "D5", |
| 114 | + "S3_D1_N": "A5", |
| 115 | + "S4_D2_P": "C4", |
| 116 | + "S5_D3_P": "B2", |
| 117 | + "S6_D2_N": "B4", |
| 118 | + "S7_D3_N": "C2", |
| 119 | + "S8_D4_P": "A2", |
| 120 | + "S9_D5_P": "C1", |
| 121 | + "S10_D5_N": "D1", |
| 122 | + "S11_D4_N": "B1", |
| 123 | + "S12_D6_P": "F4", |
| 124 | + "S13_D7_P": "D2", |
| 125 | + "S14_D6_N": "E3", |
| 126 | + "S15_D7_N": "E1", |
| 127 | + "S16": "B5", |
| 128 | + "S17": "E5", |
| 129 | + "S18": "F5", |
| 130 | + "S19": "C5", |
| 131 | + "S20": "B3", |
| 132 | + "S21": "A3", |
| 133 | + "S22": "D3", |
| 134 | + "S23": "C3", |
| 135 | + "S24": "H5", |
| 136 | + "S25": "G5", |
| 137 | + "S26": "H3", |
| 138 | + "S27": "H4", |
| 139 | + "C2P_CLK_N": "F3", |
| 140 | + "C2P_CLK_P": "G3", |
| 141 | + "P2C_CLK_N": "E2", |
| 142 | + "P2C_CLK_P": "F2", |
| 143 | + }), |
| 144 | + Connector("syzygy", 2, { |
| 145 | + "S0": "C11", |
| 146 | + "S1": "B11", |
| 147 | + "S2": "D6", |
| 148 | + "S3": "D7", |
| 149 | + "S4": "E6", |
| 150 | + "S5": "E7", |
| 151 | + "S6": "D8", |
| 152 | + "S7": "E8", |
| 153 | + "S8": "E10", |
| 154 | + "S9": "D10", |
| 155 | + "RX0_N": "Y6", |
| 156 | + "RX0_P": "Y5", |
| 157 | + "RX1_N": "Y8", |
| 158 | + "RX1_P": "Y7", |
| 159 | + "RX2_N": "Y15", |
| 160 | + "RX2_P": "Y14", |
| 161 | + "RX3_N": "Y17", |
| 162 | + "RX3_P": "Y16", |
| 163 | + "TX0_N": "W5", |
| 164 | + "TX0_P": "W4", |
| 165 | + "TX1_N": "W9", |
| 166 | + "TX1_P": "W8", |
| 167 | + "TX2_N": "W14", |
| 168 | + "TX2_P": "W13", |
| 169 | + "TX3_N": "W18", |
| 170 | + "TX3_P": "W17", |
| 171 | + "C2P_CLK_N": "B10", |
| 172 | + "C2P_CLK_P": "A9", |
| 173 | + "P2C_CLK_N": "A11", |
| 174 | + "P2C_CLK_P": "A10", |
| 175 | + "REFCLK_N": "Y12", |
| 176 | + "REFCLK_P": "Y11", |
| 177 | + }), |
| 178 | + ] |
| 179 | + |
| 180 | + @property |
| 181 | + def required_tools(self): |
| 182 | + return super().required_tools + [ |
| 183 | + "dfu-suffix" |
| 184 | + ] |
| 185 | + |
| 186 | + @property |
| 187 | + def command_templates(self): |
| 188 | + return super().command_templates + [ |
| 189 | + r""" |
| 190 | + {{invoke_tool("dfu-suffix")}} |
| 191 | + -v 1209 -p 5af0 -a {{name}}.bit |
| 192 | + """ |
| 193 | + ] |
| 194 | + |
| 195 | + def toolchain_prepare(self, fragment, name, **kwargs): |
| 196 | + overrides = dict(ecppack_opts="--compress --freq 38.8") |
| 197 | + overrides.update(kwargs) |
| 198 | + return super().toolchain_prepare(fragment, name, **overrides) |
| 199 | + |
| 200 | + def toolchain_program(self, products, name): |
| 201 | + dfu_util = os.environ.get("DFU_UTIL", "dfu-util") |
| 202 | + with products.extract("{}.bit".format(name)) as bitstream_filename: |
| 203 | + subprocess.check_call([dfu_util, "-D", bitstream_filename]) |
| 204 | + |
| 205 | + |
| 206 | +if __name__ == "__main__": |
| 207 | + from .test.blinky import * |
| 208 | + ButterStickR1_0Platform().build(Blinky(), do_program=True) |
0 commit comments