Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for Tang nano 9k board #208

Closed
wants to merge 17 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions amaranth_boards/tang_nano_9k.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import os
import subprocess

from amaranth.build import *
from amaranth.vendor.gowin import *

try:
from .resources import *
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only be from .resources import *; for testing you can install amaranth-boards in "editable mode".

except:
from resources import *


__all__ = ["TangNano9kPlatform"]


class TangNano9kPlatform(GowinPlatform):
part = "GW1NR-LV9QN88PC6/I5"
family = "GW1NR-9C"
default_clk = "clk27" # or "OSC" to use on-chip oscillator
osc_frequency = 2500000 # Hz
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our general policy here is that if default_clk points to a pin (like here), then osc_frequency is unspecified. However if the external clock is missing or unusable (like on the original Tang Nano), then default_clk would be OSC and the frequency would be specified by the designer, with some reasonable default (like 24 MHz).

board = "tangnano9k"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our convention is to inline the board field you have here into toolchain_program.

resources = [
Resource("clk27", 0, Pins("52", dir="i"),
Clock(27e6), Attrs(IO_TYPE="LVCMOS33")),

*ButtonResources(pins="3 4",
attrs=Attrs(IO_TYPE="LVCMOS33")),

# Pins 5 to 8 are JTAG (TMS, TCK, TDI, TDO) from BL702

# Pin 12 is VCC03_1V8
# LEDs are connected to 1V8, pins pull cathode to GND, when low
*LEDResources(pins="10 11 13 14 15 16", invert=True,
attrs=Attrs(IO_TYPE="LVCMOS33")),

# Connects to BL702 UART1
UARTResource(0, rx="18", tx="17",
attrs=Attrs(PULL_MODE="UP", IO_TYPE="LVCMOS33")),

*SPIFlashResources(0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this also a PSRAM on the 9k? If so, it should be:

Suggested change
*SPIFlashResources(0,
*SPIFlashResources("psram", 0,

cs_n="60", clk="59", copi="61", cipo="62",
attrs=Attrs(IO_TYPE="LVCMOS33")),

*SDCardResources(0,
clk="36", cmd="37", dat0="39", dat3="38", wp_n="-",
attrs=Attrs(IO_TYPE="LVCMOS33")),

Resource("backlight_pwm", 0, Pins("86", dir="o"),
Copy link
Member

@whitequark whitequark Aug 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Resource("backlight_pwm", 0, Pins("86", dir="o"),
Resource("lcd_backlight", 0, Pins("86", dir="o"),

Attrs(IO_TYPE="LVCMOS33")),

# Missing 1.14 inch LCD
# LCD_RESET RESET PIN47_EN
# PIN49_RS RS
# PIN77_MO SDA
# PIN76_MCLK SCL
# PIN48_CS CS

Resource("hdmi", 0, # FPGA_HDMI
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you like to add HDMIResource?

Subsignal("clk",
DiffPairs(p="69", n="68", dir="o")),
Subsignal("d",
DiffPairs(p="71 73 75",
n="70 72 74", dir="o")),
Attrs(IO_TYPE="LVCMOS33")),

]
connectors = [
Connector("gpio", 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The silk that is printed on the board refers to FPGA pin numbers, is that correct?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I remember from trying: they can be put in the .cst files as pin number.
This is also what the pinout diagram from Sipeed suggests:
img

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By silk I mean the other side (not visible on the diagram).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they just number their pins and also put these numbers on the silkscreen next to the GPIO headers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we probably don't need this connector since it's much easier and less error prone to use actual pin numbers.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mpv-shot0001
They match with the grey "IC Pin number" from the pinout diagram.

# I/O banks: 1: 3.3V, 2: 3.3V, 3: 1.8V

# Some pins are not available, when certain boot modes are enabled:
# MSPI: MI, MO, MCS_N, MCLK, FASTRD_N
# SSPI: SI, SO, SSPI_CS_N
# See 'overrides' below in toolchain_prepare()

# When viewed from top (FPGA-side up), from USB to HDMI
# top row
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # gpio Pin
# 5V # voltage
# 1 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 # bank
" 63 86 85 84 83 82 81 80 79 77 76 75 74 73 72 71 70 -"
# 19 20 21 22 # gpio Pin
# GND 3V3 # voltage
# 1 1 2 2 # bank
" 48 49 31 32 - -"
# bottom row
# 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 # gpio Pin
# 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 # bank
" 38 37 36 39 25 26 27 28 29 30 33 34 40 35 41 42 51 53"
# 43 44 45 46 47 48 # gpio Pin
# x x x # special, don't use
# 1 1 1 1 1 1 # bank
" 54 55 56 57 68 69"
),
# TODO: Convert to Resource
Connector("rgb_lcd", 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can take this for inspiration.

# LEDK LEDA GND +3V3 GND GND GND
" - - - - - - -"
# HDMI_D2 ... GND ... HDMI_CK_N
# R3 R4 R5 R6 R7 G2 G3 G4
" 75 74 73 72 71 - - 70 69 68"
# RGB_G5 ... GND ... RGB_B7 GND
# G5 G6 G7 B3 B4 B7 B6 B7
" 57 56 55 - - - 54 53 51 42 41 -"
# RGB_CK +3V3 RGB_HS RGB_VS RGB_DE NC GND
# CLK DISP HSYNC VSYNC DEN
" 35 - 40 34 33 - -"
# RGB_INIT ...GND GND
# XR YD XL YU
" 32 31 63 50 - -"
)
]

def toolchain_prepare(self, fragment, name, **kwargs):
overrides = {
"add_options":
"set_option -use_mspi_as_gpio 1 -use_sspi_as_gpio 1",
"gowin_pack_opts":
"--sspi_as_gpio --mspi_as_gpio"
}
return super().toolchain_prepare(fragment, name, **overrides, **kwargs)

def toolchain_program(self, products, name):
with products.extract("{}.fs".format(name)) as bitstream_filename:
subprocess.check_call(["openFPGALoader",
"-b", self.board,
bitstream_filename])


if __name__ == "__main__":
try:
from .test.blinky import *
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise here.

except:
from test.blinky import *
TangNano9kPlatform().build(Blinky(), do_program=True)
Loading