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

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

Run lambdaSoC with upduino_v2 platform

已有 4801 次阅读| 2020-10-1 23:34 |系统分类:芯片设计| nMigen, LambdaSoC, RISCV, FPGA, Python

Tested platform:

    WIN10-WSL (ubuntu 18.04) : yosys / next-pnr-ice40 / icestorm build  from latest github

            - Note:  WSL does not support FTDI usb device,  use windows version "iceprog.exe" instead
    ubuntu 18.04 : yosys / next_pnr-ice40 / icestorm build from latest github
    Msys  - mingw64:  toolchain-yosys / toolchain-ice40 from FPGAWars github
             yosys : https://github.com/FPGAwars/toolchain-yosys
             nxt_pnr-ice40:  https://github.com/FPGAwars/toolchain-ice40
    FTDI driver:
             WIN10/WSL & Msys: https://zadig.akeo.ie/ 
                 - Modify default winusb driver to libusbK (libusb-1.0 support)
             Ubuntu 18.04:  sudo apt install libftdi-dev

Msys prepare:

Get copy of Msys from  https://www.msys2.org/ 

After Msys successfully installed,  follow below steps to make it works smoothly:
  1. change software package source to native ones, the configure file location: msys64/etc/pacman.d/
  2. if pacman timeout, try --disable-download-timeout while run pacman
  3. run msys2_shell.bat: pacman -Sy  to update core packages
update core packages: 
pacman -S --needed filesystem msys2-runtime bash libreadline libiconv \
                                    libarchive libgpgme libcurl pacman ncurses libintl
then close all MSYS2 shell,run autorebase.bat
update other packages:pacman -Su
Usefull commands:
    pacman -Q  to list packages installed
    pacman -S -g to list package groups
    pacman -Q -g base-devel to list packages inside a software
    pacman -Q -l vim to list contents of a package
    pacman -Q -s nettle to query the package of software
    for help:pacman -h ;pacman -S -
it's recommendded to install toolchains by its package group:
    pacman -S mingw-w64-i686-toolchain
    pacman -S mingw-w64-x86_64-toolchain
    pacman -S base-devel
    pacman -S vim
   
We need python3 to run our nmigen platform
    pacman -S python3 python3-pip

nMigen & lambdaSoC prepare    

    git clone https://github.com/nmigen/nmigen

    cd nmigen && python3 setup.py install
    git clone https://github.com/nmigen/nmigen-soc
    cd nmigen-soc && python3 setup.py install
    git clone https://github.com/nmigen/nmigen-stdio
    cd nmigen-stdio && python3 setup.py install
    git clone https://github.com/nmigen/nmigen-boards
    cd nmigen-boards && python3 setup.py install
    git clone https://github.com/lambdaconcept/minerva
    cd minerva && python3 setup.py install
    git clone https://github.com/lambdaconcept/lambdasoc
    cd lambdasoc && python3 setup.py install

RISCV toolchain prepare

    lambdasoc based on Minerva (pure python version) RISCV core,  so we needs riscv toochain for soc software building.

    there is a prebuild version from sifive which is almost prefect for us (for Windows/Linux/MacOS)
    go to  https://www.sifive.com/boards for more details.

Windows prepare for WSL or Msys 

    If we use win10/WSL, we can build our own yosys / icestorm / next-pnr from github source,

    but as known, WSL do not support native USB device (libusb-1.0), so we needs a windows version "iceprog.exe" 
    to do program, for all others toolchains, we can use our build version (WSL/ubuntu)
    if we use Msys-mingw64, recommeneded to use yosys and iCE40 toolchains released from FPGAwars
    
    After software installed, our bash script should be updated as follow:
    .bash_alias for WIN10/WSL, (yosys/next-pnr/icestorm builded and installed to /usr/local/bin)
export DISPLAY=localhost:0.0
export RISCV=/opt/riscv64-elf-x86_64
RISCV32=/opt/lowrisc-rv32imc
PATH=$PATH:$RISCV/bin
PATH=$PATH:$RISCV32/bin
# we just needs iceprog.exe only, so copy it to a new directory
PATH=$PATH:/mnt/d/Software/toolchain-ice40-windows_amd64-2019.12.11/bin/iceprog-win
export PATH
export ICEPROG="iceprog.exe"

.bashrc for Msys - mingw64

