mipsgreen的个人空间 http://blog.eetop.cn/806108 [收藏] [复制] [RSS]

日志

WIN10/WSL系统下使用nMigen实现FPGA开发

热度 10已有 3986 次阅读2020-10-1 23:21 |系统分类:芯片设计| nMigen, FPGA, Python, DE0_nano, Altera, FPGA, Altera

WIN10/WSL系统下使用nMigen实现FPGA开发

软件:
  • Windows10 安装 WSL - ubuntu (18.04 or 20.02)
  • WSL: Python3 (>3.5)
  • WSL: yosys (https://githbub.com/yosyshq/yosys)
  • WSL: nMigen (https://github.com/nmigen/nmigen)
  • WSL: nmigen-soc/nmigen-boards/nmigen-stdio (https://github.com/nmigen/...)
  • Win10: Quartus primer Pro/Std 18.1 (+Cyclone IV support, + licensed)
硬件:
  • DE0_Nano (based on Cyclone IV)

nmigen可以实现基于python的FPGA数字系统设计/验证, 但需要借助专用的工具完成Fhdl到硬件的实现。
nmigen支持基于quartus作为后端实现的工具,我们可以利用WSL平台执行windows程序的功能,
将windows下的quartus与WSL下的nmigen配合,完成FPGA系统的设计,验证,综合,映射,以及最终部署

到DE0_NANO开发板上运行。

nmigen支持quartus工具链,在WSL系统下,我们需要首先设置下运行环境,以便nmigen能够正确的找到WIN10
下的工具。需要设置的环境变量如下,可添加到.bashrc中:
QTS_HOME=/mnt/d/intelFPGA/18.1/quartus
PATH=$PATH:$QTS_HOME/bin64
export PATH
LD_LIBRARY_PATH=$QTS_HOME/linux64
export LD_LIBRARY_PATH
export QUARTUS_PGM="quartus_pgm.exe"
export QUARTUS_MAP="quartus_map.exe"
export QUARTUS_FIT="quartus_fit.exe"
export QUARTUS_CPF="quartus_cpf.exe"
export QUARTUS_STA="quartus_sta.exe"
export QUARTUS_ASM="quartus_asm.exe"
alias quartus_pgm="quartus_pgm.exe"
alias quartus_map="quartus_map.exe"
alias quartus_fit="quartus_fit.exe"
alias quartus_cpf="quartus_cpf.exe"

alias quartus_sta="quartus_sta.exe"alias quartus_asm="quartus_asm.exe"

安装nmigen-soc/nmigen-stdio/nmigen-boards

(注:用下面的方法不用单独安装nmigen, pip会自动根据依赖关系安装nmigen)
sudo pip3 install git+https://github.com/nmigen/nmigen-soc
sudo pip3 install git+https://github.com/nmigen/nmigen-stdio

sudo pip3 install git+https://github.com/nmigen/nmigen-boards

nmigen默认使用yosys作为综合工具,而不是直接使用quartus,所以需要安装yosys,

安装yosys可以直接从github源下载安装, 也可以直接安装编译好的源:
#ubuntu 18.04/20.02可以直接apt安装:

sudo apt install yosys

nmigen-boards里面没有支持DE0_Nano, 我们可以通过复制一个相似的平台创建一个, 比如de0_cv.py

创建一个项目目录, 复制/nmigen-boards/下的de0_cv.py,改名de0_nano.py
按照DE0_Nano的资源,更新如下:
#!/usr/bin/env python3
# DE0_Nano support file
import os
import subprocess
from nmigen.build import *
from nmigen.vendor.intel import *
from nmigen_boards.resources import *
__all__ = ["DE0NanoPlatform"]
class DE0NanoPlatform(IntelPlatform):
   device      = "EP4CE22" #
   package     = "F17"    # FBGA-484
   speed       = "C6"
   default_clk = "clk50"
   resources   = [
       Resource("clk50", 0, Pins("R8", dir="i"),
                Clock(50e6), Attrs(io_standard="3.3-V LVTTL")),
       Resource("epcs", 0,
           Subsignal("data0", Pins("H2", dir="i")),
           Subsignal("dclk", Pins("H1", dir="o")),
           Subsignal("ncs0", Pins("D2", dir="o")),
           Subsignal("asd0", Pins("C1", dir="o")),
           Attrs(io_standard="3.3-V LVTTL")
       ),
       Resource("i2c", 0,
           Subsignal("sclk", Pins("F2", dir="o")),
           Subsignal("sdat", Pins("F1", dir="io")),
           Attrs(io_standard="3.3-V LVTTL")
       ),
       Resource("g_sensor", 0,
           Subsignal("cs_n", Pins("G5", dir="o")),
           Subsignal("int", Pins("M2", dir="i")),
           Attrs(io_standard="3.3-V LVTTL")
       ),
       Resource("adc", 0,
           Subsignal("cs_n", Pins("A10", dir="o")),
           Subsignal("saddr", Pins("B10", dir="i")),
           Subsignal("sclk", Pins("B14", dir="o")),
           Subsignal("sdat", Pins("A9", dir="o")),
           Attrs(io_standard="3.3-V LVTTL")
       ),
       *LEDResources(
           pins="A15 A13 B13 A11 D1 F3 B1 L3", invert=True,
           attrs=Attrs(io_standard="3.3-V LVTTL")),
       *ButtonResources(
           pins="J15 E1", invert=True,
           attrs=Attrs(io_standard="3.3-V LVTTL")),
       *SwitchResources(
           pins="M1 T8 B9 M15",
           attrs=Attrs(io_standard="3.3-V LVTTL")),
       UARTResource(0, # uart
           rx="C3", tx="D3",
           attrs=Attrs(io_standard="3.3-V LVTTL")),
        *SDCardResources(0,
           clk="H11", cmd="B11", dat0="K9", dat1="D12", dat2="E12", dat3="C11", wp="W20",
           attrs=Attrs(io_standard="3.3-V LVTTL")),
        SDRAMResource(0,
           clk="R4", cke="L7", cs="P6", we="C2", ras="L2", cas="L1",
           ba="M7 M6", a="P2 N5 N6 M8 P8 T7 N8 T6 R1 P1 N2 N1 L4",
           dq="G2 G1 L8 K5 K2 J2 J1 R7 T4 T2 T3 R3 R5 P3 N3 K1", dqm="R6 T5",
           attrs=Attrs(io_standard="3.3-V LVCMOS")),
   ]
   connectors  = [
       Connector("j", 1,
           "A8  D3  B8  C3  A2  A3  B3  B4  A4  B5  "
           "-   -   A5  D5  B6  A6  B7  D6  A7  C6  "
           "C8  E6  E7  D8  E8  F8  F9  E9  -   -   "
           "C9  D9  E11 E10 C11 B11 A12 D11 D12 B12  "),
       Connector("j", 2,
           "T9   F13  R9   T15  T14  T13  R13  T12  R12  T11  "
           "-    -    T10  R11  P11  R10  N12  P9   N9   N11"
           "L16  K16  R16  L15  P15  P16  R14  N16  -    -    "
           "N15  P14  L14  N14  M10  L13  J16  K15  J13  J14  "),
       Connector("j", 3,
           "-    E15  E16  M16  A14  B16  C14   C16   C15  "
           "D16  D15  D14  F15  F16  F14  G16   G15   -    "
           "-    -    -    -    -    -    -     -  "),
   ]
    def toolchAIn_program(self, products, name):
       quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm")
       with products.extract("{}.sof".format(name)) as bitstream_filename:
           subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG",
                                  "--operation", "P;" + bitstream_filename])

下面我们写一个blinker.py例程测试下:

#!/usr/bin/env python3
from nmigen import *
from de0_nano import DE0NanoPlatform
class Blinker(Elaboratable):
   def __init__(self, max_prd):
       self.max_prd = max_prd
   def elaborate(self, platform):
        led = platform.request("led", 0);
       m = Module()
       counter = Signal(range(self.max_prd + 1))
       period = Signal(range(self.max_prd + 1))
        # load/init period value
       m.d.comb += period.eq(self.max_prd)
        with m.If(counter == 0):
           m.d.sync += [
                   led.eq(~led),
                   counter.eq(period)
           ]
        with m.Else():
           m.d.sync += [
                   counter.eq(counter - 1)
           ]
        return m
if __name__ == "__main__":
    plat = DE0NanoPlatform()
    plat.build(Blinker(40000000), do_program=True)

将DE0_Nano连上电脑, 运行 > ./Blinker.py 完成项目的编译,综合,映射,下载运行....

Image.png

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

关闭

站长推荐上一条 /2 下一条

小黑屋| 关于我们| 联系我们| 在线咨询 |  EETOP 创芯网 ( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2020-10-27 14:54 , Processed in 0.033667 second(s), 6 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

返回顶部