# alias cd=cd_func
PATH='/c/openEDA/iverilog/bin':$PATH
PATH='/c/openEDA/iverilog/gtkwave/bin':$PATH
PATH='/d/Software/toolchain-ecp5-windows_amd64-2019.12.11/bin':$PATH
PATH='/d/Software/toolchain-ice40-windows_amd64-2019.12.11/bin':$PATH
PATH='/d/Software/toolchain-yosys-windows_amd64-2019.12.11/bin':$PATH
PATH='/d/Software/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-w64-mingw32/bin':$PATH
#PATH='/d/intelFPGA/18.1/quartus/bin64':$PATH
#PATH='/d/Xilinx/Vivado/2018.3/bin':$PATH
#PATH='/d/Software/xc3sprog_win32_rev780':$PATH
#PATH=$PATH:'/c/Program Files (x86)/Vim/vim82'
export PATH

Test nMigen platform 

    Create a directory for test our nMigen building platform

$mkdir ~/nmigen_test
$cd ~/nmigen_test
$cp ~/projects/nmigen/nmigen-boards/nmigen_boards/upduino_v2.py .
    
    By default, upduino_v2.py build based on upduino_v1.py, which defined default_clk to "SB_HFOSC"
there is no "SB_HFOSC" instance inside upduino_v2.py, so if we try to build, will got error.
    to fix the problem, we can add SB_HFOSC instance and modify "sync" domain to output of SB_HFOSC.
But very lucky, upduino_v2 route on-board 12MHz crystall output to J8 which can be coupled with JP6-12 
easily with a jumper.  so we can define default clock to extenal clock resource "clk12" defined inside upduino_v2.py
modify our upduino_v2.py like this: (care of lines in Bold)
#!/usr/bin/env python3
import os
import subprocess
from nmigen.build import *
from nmigen.vendor.lattice_ice40 import *
from nmigen_boards.resources import *
from nmigen_boards.upduino_v1 import UpduinoV1Platform
from nmigen_boards.test.blinky import Blinky
class myPlatform(UpduinoV1Platform):
    default_clk = "clk12"
    # Mostly identical to the V1 board, but it has an integrated
    # programmer and a 12MHz oscillator which is NC by default.
    resources = UpduinoV1Platform.resources + [
        # Solder pin 12 to the adjacent 'J8' osc_out pin to enable.
        Resource("clk12", 0, Pins("12", dir="i"),
                 Clock(12e6), Attrs(IO_STANDARD="SB_LVCMOS")),
    ]
    def toolchain_program(self, products, name):
        iceprog = os.environ.get("ICEPROG", "iceprog")
        with products.extract("{}.bin".format(name)) as bitstream_filename:
            subprocess.check_call([iceprog, bitstream_filename])
if __name__ == "__main__":
    myPlatform().build(Blinky(), do_program=True)

Now, we can connect upduino_v2 kit to our computer and run "python3 upduino_v2.py"

Just wait and see....
hope there is no any problem.
    If everything goes well, it's time to build lambdaSoC for our upduino_v2.
Firstly, Copy example soc from lambdasoc directory:
    $cp ~/projects/lambdaconcept/lambdasoc/example/sram_soc.py .

    Before start, we should make serveral modification to make it fit our upduino_v2

  1. upduino_v2 has limited ram resouce , so reduced the rom size to fit up5k device
  2. add UART resource definition, which is useful for debug, also needed by example soc
  3. for Msys-mingw64, there is no "glob.h" (posix api) support, which need by lambdsoc build procedure,
           here we just disable do_build and do_init of soc to passby the problem.
          

Finally, upduino_v2.py and sram_soc.py after modification:

# filename: upduino_v2.py
import os
import subprocess
from nmigen.build import *
from nmigen.vendor.lattice_ice40 import *
from nmigen_boards.resources import *
from nmigen_boards.upduino_v1 import UpduinoV1Platform
__all__ = ["UpduinoV2Platform"]
class UpduinoV2Platform(UpduinoV1Platform):
    # Mostly identical to the V1 board, but it has an integrated
    # programmer and a 12MHz oscillator which is NC by default.
    default_clk = "clk12"
    resources = UpduinoV1Platform.resources + [
        # Solder pin 12 to the adjacent 'J8' osc_out pin to enable.
        Resource("clk12", 0, Pins("12", dir="i"),
                 Clock(12e6), Attrs(IO_STANDARD="SB_LVCMOS")),
        UARTResource(0,
            rx="6", tx="9", attrs=Attrs(IO_STANDARD="SB_LVTTL", PULLUP=1)),
    ]
    def toolchain_program(self, products, name):
        iceprog = os.environ.get("ICEPROG", "iceprog")
        with products.extract("{}.bin".format(name)) as bitstream_filename:
            subprocess.check_call([iceprog, bitstream_filename])
if __name__ == "__main__":
    from nmigen_boards.test.blinky import *
    UpduinoV2Platform().build(Blinky(), do_program=True)

    

Filename: sram_soc.py

# filename: sram_soc.py
import argparse
import importlib
from nmigen import *
from nmigen_soc import wishbone
from lambdasoc.cpu.minerva import MinervaCPU
from lambdasoc.periph.intc import GenericInterruptController
from lambdasoc.periph.serial import AsyncSerialPeripheral
from lambdasoc.periph.sram import SRAMPeripheral
from lambdasoc.periph.timer import TimerPeripheral
from lambdasoc.soc.cpu import CPUSoC
# import our modified version
from upduino_v2 import UpduinoV2Platform
__all__ = ["SRAMSoC"]
class SRAMSoC(CPUSoC, Elaboratable):
    def __init__(self, *, reset_addr, clk_freq,
                 rom_addr, rom_size,
                 ram_addr, ram_size,
                 uart_addr, uart_divisor, uart_pins,
                 timer_addr, timer_width):
        self._arbiter = wishbone.Arbiter(addr_width=30, data_width=32, granularity=8,
                                         features={"cti", "bte"})
        self._decoder = wishbone.Decoder(addr_width=30, data_width=32, granularity=8,
                                         features={"cti", "bte"})
        self.cpu = MinervaCPU(reset_address=reset_addr)
        self._arbiter.add(self.cpu.ibus)
        self._arbiter.add(self.cpu.dbus)
        self.rom = SRAMPeripheral(size=rom_size, writable=False)
        self._decoder.add(self.rom.bus, addr=rom_addr)
        self.ram = SRAMPeripheral(size=ram_size)
        self._decoder.add(self.ram.bus, addr=ram_addr)
        self.uart = AsyncSerialPeripheral(divisor=uart_divisor, pins=uart_pins)
        self._decoder.add(self.uart.bus, addr=uart_addr)
        self.timer = TimerPeripheral(width=timer_width)
        self._decoder.add(self.timer.bus, addr=timer_addr)
        self.intc = GenericInterruptController(width=len(self.cpu.ip))
        self.intc.add_irq(self.timer.irq, 0)
        self.intc.add_irq(self.uart .irq, 1)
        self.memory_map = self._decoder.bus.memory_map
        self.clk_freq = clk_freq
    def elaborate(self, platform):
        m = Module()
        m.submodules.arbiter = self._arbiter
        m.submodules.cpu     = self.cpu
        m.submodules.decoder = self._decoder
        m.submodules.rom     = self.rom
        m.submodules.ram     = self.ram
        m.submodules.uart    = self.uart
        m.submodules.timer   = self.timer
        m.submodules.intc    = self.intc
        m.d.comb += [
            self._arbiter.bus.connect(self._decoder.bus),
            self.cpu.ip.eq(self.intc.ip),
        ]
        return m
if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--baudrate", type=int,
            default=9600,
            help="UART baudrate (default: 9600)")
    args = parser.parse_args()
    # here will modify paltform only target for upduino_v2
    platform = UpduinoV2Platform()
    uart_divisor = int(platform.default_clk_frequency // args.baudrate)
    uart_pins = platform.request("uart", 0)
    soc = SRAMSoC(
         reset_addr=0x00000000, clk_freq=int(platform.default_clk_frequency),
           rom_addr=0x00000000, rom_size=0x1000,
           ram_addr=0x00004000, ram_size=0x1000,
          uart_addr=0x00005000, uart_divisor=uart_divisor, uart_pins=uart_pins,
         timer_addr=0x00006000, timer_width=32,
    )
    # disable soc build/init only for Msys-mingw64
    soc.build(do_build=False, do_init=False)
    platform.build(soc, do_program=True)

    Connect upduino_v2 to computer then start building example soc by run: 

    $python3 sram_soc.py


点赞

评论 (0 个评论)

facelist

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

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 4

    粉丝
  • 3

    好友
  • 0

    获赞
  • 13

    评论
  • 412

    访问数
关闭

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

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

GMT+8, 2024-3-29 20:49 , Processed in 0.025947 second(s), 14 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部