sw: first software commit
The software is untested, but it builds. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
		
							
								
								
									
										14
									
								
								hw/bin/litex_read_verilog
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_read_verilog
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
			
		||||
# directory.  Obtain the current path so we can get the absolute parent path.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(
 | 
			
		||||
    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
			
		||||
sys.path.insert(0, script_path)
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
from litex.tools.litex_read_verilog import main
 | 
			
		||||
main()
 | 
			
		||||
							
								
								
									
										14
									
								
								hw/bin/litex_server
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_server
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
			
		||||
# directory.  Obtain the current path so we can get the absolute parent path.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(
 | 
			
		||||
    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
			
		||||
sys.path.insert(0, script_path)
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
from litex.tools.litex_server import main
 | 
			
		||||
main()
 | 
			
		||||
							
								
								
									
										14
									
								
								hw/bin/litex_sim
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_sim
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
			
		||||
# directory.  Obtain the current path so we can get the absolute parent path.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(
 | 
			
		||||
    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
			
		||||
sys.path.insert(0, script_path)
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
from litex.tools.litex_sim import main
 | 
			
		||||
main()
 | 
			
		||||
							
								
								
									
										14
									
								
								hw/bin/litex_simple
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_simple
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
			
		||||
# directory.  Obtain the current path so we can get the absolute parent path.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(
 | 
			
		||||
    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
			
		||||
sys.path.insert(0, script_path)
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
from litex.boards.targets.simple import main
 | 
			
		||||
main()
 | 
			
		||||
							
								
								
									
										14
									
								
								hw/bin/litex_term
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/litex_term
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
			
		||||
# directory.  Obtain the current path so we can get the absolute parent path.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(
 | 
			
		||||
    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
			
		||||
sys.path.insert(0, script_path)
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
from litex.tools.litex_term import main
 | 
			
		||||
main()
 | 
			
		||||
							
								
								
									
										14
									
								
								hw/bin/mkmscimg
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								hw/bin/mkmscimg
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
			
		||||
# directory.  Obtain the current path so we can get the absolute parent path.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(
 | 
			
		||||
    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
			
		||||
sys.path.insert(0, script_path)
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
from litex.soc.software.mkmscimg import main
 | 
			
		||||
main()
 | 
			
		||||
							
								
								
									
										1
									
								
								hw/deps/litedram
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litedram
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litedram added at da68e21bad
									
								
							
							
								
								
									
										1
									
								
								hw/deps/litescope
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litescope
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litescope added at 7f20aa477f
									
								
							
							
								
								
									
										1
									
								
								hw/deps/litex
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/litex
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/litex added at 3a72688b28
									
								
							
							
								
								
									
										1
									
								
								hw/deps/lxsocsupport
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/lxsocsupport
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/lxsocsupport added at 74f1333401
									
								
							
							
								
								
									
										1
									
								
								hw/deps/migen
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/migen
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/migen added at bc903441a5
									
								
							
							
								
								
									
										1
									
								
								hw/deps/pyserial
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/pyserial
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/pyserial added at acab9d2c0e
									
								
							
							
								
								
									
										1
									
								
								hw/deps/valentyusb
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								hw/deps/valentyusb
									
									
									
									
									
										Submodule
									
								
							 Submodule hw/deps/valentyusb added at 3052a16d9f
									
								
							
							
								
								
									
										883
									
								
								hw/factory-bitstream.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										883
									
								
								hw/factory-bitstream.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,883 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
# This variable defines all the external programs that this module
 | 
			
		||||
# relies on.  lxbuildenv reads this variable in order to ensure
 | 
			
		||||
# the build will finish without exiting due to missing third-party
 | 
			
		||||
# programs.
 | 
			
		||||
LX_DEPENDENCIES = ["riscv", "icestorm", "yosys"]
 | 
			
		||||
 | 
			
		||||
# Import lxbuildenv to integrate the deps/ directory
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
# Disable pylint's E1101, which breaks completely on migen
 | 
			
		||||
#pylint:disable=E1101
 | 
			
		||||
 | 
			
		||||
#from migen import *
 | 
			
		||||
from migen import Module, Signal, Instance, ClockDomain, If
 | 
			
		||||
from migen.genlib.resetsync import AsyncResetSynchronizer
 | 
			
		||||
from migen.fhdl.specials import TSTriple
 | 
			
		||||
from migen.fhdl.bitcontainer import bits_for
 | 
			
		||||
from migen.fhdl.structure import ClockSignal, ResetSignal, Replicate, Cat
 | 
			
		||||
 | 
			
		||||
from litex.build.lattice.platform import LatticePlatform
 | 
			
		||||
from litex.build.generic_platform import Pins, IOStandard, Misc, Subsignal
 | 
			
		||||
from litex.soc.integration import SoCCore
 | 
			
		||||
from litex.soc.integration.builder import Builder
 | 
			
		||||
from litex.soc.integration.soc_core import csr_map_update
 | 
			
		||||
from litex.soc.interconnect import wishbone
 | 
			
		||||
from litex.soc.interconnect.csr import AutoCSR, CSRStatus, CSRStorage
 | 
			
		||||
 | 
			
		||||
from valentyusb import usbcore
 | 
			
		||||
from valentyusb.usbcore import io as usbio
 | 
			
		||||
from valentyusb.usbcore.cpu import epmem, unififo, epfifo
 | 
			
		||||
from valentyusb.usbcore.endpoint import EndpointType
 | 
			
		||||
 | 
			
		||||
from lxsocsupport import up5kspram, spi_flash
 | 
			
		||||
 | 
			
		||||
import argparse
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
_io_evt = [
 | 
			
		||||
    ("serial", 0,
 | 
			
		||||
        Subsignal("rx", Pins("21")),
 | 
			
		||||
        Subsignal("tx", Pins("13"), Misc("PULLUP")),
 | 
			
		||||
        IOStandard("LVCMOS33")
 | 
			
		||||
    ),
 | 
			
		||||
    ("usb", 0,
 | 
			
		||||
        Subsignal("d_p", Pins("34")),
 | 
			
		||||
        Subsignal("d_n", Pins("37")),
 | 
			
		||||
        Subsignal("pullup", Pins("35")),
 | 
			
		||||
        Subsignal("pulldown", Pins("36")),
 | 
			
		||||
        IOStandard("LVCMOS33")
 | 
			
		||||
    ),
 | 
			
		||||
    ("touch", 0,
 | 
			
		||||
        Subsignal("t1", Pins("48"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t2", Pins("47"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t3", Pins("46"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t4", Pins("45"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("pmoda", 0,
 | 
			
		||||
        Subsignal("p1", Pins("28"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("p2", Pins("27"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("p3", Pins("26"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("p4", Pins("23"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("pmodb", 0,
 | 
			
		||||
        Subsignal("p1", Pins("48"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("p2", Pins("47"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("p3", Pins("46"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("p4", Pins("45"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("led", 0,
 | 
			
		||||
        Subsignal("rgb0", Pins("39"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("rgb1", Pins("40"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("rgb2", Pins("41"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("spiflash", 0,
 | 
			
		||||
        Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("clk",  Pins("15"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("miso", Pins("17"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("mosi", Pins("14"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("wp",   Pins("18"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("hold", Pins("19"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("spiflash4x", 0,
 | 
			
		||||
        Subsignal("cs_n", Pins("16"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("clk",  Pins("15"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("dq",   Pins("14 17 19 18"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("clk48", 0, Pins("44"), IOStandard("LVCMOS33"))
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
_io_pvt = [
 | 
			
		||||
    ("serial", 0,
 | 
			
		||||
        Subsignal("rx", Pins("C3")),
 | 
			
		||||
        Subsignal("tx", Pins("B3"), Misc("PULLUP")),
 | 
			
		||||
        IOStandard("LVCMOS33")
 | 
			
		||||
    ),
 | 
			
		||||
    ("usb", 0,
 | 
			
		||||
        Subsignal("d_p", Pins("A1")),
 | 
			
		||||
        Subsignal("d_n", Pins("A2")),
 | 
			
		||||
        Subsignal("pullup", Pins("A4")),
 | 
			
		||||
        IOStandard("LVCMOS33")
 | 
			
		||||
    ),
 | 
			
		||||
    ("touch", 0,
 | 
			
		||||
        Subsignal("t1", Pins("E4"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t2", Pins("D5"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t3", Pins("E5"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t4", Pins("F5"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("led", 0,
 | 
			
		||||
        Subsignal("rgb0", Pins("A5"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("rgb1", Pins("B5"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("rgb2", Pins("C5"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("spiflash", 0,
 | 
			
		||||
        Subsignal("cs_n", Pins("C1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("clk",  Pins("D1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("miso", Pins("E1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("mosi", Pins("F1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("wp",   Pins("F2"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("hold", Pins("B1"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("spiflash4x", 0,
 | 
			
		||||
        Subsignal("cs_n", Pins("C1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("clk",  Pins("D1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("dq",   Pins("E1 F1 F2 B1"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("clk48", 0, Pins("F4"), IOStandard("LVCMOS33"))
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
_io_hacker = [
 | 
			
		||||
    ("serial", 0,
 | 
			
		||||
        Subsignal("rx", Pins("C3")),
 | 
			
		||||
        Subsignal("tx", Pins("B3"), Misc("PULLUP")),
 | 
			
		||||
        IOStandard("LVCMOS33")
 | 
			
		||||
    ),
 | 
			
		||||
    ("usb", 0,
 | 
			
		||||
        Subsignal("d_p", Pins("A4")),
 | 
			
		||||
        Subsignal("d_n", Pins("A2")),
 | 
			
		||||
        Subsignal("pullup", Pins("D5")),
 | 
			
		||||
        IOStandard("LVCMOS33")
 | 
			
		||||
    ),
 | 
			
		||||
    ("touch", 0,
 | 
			
		||||
        Subsignal("t1", Pins("F4"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t2", Pins("E5"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t3", Pins("E4"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("t4", Pins("F2"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("led", 0,
 | 
			
		||||
        Subsignal("rgb0", Pins("A5"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("rgb1", Pins("B5"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("rgb2", Pins("C5"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("spiflash", 0,
 | 
			
		||||
        Subsignal("cs_n", Pins("C1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("clk",  Pins("D1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("miso", Pins("E1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("mosi", Pins("F1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("wp",   Pins("A1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("hold", Pins("B1"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("spiflash4x", 0,
 | 
			
		||||
        Subsignal("cs_n", Pins("C1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("clk",  Pins("D1"), IOStandard("LVCMOS33")),
 | 
			
		||||
        Subsignal("dq",   Pins("E1 F1 A1 B1"), IOStandard("LVCMOS33")),
 | 
			
		||||
    ),
 | 
			
		||||
    ("clk48", 0, Pins("F5"), IOStandard("LVCMOS33"))
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
_connectors = []
 | 
			
		||||
 | 
			
		||||
class _CRG(Module):
 | 
			
		||||
    def __init__(self, platform, use_pll):
 | 
			
		||||
        clk48_raw = platform.request("clk48")
 | 
			
		||||
        clk12_raw = Signal()
 | 
			
		||||
        clk48 = Signal()
 | 
			
		||||
        clk12 = Signal()
 | 
			
		||||
 | 
			
		||||
        reset_delay = Signal(13, reset=4095)
 | 
			
		||||
        self.clock_domains.cd_por = ClockDomain()
 | 
			
		||||
        self.reset = Signal()
 | 
			
		||||
 | 
			
		||||
        self.clock_domains.cd_sys = ClockDomain()
 | 
			
		||||
        self.clock_domains.cd_usb_12 = ClockDomain()
 | 
			
		||||
        self.clock_domains.cd_usb_48 = ClockDomain()
 | 
			
		||||
 | 
			
		||||
        platform.add_period_constraint(self.cd_usb_48.clk, 1e9/48e6)
 | 
			
		||||
        platform.add_period_constraint(self.cd_sys.clk, 1e9/12e6)
 | 
			
		||||
        platform.add_period_constraint(self.cd_usb_12.clk, 1e9/12e6)
 | 
			
		||||
        platform.add_period_constraint(clk48, 1e9/48e6)
 | 
			
		||||
        platform.add_period_constraint(clk48_raw, 1e9/48e6)
 | 
			
		||||
        platform.add_period_constraint(clk12_raw, 1e9/12e6)
 | 
			
		||||
 | 
			
		||||
        # POR reset logic- POR generated from sys clk, POR logic feeds sys clk
 | 
			
		||||
        # reset.
 | 
			
		||||
        self.comb += [
 | 
			
		||||
            self.cd_por.clk.eq(self.cd_sys.clk),
 | 
			
		||||
            self.cd_sys.rst.eq(reset_delay != 0),
 | 
			
		||||
            self.cd_usb_12.rst.eq(reset_delay != 0),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        if use_pll:
 | 
			
		||||
            # Divide clk48 down to clk12, to ensure they're synchronized.
 | 
			
		||||
            # By doing this, we avoid needing clock-domain crossing.
 | 
			
		||||
            clk12_counter = Signal(2)
 | 
			
		||||
 | 
			
		||||
            self.clock_domains.cd_usb_48_raw = ClockDomain()
 | 
			
		||||
 | 
			
		||||
            platform.add_period_constraint(self.cd_usb_48_raw.clk, 1e9/48e6)
 | 
			
		||||
 | 
			
		||||
            # POR reset logic- POR generated from sys clk, POR logic feeds sys clk
 | 
			
		||||
            # reset.
 | 
			
		||||
            self.comb += [
 | 
			
		||||
                self.cd_usb_48.rst.eq(reset_delay != 0),
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
            self.comb += self.cd_usb_48_raw.clk.eq(clk48_raw)
 | 
			
		||||
            self.comb += self.cd_usb_48.clk.eq(clk48)
 | 
			
		||||
 | 
			
		||||
            self.sync.usb_48_raw += clk12_counter.eq(clk12_counter + 1)
 | 
			
		||||
 | 
			
		||||
            self.comb += clk12_raw.eq(clk12_counter[1])
 | 
			
		||||
            self.specials += Instance(
 | 
			
		||||
                "SB_GB",
 | 
			
		||||
                i_USER_SIGNAL_TO_GLOBAL_BUFFER=clk12_raw,
 | 
			
		||||
                o_GLOBAL_BUFFER_OUTPUT=clk12,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            self.specials += Instance(
 | 
			
		||||
                "SB_PLL40_CORE",
 | 
			
		||||
                # Parameters
 | 
			
		||||
                p_DIVR = 0,
 | 
			
		||||
                p_DIVF = 3,
 | 
			
		||||
                p_DIVQ = 2,
 | 
			
		||||
                p_FILTER_RANGE = 1,
 | 
			
		||||
                p_FEEDBACK_PATH = "PHASE_AND_DELAY",
 | 
			
		||||
                p_DELAY_ADJUSTMENT_MODE_FEEDBACK = "FIXED",
 | 
			
		||||
                p_FDA_FEEDBACK = 15,
 | 
			
		||||
                p_DELAY_ADJUSTMENT_MODE_RELATIVE = "FIXED",
 | 
			
		||||
                p_FDA_RELATIVE = 0,
 | 
			
		||||
                p_SHIFTREG_DIV_MODE = 1,
 | 
			
		||||
                p_PLLOUT_SELECT = "SHIFTREG_0deg",
 | 
			
		||||
                p_ENABLE_ICEGATE = 0,
 | 
			
		||||
                # IO
 | 
			
		||||
                i_REFERENCECLK = clk12,
 | 
			
		||||
                # o_PLLOUTCORE = clk12,
 | 
			
		||||
                o_PLLOUTGLOBAL = clk48,
 | 
			
		||||
                #i_EXTFEEDBACK,
 | 
			
		||||
                #i_DYNAMICDELAY,
 | 
			
		||||
                #o_LOCK,
 | 
			
		||||
                i_BYPASS = 0,
 | 
			
		||||
                i_RESETB = 1,
 | 
			
		||||
                #i_LATCHINPUTVALUE,
 | 
			
		||||
                #o_SDO,
 | 
			
		||||
                #i_SDI,
 | 
			
		||||
            )
 | 
			
		||||
        else:
 | 
			
		||||
            self.specials += Instance(
 | 
			
		||||
                "SB_GB",
 | 
			
		||||
                i_USER_SIGNAL_TO_GLOBAL_BUFFER=clk48_raw,
 | 
			
		||||
                o_GLOBAL_BUFFER_OUTPUT=clk48,
 | 
			
		||||
            )
 | 
			
		||||
            self.comb += self.cd_usb_48.clk.eq(clk48)
 | 
			
		||||
 | 
			
		||||
            clk12_counter = Signal(2)
 | 
			
		||||
            self.sync.usb_48 += clk12_counter.eq(clk12_counter + 1)
 | 
			
		||||
 | 
			
		||||
            self.comb += clk12_raw.eq(clk12_counter[1])
 | 
			
		||||
            self.specials += Instance(
 | 
			
		||||
                "SB_GB",
 | 
			
		||||
                i_USER_SIGNAL_TO_GLOBAL_BUFFER=clk12_raw,
 | 
			
		||||
                o_GLOBAL_BUFFER_OUTPUT=clk12,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        self.comb += self.cd_sys.clk.eq(clk12)
 | 
			
		||||
        self.comb += self.cd_usb_12.clk.eq(clk12)
 | 
			
		||||
 | 
			
		||||
        self.sync.por += \
 | 
			
		||||
            If(reset_delay != 0,
 | 
			
		||||
                reset_delay.eq(reset_delay - 1)
 | 
			
		||||
            )
 | 
			
		||||
        self.specials += AsyncResetSynchronizer(self.cd_por, self.reset)
 | 
			
		||||
 | 
			
		||||
class RandomFirmwareROM(wishbone.SRAM):
 | 
			
		||||
    """
 | 
			
		||||
    Seed the random data with a fixed number, so different bitstreams
 | 
			
		||||
    can all share firmware.
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self, size, seed=2373):
 | 
			
		||||
        def xorshift32(x):
 | 
			
		||||
            x = x ^ (x << 13) & 0xffffffff
 | 
			
		||||
            x = x ^ (x >> 17) & 0xffffffff
 | 
			
		||||
            x = x ^ (x << 5)  & 0xffffffff
 | 
			
		||||
            return x & 0xffffffff
 | 
			
		||||
 | 
			
		||||
        def get_rand(x):
 | 
			
		||||
            out = 0
 | 
			
		||||
            for i in range(32):
 | 
			
		||||
                x = xorshift32(x)
 | 
			
		||||
                if (x & 1) == 1:
 | 
			
		||||
                    out = out | (1 << i)
 | 
			
		||||
            return out & 0xffffffff
 | 
			
		||||
        data = []
 | 
			
		||||
        seed = 1
 | 
			
		||||
        for d in range(int(size / 4)):
 | 
			
		||||
            seed = get_rand(seed)
 | 
			
		||||
            data.append(seed)
 | 
			
		||||
        wishbone.SRAM.__init__(self, size, read_only=True, init=data)
 | 
			
		||||
 | 
			
		||||
class FirmwareROM(wishbone.SRAM):
 | 
			
		||||
    def __init__(self, size, filename):
 | 
			
		||||
        data = []
 | 
			
		||||
        with open(filename, 'rb') as inp:
 | 
			
		||||
            data = inp.read()
 | 
			
		||||
        wishbone.SRAM.__init__(self, size, read_only=True, init=data)
 | 
			
		||||
 | 
			
		||||
class Platform(LatticePlatform):
 | 
			
		||||
    def __init__(self, revision=None, toolchain="icestorm"):
 | 
			
		||||
        if revision == "evt":
 | 
			
		||||
            LatticePlatform.__init__(self, "ice40-up5k-sg48", _io_evt, _connectors, toolchain="icestorm")
 | 
			
		||||
        elif revision == "pvt" or revision == "dvt":
 | 
			
		||||
            LatticePlatform.__init__(self, "ice40-up5k-uwg30", _io_pvt, _connectors, toolchain="icestorm")
 | 
			
		||||
        elif revision == "hacker":
 | 
			
		||||
            LatticePlatform.__init__(self, "ice40-up5k-uwg30", _io_hacker, _connectors, toolchain="icestorm")
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError("Unrecognized reivsion: {}.  Known values: evt, dvt, pvt, hacker".format(revision))
 | 
			
		||||
 | 
			
		||||
    def create_programmer(self):
 | 
			
		||||
        raise ValueError("programming is not supported")
 | 
			
		||||
 | 
			
		||||
class SBLED(Module, AutoCSR):
 | 
			
		||||
    def __init__(self, pads):
 | 
			
		||||
        rgba_pwm = Signal(3)
 | 
			
		||||
 | 
			
		||||
        self.dat = CSRStorage(8)
 | 
			
		||||
        self.addr = CSRStorage(4)
 | 
			
		||||
        self.ctrl = CSRStorage(4)
 | 
			
		||||
 | 
			
		||||
        self.specials += Instance("SB_RGBA_DRV",
 | 
			
		||||
            i_CURREN = self.ctrl.storage[1],
 | 
			
		||||
            i_RGBLEDEN = self.ctrl.storage[2],
 | 
			
		||||
            i_RGB0PWM = rgba_pwm[0],
 | 
			
		||||
            i_RGB1PWM = rgba_pwm[1],
 | 
			
		||||
            i_RGB2PWM = rgba_pwm[2],
 | 
			
		||||
            o_RGB0 = pads.rgb0,
 | 
			
		||||
            o_RGB1 = pads.rgb1,
 | 
			
		||||
            o_RGB2 = pads.rgb2,
 | 
			
		||||
            p_CURRENT_MODE = "0b1",
 | 
			
		||||
            p_RGB0_CURRENT = "0b000011",
 | 
			
		||||
            p_RGB1_CURRENT = "0b000001",
 | 
			
		||||
            p_RGB2_CURRENT = "0b000011",
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.specials += Instance("SB_LEDDA_IP",
 | 
			
		||||
            i_LEDDCS = self.dat.re,
 | 
			
		||||
            i_LEDDCLK = ClockSignal(),
 | 
			
		||||
            i_LEDDDAT7 = self.dat.storage[7],
 | 
			
		||||
            i_LEDDDAT6 = self.dat.storage[6],
 | 
			
		||||
            i_LEDDDAT5 = self.dat.storage[5],
 | 
			
		||||
            i_LEDDDAT4 = self.dat.storage[4],
 | 
			
		||||
            i_LEDDDAT3 = self.dat.storage[3],
 | 
			
		||||
            i_LEDDDAT2 = self.dat.storage[2],
 | 
			
		||||
            i_LEDDDAT1 = self.dat.storage[1],
 | 
			
		||||
            i_LEDDDAT0 = self.dat.storage[0],
 | 
			
		||||
            i_LEDDADDR3 = self.addr.storage[3],
 | 
			
		||||
            i_LEDDADDR2 = self.addr.storage[2],
 | 
			
		||||
            i_LEDDADDR1 = self.addr.storage[1],
 | 
			
		||||
            i_LEDDADDR0 = self.addr.storage[0],
 | 
			
		||||
            i_LEDDDEN = self.dat.re,
 | 
			
		||||
            i_LEDDEXE = self.ctrl.storage[0],
 | 
			
		||||
            # o_LEDDON = led_is_on, # Indicates whether LED is on or not
 | 
			
		||||
            # i_LEDDRST = ResetSignal(), # This port doesn't actually exist
 | 
			
		||||
            o_PWMOUT0 = rgba_pwm[0], 
 | 
			
		||||
            o_PWMOUT1 = rgba_pwm[1], 
 | 
			
		||||
            o_PWMOUT2 = rgba_pwm[2],
 | 
			
		||||
            o_LEDDON = Signal(), 
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SBWarmBoot(Module, AutoCSR):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.ctrl = CSRStorage(size=8)
 | 
			
		||||
        self.addr = CSRStorage(size=32)
 | 
			
		||||
        do_reset = Signal()
 | 
			
		||||
        self.comb += [
 | 
			
		||||
            # "Reset Key" is 0xac (0b101011xx)
 | 
			
		||||
            do_reset.eq(self.ctrl.storage[2] & self.ctrl.storage[3] & ~self.ctrl.storage[4]
 | 
			
		||||
                      & self.ctrl.storage[5] & ~self.ctrl.storage[6] & self.ctrl.storage[7])
 | 
			
		||||
        ]
 | 
			
		||||
        self.specials += Instance("SB_WARMBOOT",
 | 
			
		||||
            i_S0   = self.ctrl.storage[0],
 | 
			
		||||
            i_S1   = self.ctrl.storage[1],
 | 
			
		||||
            i_BOOT = do_reset,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
class TouchPads(Module, AutoCSR):
 | 
			
		||||
    def __init__(self, pads):
 | 
			
		||||
        touch1 = TSTriple()
 | 
			
		||||
        touch2 = TSTriple()
 | 
			
		||||
        touch3 = TSTriple()
 | 
			
		||||
        touch4 = TSTriple()
 | 
			
		||||
        self.specials += touch1.get_tristate(pads.t1)
 | 
			
		||||
        self.specials += touch2.get_tristate(pads.t2)
 | 
			
		||||
        self.specials += touch3.get_tristate(pads.t3)
 | 
			
		||||
        self.specials += touch4.get_tristate(pads.t4)
 | 
			
		||||
 | 
			
		||||
        self.o  = CSRStorage(size=4)
 | 
			
		||||
        self.oe = CSRStorage(size=4)
 | 
			
		||||
        self.i  = CSRStatus(size=4)
 | 
			
		||||
 | 
			
		||||
        self.comb += [
 | 
			
		||||
            touch1.o.eq(self.o.storage[0]),
 | 
			
		||||
            touch2.o.eq(self.o.storage[1]),
 | 
			
		||||
            touch3.o.eq(self.o.storage[2]),
 | 
			
		||||
            touch4.o.eq(self.o.storage[3]),
 | 
			
		||||
 | 
			
		||||
            touch1.oe.eq(self.oe.storage[0]),
 | 
			
		||||
            touch2.oe.eq(self.oe.storage[1]),
 | 
			
		||||
            touch3.oe.eq(self.oe.storage[2]),
 | 
			
		||||
            touch4.oe.eq(self.oe.storage[3]),
 | 
			
		||||
 | 
			
		||||
            self.i.status.eq(Cat(touch1.i, touch2.i, touch3.i, touch4.i))
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PicoRVSpi(Module, AutoCSR):
 | 
			
		||||
    def __init__(self, platform, pads, size=2*1024*1024):
 | 
			
		||||
        self.size = size
 | 
			
		||||
 | 
			
		||||
        self.bus = bus = wishbone.Interface()
 | 
			
		||||
 | 
			
		||||
        self.reset = Signal()
 | 
			
		||||
 | 
			
		||||
        self.cfg1 = CSRStorage(size=8)
 | 
			
		||||
        self.cfg2 = CSRStorage(size=8)
 | 
			
		||||
        self.cfg3 = CSRStorage(size=8)
 | 
			
		||||
        self.cfg4 = CSRStorage(size=8)
 | 
			
		||||
 | 
			
		||||
        self.stat1 = CSRStatus(size=8)
 | 
			
		||||
        self.stat2 = CSRStatus(size=8)
 | 
			
		||||
        self.stat3 = CSRStatus(size=8)
 | 
			
		||||
        self.stat4 = CSRStatus(size=8)
 | 
			
		||||
 | 
			
		||||
        cfg = Signal(32)
 | 
			
		||||
        cfg_we = Signal(4)
 | 
			
		||||
        cfg_out = Signal(32)
 | 
			
		||||
        self.comb += [
 | 
			
		||||
            cfg.eq(Cat(self.cfg1.storage, self.cfg2.storage, self.cfg3.storage, self.cfg4.storage)),
 | 
			
		||||
            cfg_we.eq(Cat(self.cfg1.re, self.cfg2.re, self.cfg3.re, self.cfg4.re)),
 | 
			
		||||
            self.stat1.status.eq(cfg_out[0:8]),
 | 
			
		||||
            self.stat2.status.eq(cfg_out[8:16]),
 | 
			
		||||
            self.stat3.status.eq(cfg_out[16:24]),
 | 
			
		||||
            self.stat4.status.eq(cfg_out[24:32]),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        mosi_pad = TSTriple()
 | 
			
		||||
        miso_pad = TSTriple()
 | 
			
		||||
        cs_n_pad = TSTriple()
 | 
			
		||||
        clk_pad  = TSTriple()
 | 
			
		||||
        wp_pad   = TSTriple()
 | 
			
		||||
        hold_pad = TSTriple()
 | 
			
		||||
        self.specials += mosi_pad.get_tristate(pads.mosi)
 | 
			
		||||
        self.specials += miso_pad.get_tristate(pads.miso)
 | 
			
		||||
        self.specials += cs_n_pad.get_tristate(pads.cs_n)
 | 
			
		||||
        self.specials += clk_pad.get_tristate(pads.clk)
 | 
			
		||||
        self.specials += wp_pad.get_tristate(pads.wp)
 | 
			
		||||
        self.specials += hold_pad.get_tristate(pads.hold)
 | 
			
		||||
 | 
			
		||||
        reset = Signal()
 | 
			
		||||
        self.comb += [
 | 
			
		||||
            reset.eq(ResetSignal() | self.reset),
 | 
			
		||||
            cs_n_pad.oe.eq(~reset),
 | 
			
		||||
            clk_pad.oe.eq(~reset),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        flash_addr = Signal(24)
 | 
			
		||||
        mem_bits = bits_for(size)
 | 
			
		||||
        self.comb += flash_addr.eq(bus.adr[0:mem_bits-2] << 2),
 | 
			
		||||
 | 
			
		||||
        read_active = Signal()
 | 
			
		||||
        spi_ready = Signal()
 | 
			
		||||
        self.sync += [
 | 
			
		||||
            If(bus.stb & bus.cyc & ~read_active,
 | 
			
		||||
                read_active.eq(1),
 | 
			
		||||
                bus.ack.eq(0),
 | 
			
		||||
            )
 | 
			
		||||
            .Elif(read_active & spi_ready,
 | 
			
		||||
                read_active.eq(0),
 | 
			
		||||
                bus.ack.eq(1),
 | 
			
		||||
            )
 | 
			
		||||
            .Else(
 | 
			
		||||
                bus.ack.eq(0),
 | 
			
		||||
                read_active.eq(0),
 | 
			
		||||
            )
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        o_rdata = Signal(32)
 | 
			
		||||
        self.comb += bus.dat_r.eq(o_rdata)
 | 
			
		||||
 | 
			
		||||
        self.specials += Instance("spimemio",
 | 
			
		||||
            o_flash_io0_oe = mosi_pad.oe,
 | 
			
		||||
            o_flash_io1_oe = miso_pad.oe,
 | 
			
		||||
            o_flash_io2_oe = wp_pad.oe,
 | 
			
		||||
            o_flash_io3_oe = hold_pad.oe,
 | 
			
		||||
 | 
			
		||||
            o_flash_io0_do = mosi_pad.o,
 | 
			
		||||
            o_flash_io1_do = miso_pad.o,
 | 
			
		||||
            o_flash_io2_do = wp_pad.o,
 | 
			
		||||
            o_flash_io3_do = hold_pad.o,
 | 
			
		||||
            o_flash_csb    = cs_n_pad.o,
 | 
			
		||||
            o_flash_clk    = clk_pad.o,
 | 
			
		||||
 | 
			
		||||
            i_flash_io0_di = mosi_pad.i,
 | 
			
		||||
            i_flash_io1_di = miso_pad.i,
 | 
			
		||||
            i_flash_io2_di = wp_pad.i,
 | 
			
		||||
            i_flash_io3_di = hold_pad.i,
 | 
			
		||||
 | 
			
		||||
            i_resetn = ~reset,
 | 
			
		||||
            i_clk = ClockSignal(),
 | 
			
		||||
 | 
			
		||||
            i_valid = bus.stb & bus.cyc,
 | 
			
		||||
            o_ready = spi_ready,
 | 
			
		||||
            i_addr  = flash_addr,
 | 
			
		||||
            o_rdata = o_rdata,
 | 
			
		||||
 | 
			
		||||
	        i_cfgreg_we = cfg_we,
 | 
			
		||||
            i_cfgreg_di = cfg,
 | 
			
		||||
	        o_cfgreg_do = cfg_out,
 | 
			
		||||
        )
 | 
			
		||||
        platform.add_source("rtl/spimemio.v")
 | 
			
		||||
 | 
			
		||||
class BBSpi(Module, AutoCSR):
 | 
			
		||||
    def __init__(self, platform, pads):
 | 
			
		||||
        self.reset = Signal()
 | 
			
		||||
 | 
			
		||||
        mosi_pad = TSTriple()
 | 
			
		||||
        miso_pad = TSTriple()
 | 
			
		||||
        cs_n_pad = TSTriple()
 | 
			
		||||
        clk_pad  = TSTriple()
 | 
			
		||||
        wp_pad   = TSTriple()
 | 
			
		||||
        hold_pad = TSTriple()
 | 
			
		||||
 | 
			
		||||
        self.do = CSRStorage(size=6)
 | 
			
		||||
        self.oe = CSRStorage(size=6)
 | 
			
		||||
        self.di = CSRStatus(size=6)
 | 
			
		||||
        
 | 
			
		||||
        self.specials += mosi_pad.get_tristate(pads.mosi)
 | 
			
		||||
        self.specials += miso_pad.get_tristate(pads.miso)
 | 
			
		||||
        self.specials += cs_n_pad.get_tristate(pads.cs_n)
 | 
			
		||||
        self.specials += clk_pad.get_tristate(pads.clk)
 | 
			
		||||
        self.specials += wp_pad.get_tristate(pads.wp)
 | 
			
		||||
        self.specials += hold_pad.get_tristate(pads.hold)
 | 
			
		||||
 | 
			
		||||
        self.comb += [
 | 
			
		||||
            mosi_pad.oe.eq(self.oe.storage[0]),
 | 
			
		||||
            miso_pad.oe.eq(self.oe.storage[1]),
 | 
			
		||||
            wp_pad.oe.eq(self.oe.storage[2]),
 | 
			
		||||
            hold_pad.oe.eq(self.oe.storage[3]),
 | 
			
		||||
            clk_pad.oe.eq(self.oe.storage[4]),
 | 
			
		||||
            cs_n_pad.oe.eq(self.oe.storage[5]),
 | 
			
		||||
 | 
			
		||||
            mosi_pad.o.eq(self.do.storage[0]),
 | 
			
		||||
            miso_pad.o.eq(self.do.storage[1]),
 | 
			
		||||
            wp_pad.o.eq(self.do.storage[2]),
 | 
			
		||||
            hold_pad.o.eq(self.do.storage[3]),
 | 
			
		||||
            clk_pad.o.eq(self.do.storage[4]),
 | 
			
		||||
            cs_n_pad.o.eq(self.do.storage[5]),
 | 
			
		||||
 | 
			
		||||
            self.di.status.eq(Cat(mosi_pad.i, miso_pad.i, wp_pad.i, hold_pad.i, clk_pad.i, cs_n_pad.i)),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
class Version(Module, AutoCSR):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        def makeint(i, base=10):
 | 
			
		||||
            try:
 | 
			
		||||
                return int(i, base=base)
 | 
			
		||||
            except:
 | 
			
		||||
                return 0
 | 
			
		||||
        def get_gitver():
 | 
			
		||||
            import subprocess
 | 
			
		||||
            def decode_version(v):
 | 
			
		||||
                version = v.split(".")
 | 
			
		||||
                major = 0
 | 
			
		||||
                minor = 0
 | 
			
		||||
                rev = 0
 | 
			
		||||
                if len(version) >= 3:
 | 
			
		||||
                    rev = makeint(version[2])
 | 
			
		||||
                if len(version) >= 2:
 | 
			
		||||
                    minor = makeint(version[1])
 | 
			
		||||
                if len(version) >= 1:
 | 
			
		||||
                    major = makeint(version[0])
 | 
			
		||||
                return (major, minor, rev)
 | 
			
		||||
            git_rev_cmd = subprocess.Popen(["git", "describe", "--tags", "--dirty=+"],
 | 
			
		||||
                                stdout=subprocess.PIPE,
 | 
			
		||||
                                stderr=subprocess.PIPE)
 | 
			
		||||
            (git_stdout, _) = git_rev_cmd.communicate()
 | 
			
		||||
            if git_rev_cmd.wait() != 0:
 | 
			
		||||
                git_rev_cmd = subprocess.Popen(["git", "rev-parse", "HEAD"],
 | 
			
		||||
                    stdout=subprocess.PIPE,
 | 
			
		||||
                    stderr=subprocess.PIPE)
 | 
			
		||||
                (git_stdout, _) = git_rev_cmd.communicate()
 | 
			
		||||
                if git_rev_cmd.wait() != 0:
 | 
			
		||||
                    print('WARNING: unable to get git version')
 | 
			
		||||
                    return (0, 0, 0, 0, 0, False)
 | 
			
		||||
                return (0, 0, 0, makeint(git_stdout[0:8], 16), 0, False)
 | 
			
		||||
            raw_git_rev = git_stdout.decode().strip()
 | 
			
		||||
 | 
			
		||||
            dirty = False
 | 
			
		||||
            if raw_git_rev[-1] == "+":
 | 
			
		||||
                raw_git_rev = raw_git_rev[:-1]
 | 
			
		||||
                dirty = True
 | 
			
		||||
 | 
			
		||||
            parts = raw_git_rev.split("-")
 | 
			
		||||
            major = 0
 | 
			
		||||
            minor = 0
 | 
			
		||||
            rev = 0
 | 
			
		||||
            gitrev = 0
 | 
			
		||||
            gitextra = 0
 | 
			
		||||
 | 
			
		||||
            if len(parts) >= 3:
 | 
			
		||||
                if parts[0].startswith("v"):
 | 
			
		||||
                    version = parts[0]
 | 
			
		||||
                    if version.startswith("v"):
 | 
			
		||||
                        version = parts[0][1:]
 | 
			
		||||
                    (major, minor, rev) = decode_version(version)
 | 
			
		||||
                gitextra = makeint(parts[1])
 | 
			
		||||
                if parts[2].startswith("g"):
 | 
			
		||||
                    gitrev = makeint(parts[2][1:], base=16)
 | 
			
		||||
            elif len(parts) >= 2:
 | 
			
		||||
                if parts[1].startswith("g"):
 | 
			
		||||
                    gitrev = makeint(parts[1][1:], base=16)
 | 
			
		||||
                version = parts[0]
 | 
			
		||||
                if version.startswith("v"):
 | 
			
		||||
                    version = parts[0][1:]
 | 
			
		||||
                (major, minor, rev) = decode_version(version)
 | 
			
		||||
            elif len(parts) >= 1:
 | 
			
		||||
                version = parts[0]
 | 
			
		||||
                if version.startswith("v"):
 | 
			
		||||
                    version = parts[0][1:]
 | 
			
		||||
                (major, minor, rev) = decode_version(version)
 | 
			
		||||
 | 
			
		||||
            return (major, minor, rev, gitrev, gitextra, dirty)
 | 
			
		||||
 | 
			
		||||
        self.major = CSRStatus(8)
 | 
			
		||||
        self.minor = CSRStatus(8)
 | 
			
		||||
        self.revision = CSRStatus(8)
 | 
			
		||||
        self.gitrev = CSRStatus(32)
 | 
			
		||||
        self.gitextra = CSRStatus(10)
 | 
			
		||||
        self.dirty = CSRStatus(1)
 | 
			
		||||
 | 
			
		||||
        (major, minor, rev, gitrev, gitextra, dirty) = get_gitver()
 | 
			
		||||
        self.comb += [
 | 
			
		||||
            self.major.status.eq(major),
 | 
			
		||||
            self.minor.status.eq(minor),
 | 
			
		||||
            self.revision.status.eq(rev),
 | 
			
		||||
            self.gitrev.status.eq(gitrev),
 | 
			
		||||
            self.gitextra.status.eq(gitextra),
 | 
			
		||||
            self.dirty.status.eq(dirty),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseSoC(SoCCore):
 | 
			
		||||
    SoCCore.csr_map = {
 | 
			
		||||
        "ctrl":           0,  # provided by default (optional)
 | 
			
		||||
        "crg":            1,  # user
 | 
			
		||||
        "uart_phy":       2,  # provided by default (optional)
 | 
			
		||||
        "uart":           3,  # provided by default (optional)
 | 
			
		||||
        "identifier_mem": 4,  # provided by default (optional)
 | 
			
		||||
        "timer0":         5,  # provided by default (optional)
 | 
			
		||||
        "cpu_or_bridge":  8,
 | 
			
		||||
        "usb":            9,
 | 
			
		||||
        "picorvspi":      10,
 | 
			
		||||
        "touch":          11,
 | 
			
		||||
        "reboot":         12,
 | 
			
		||||
        "rgb":            13,
 | 
			
		||||
        "version":        14,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mem_map = {
 | 
			
		||||
        "spiflash": 0x20000000,  # (default shadow @0xa0000000)
 | 
			
		||||
    }
 | 
			
		||||
    mem_map.update(SoCCore.mem_map)
 | 
			
		||||
 | 
			
		||||
    interrupt_map = {
 | 
			
		||||
        "usb": 3,
 | 
			
		||||
    }
 | 
			
		||||
    interrupt_map.update(SoCCore.interrupt_map)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, platform, boot_source="rand",
 | 
			
		||||
                 debug=None, bios_file=None, use_pll=True,
 | 
			
		||||
                 use_dsp=False, placer=None, output_dir="build",
 | 
			
		||||
                 **kwargs):
 | 
			
		||||
        # Disable integrated RAM as we'll add it later
 | 
			
		||||
        self.integrated_sram_size = 0
 | 
			
		||||
 | 
			
		||||
        self.output_dir = output_dir
 | 
			
		||||
 | 
			
		||||
        clk_freq = int(12e6)
 | 
			
		||||
        self.submodules.crg = _CRG(platform, use_pll=use_pll)
 | 
			
		||||
 | 
			
		||||
        SoCCore.__init__(self, platform, clk_freq, integrated_sram_size=0, with_uart=False, **kwargs)
 | 
			
		||||
 | 
			
		||||
        usb_debug = False
 | 
			
		||||
        if debug is not None:
 | 
			
		||||
            if debug == "uart":
 | 
			
		||||
                from litex.soc.cores.uart import UARTWishboneBridge
 | 
			
		||||
                self.submodules.uart_bridge = UARTWishboneBridge(platform.request("serial"), clk_freq, baudrate=115200)
 | 
			
		||||
                self.add_wb_master(self.uart_bridge.wishbone)
 | 
			
		||||
            elif debug == "usb":
 | 
			
		||||
                usb_debug = True
 | 
			
		||||
            if hasattr(self, "cpu"):
 | 
			
		||||
                self.cpu.use_external_variant("rtl/2-stage-1024-cache-debug.v")
 | 
			
		||||
                self.copy_memory_file("2-stage-1024-cache-debug.v_toplevel_RegFilePlugin_regFile.bin")
 | 
			
		||||
                os.path.join(output_dir, "gateware")
 | 
			
		||||
                self.register_mem("vexriscv_debug", 0xf00f0000, self.cpu.debug_bus, 0x10)
 | 
			
		||||
        else:
 | 
			
		||||
            if hasattr(self, "cpu"):
 | 
			
		||||
                self.cpu.use_external_variant("rtl/2-stage-1024-cache.v")
 | 
			
		||||
                self.copy_memory_file("2-stage-1024-cache.v_toplevel_RegFilePlugin_regFile.bin")
 | 
			
		||||
 | 
			
		||||
        # SPRAM- UP5K has single port RAM, might as well use it as SRAM to
 | 
			
		||||
        # free up scarce block RAM.
 | 
			
		||||
        spram_size = 128*1024
 | 
			
		||||
        self.submodules.spram = up5kspram.Up5kSPRAM(size=spram_size)
 | 
			
		||||
        self.register_mem("sram", 0x10000000, self.spram.bus, spram_size)
 | 
			
		||||
 | 
			
		||||
        if boot_source == "rand":
 | 
			
		||||
            kwargs['cpu_reset_address']=0
 | 
			
		||||
            bios_size = 0x2000
 | 
			
		||||
            self.submodules.random_rom = RandomFirmwareROM(bios_size)
 | 
			
		||||
            self.add_constant("ROM_DISABLE", 1)
 | 
			
		||||
            self.register_rom(self.random_rom.bus, bios_size)
 | 
			
		||||
        elif boot_source == "bios":
 | 
			
		||||
            kwargs['cpu_reset_address'] = 0
 | 
			
		||||
            if bios_file is None:
 | 
			
		||||
                self.integrated_rom_size = bios_size = 0x2000
 | 
			
		||||
                self.submodules.rom = wishbone.SRAM(bios_size, read_only=True, init=[])
 | 
			
		||||
                self.register_rom(self.rom.bus, bios_size)
 | 
			
		||||
            else:
 | 
			
		||||
                bios_size = 0x2000
 | 
			
		||||
                self.submodules.firmware_rom = FirmwareROM(bios_size, bios_file)
 | 
			
		||||
                self.add_constant("ROM_DISABLE", 1)
 | 
			
		||||
                self.register_rom(self.firmware_rom.bus, bios_size)
 | 
			
		||||
 | 
			
		||||
        elif boot_source == "spi":
 | 
			
		||||
            bios_size = 0x8000
 | 
			
		||||
            kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size
 | 
			
		||||
            self.add_memory_region("rom", kwargs['cpu_reset_address'], bios_size)
 | 
			
		||||
            self.add_constant("ROM_DISABLE", 1)
 | 
			
		||||
            self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size
 | 
			
		||||
            self.add_memory_region("user_flash",
 | 
			
		||||
                self.flash_boot_address,
 | 
			
		||||
                # Leave a grace area- possible one-by-off bug in add_memory_region?
 | 
			
		||||
                # Possible fix: addr < origin + length - 1
 | 
			
		||||
                platform.spiflash_total_size - (self.flash_boot_address - self.mem_map["spiflash"]) - 0x100)
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError("unrecognized boot_source: {}".format(boot_source))
 | 
			
		||||
 | 
			
		||||
        # Add a simple bit-banged SPI Flash module
 | 
			
		||||
        spi_pads = platform.request("spiflash")
 | 
			
		||||
        self.submodules.picorvspi = PicoRVSpi(platform, spi_pads)
 | 
			
		||||
        self.register_mem("spiflash", self.mem_map["spiflash"],
 | 
			
		||||
            self.picorvspi.bus, size=self.picorvspi.size)
 | 
			
		||||
 | 
			
		||||
        self.submodules.reboot = SBWarmBoot()
 | 
			
		||||
        self.cpu.cpu_params.update(
 | 
			
		||||
            i_externalResetVector=self.reboot.addr.storage,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        self.submodules.rgb = SBLED(platform.request("led"))
 | 
			
		||||
        self.submodules.version = Version()
 | 
			
		||||
 | 
			
		||||
        # Add USB pads
 | 
			
		||||
        usb_pads = platform.request("usb")
 | 
			
		||||
        usb_iobuf = usbio.IoBuf(usb_pads.d_p, usb_pads.d_n, usb_pads.pullup)
 | 
			
		||||
        self.submodules.usb = epfifo.PerEndpointFifoInterface(usb_iobuf, debug=usb_debug)
 | 
			
		||||
        if usb_debug:
 | 
			
		||||
            self.add_wb_master(self.usb.debug_bridge.wishbone)
 | 
			
		||||
        # For the EVT board, ensure the pulldown pin is tristated as an input
 | 
			
		||||
        if hasattr(usb_pads, "pulldown"):
 | 
			
		||||
            pulldown = TSTriple()
 | 
			
		||||
            self.specials += pulldown.get_tristate(usb_pads.pulldown)
 | 
			
		||||
            self.comb += pulldown.oe.eq(0)
 | 
			
		||||
 | 
			
		||||
        # Add GPIO pads for the touch buttons
 | 
			
		||||
        self.submodules.touch = TouchPads(platform.request("touch"))
 | 
			
		||||
 | 
			
		||||
        # Add "-relut -dffe_min_ce_use 4" to the synth_ice40 command.
 | 
			
		||||
        # The "-reult" adds an additional LUT pass to pack more stuff in,
 | 
			
		||||
        # and the "-dffe_min_ce_use 4" flag prevents Yosys from generating a
 | 
			
		||||
        # Clock Enable signal for a LUT that has fewer than 4 flip-flops.
 | 
			
		||||
        # This increases density, and lets us use the FPGA more efficiently.
 | 
			
		||||
        platform.toolchain.nextpnr_yosys_template[2] += " -relut -dffe_min_ce_use 4"
 | 
			
		||||
        if use_dsp:
 | 
			
		||||
            platform.toolchain.nextpnr_yosys_template[2] += " -dsp"
 | 
			
		||||
 | 
			
		||||
        # Disable final deep-sleep power down so firmware words are loaded
 | 
			
		||||
        # onto softcore's address bus.
 | 
			
		||||
        platform.toolchain.build_template[3] = "icepack -s {build_name}.txt {build_name}.bin"
 | 
			
		||||
        platform.toolchain.nextpnr_build_template[2] = "icepack -s {build_name}.txt {build_name}.bin"
 | 
			
		||||
 | 
			
		||||
        if placer is not None:
 | 
			
		||||
            platform.toolchain.nextpnr_build_template[1] += " --placer {}".format(placer)
 | 
			
		||||
 | 
			
		||||
    def copy_memory_file(self, src):
 | 
			
		||||
        import os
 | 
			
		||||
        from shutil import copyfile
 | 
			
		||||
        if not os.path.exists(self.output_dir):
 | 
			
		||||
            os.mkdir(self.output_dir)
 | 
			
		||||
        if not os.path.exists(os.path.join(self.output_dir, "gateware")):
 | 
			
		||||
            os.mkdir(os.path.join(self.output_dir, "gateware"))
 | 
			
		||||
        copyfile(os.path.join("rtl", src), os.path.join(self.output_dir, "gateware", src))
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    parser = argparse.ArgumentParser(
 | 
			
		||||
        description="Build Fomu Main Gateware")
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--boot-source", choices=["spi", "rand", "bios"], default="bios",
 | 
			
		||||
        help="where to have the CPU obtain its executable code from"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--revision", choices=["pvt", "dvt", "evt", "hacker"], required=True,
 | 
			
		||||
        help="build foboot for a particular hardware revision"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--bios", help="use specified file as a BIOS, rather than building one"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--with-debug", help="enable debug support", choices=["usb", "uart", None]
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--no-pll", help="disable pll -- this is easier to route, but may not work", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--with-dsp", help="use dsp inference in yosys (not all yosys builds have -dsp)", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--no-cpu", help="disable cpu generation for debugging purposes", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--placer", choices=["sa", "heap"], help="which placer to use in nextpnr"
 | 
			
		||||
    )
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    output_dir = 'build'
 | 
			
		||||
 | 
			
		||||
    compile_software = False
 | 
			
		||||
    if args.boot_source == "bios" and args.bios is None:
 | 
			
		||||
        compile_software = True
 | 
			
		||||
 | 
			
		||||
    cpu_type = "vexriscv"
 | 
			
		||||
    cpu_variant = "min"
 | 
			
		||||
    if args.with_debug:
 | 
			
		||||
        cpu_variant = "debug"
 | 
			
		||||
 | 
			
		||||
    if args.no_cpu:
 | 
			
		||||
        cpu_type = None
 | 
			
		||||
        cpu_variant = None
 | 
			
		||||
 | 
			
		||||
    os.environ["LITEX"] = "1" # Give our Makefile something to look for
 | 
			
		||||
    platform = Platform(revision=args.revision)
 | 
			
		||||
    soc = BaseSoC(platform, cpu_type=cpu_type, cpu_variant=cpu_variant,
 | 
			
		||||
                            debug=args.with_debug, boot_source=args.boot_source,
 | 
			
		||||
                            bios_file=args.bios, use_pll=not args.no_pll,
 | 
			
		||||
                            use_dsp=args.with_dsp, placer=args.placer,
 | 
			
		||||
                            output_dir=output_dir)
 | 
			
		||||
    builder = Builder(soc, output_dir=output_dir, csr_csv="test/csr.csv", compile_software=compile_software)
 | 
			
		||||
    if compile_software:
 | 
			
		||||
        builder.software_packages = [
 | 
			
		||||
            ("bios", os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "sw")))
 | 
			
		||||
        ]
 | 
			
		||||
    vns = builder.build()
 | 
			
		||||
    soc.do_exit(vns)
 | 
			
		||||
 | 
			
		||||
    print(
 | 
			
		||||
"""Foboot build complete.  Output files:
 | 
			
		||||
    {}/gateware/top.bin             Bitstream file.  Load this onto the FPGA for testing.
 | 
			
		||||
    {}/gateware/top.v               Source Verilog file.  Useful for debugging issues.
 | 
			
		||||
    {}/software/include/generated/  Directory with header files for API access.
 | 
			
		||||
    {}/software/bios/bios.elf       ELF file for debugging bios.
 | 
			
		||||
""".format(output_dir, output_dir, output_dir, output_dir))
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
							
								
								
									
										553
									
								
								hw/lxbuildenv.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										553
									
								
								hw/lxbuildenv.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,553 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
# This script enables easy, cross-platform building without the need
 | 
			
		||||
# to install third-party Python modules.
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
import argparse
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
DEPS_DIR = "deps"
 | 
			
		||||
 | 
			
		||||
DEFAULT_DEPS = {
 | 
			
		||||
    'migen':        'https://github.com/m-labs/migen.git',
 | 
			
		||||
    'litex':        'https://github.com/enjoy-digital/litex.git',
 | 
			
		||||
    'litedram':     'https://github.com/enjoy-digital/litedram.git',
 | 
			
		||||
    'litescope':    'https://github.com/enjoy-digital/litescope.git',
 | 
			
		||||
    'pyserial':     'https://github.com/pyserial/pyserial.git',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OPTIONAL_DEPS = {
 | 
			
		||||
    'liteeth':      'https://github.com/enjoy-digital/liteeth.git',
 | 
			
		||||
    'liteusb':      'https://github.com/enjoy-digital/liteusb.git',
 | 
			
		||||
    'litepcie':     'https://github.com/enjoy-digital/litepcie.git',
 | 
			
		||||
    'litesdcard':   'https://github.com/enjoy-digital/litesdcard.git',
 | 
			
		||||
    'liteiclink':   'https://github.com/enjoy-digital/liteiclink.git',
 | 
			
		||||
    'litevideo':    'https://github.com/enjoy-digital/litevideo.git',
 | 
			
		||||
    'usb':          'https://github.com/pyusb/pyusb.git',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Obtain the path to this script, plus a trailing separator.  This will
 | 
			
		||||
# be used later on to construct various environment variables for paths
 | 
			
		||||
# to a variety of support directories.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(__file__)) + os.path.sep
 | 
			
		||||
 | 
			
		||||
# Look through the specified file for known variables to get the dependency list
 | 
			
		||||
def get_required_dependencies(filename):
 | 
			
		||||
    import ast
 | 
			
		||||
 | 
			
		||||
    # Always check the Python version
 | 
			
		||||
    dependencies = {
 | 
			
		||||
        'python': 1
 | 
			
		||||
    }
 | 
			
		||||
    main_src = ""
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        with open(sys.argv[0], 'r') as f:
 | 
			
		||||
            main_src = f.read()
 | 
			
		||||
        main_ast = ast.parse(main_src, filename=filename)
 | 
			
		||||
    except:
 | 
			
		||||
        return list(dependencies.keys())
 | 
			
		||||
 | 
			
		||||
    # Iterate through the top-level nodes looking for variables named
 | 
			
		||||
    # LX_DEPENDENCIES or LX_DEPENDENCY and get the values that are
 | 
			
		||||
    # assigned to them.
 | 
			
		||||
    for node in ast.iter_child_nodes(main_ast):
 | 
			
		||||
        if isinstance(node, ast.Assign):
 | 
			
		||||
            value = node.value
 | 
			
		||||
            for target in node.targets:
 | 
			
		||||
                if isinstance(target, ast.Name):
 | 
			
		||||
                    if target.id == "LX_DEPENDENCIES" or target.id == "LX_DEPENDENCY":
 | 
			
		||||
                        if isinstance(value, (ast.List, ast.Tuple)):
 | 
			
		||||
                            for elt in value.elts:
 | 
			
		||||
                                if isinstance(elt, ast.Str):
 | 
			
		||||
                                    dependencies[elt.s] = 1
 | 
			
		||||
                        elif isinstance(value, ast.Str):
 | 
			
		||||
                            dependencies[value.s] = 1
 | 
			
		||||
 | 
			
		||||
    # Set up sub-dependencies
 | 
			
		||||
    if 'riscv' in dependencies:
 | 
			
		||||
        dependencies['make'] = 1
 | 
			
		||||
    return list(dependencies.keys())
 | 
			
		||||
 | 
			
		||||
def get_python_path(script_path, args):
 | 
			
		||||
    # Python has no concept of a local dependency path, such as the C `-I``
 | 
			
		||||
    # switch, or the nodejs `node_modules` path, or the rust cargo registry.
 | 
			
		||||
    # Instead, it relies on an environment variable to append to the search
 | 
			
		||||
    # path.
 | 
			
		||||
    # Construct this variable by adding each subdirectory under the `deps/`
 | 
			
		||||
    # directory to the PYTHONPATH environment variable.
 | 
			
		||||
    python_path = []
 | 
			
		||||
    if os.path.isdir(script_path + DEPS_DIR):
 | 
			
		||||
        for dep in os.listdir(script_path + DEPS_DIR):
 | 
			
		||||
            dep = script_path + DEPS_DIR + os.path.sep + dep
 | 
			
		||||
            if os.path.isdir(dep):
 | 
			
		||||
                python_path.append(dep)
 | 
			
		||||
    return python_path
 | 
			
		||||
 | 
			
		||||
def fixup_env(script_path, args):
 | 
			
		||||
    os.environ["PYTHONPATH"] = os.pathsep.join(get_python_path(script_path, 0))
 | 
			
		||||
 | 
			
		||||
    # Set the "LXBUILDENV_REEXEC" variable to prevent the script from continuously
 | 
			
		||||
    # reinvoking itself.
 | 
			
		||||
    os.environ["LXBUILDENV_REEXEC"] = "1"
 | 
			
		||||
 | 
			
		||||
    # Python randomizes the order in which it traverses hashes, and Migen uses
 | 
			
		||||
    # hashes an awful lot when bringing together modules.  As such, the order
 | 
			
		||||
    # in which Migen generates its output Verilog will change with every run,
 | 
			
		||||
    # and the addresses for various modules will change.
 | 
			
		||||
    # Make builds deterministic so that the generated Verilog code won't change
 | 
			
		||||
    # across runs.
 | 
			
		||||
    os.environ["PYTHONHASHSEED"] = "1"
 | 
			
		||||
 | 
			
		||||
    # Some Makefiles are invoked as part of the build process, and those Makefiles
 | 
			
		||||
    # occasionally have calls to Python.  Ensure those Makefiles use the same
 | 
			
		||||
    # interpreter that this script is using.
 | 
			
		||||
    os.environ["PYTHON"] = sys.executable
 | 
			
		||||
 | 
			
		||||
    # Set the environment variable "V" to 1.  This causes Makefiles to print
 | 
			
		||||
    # the commands they run, which makes them easier to debug.
 | 
			
		||||
    if "lx_verbose" in args and args.lx_verbose:
 | 
			
		||||
        os.environ["V"] = "1"
 | 
			
		||||
 | 
			
		||||
    # If the user just wanted to print the environment variables, do that and quit.
 | 
			
		||||
    if args.lx_print_env:
 | 
			
		||||
        print("PYTHONPATH={}".format(os.environ["PYTHONPATH"]))
 | 
			
		||||
        print("PYTHONHASHSEED={}".format(os.environ["PYTHONHASHSEED"]))
 | 
			
		||||
        print("PYTHON={}".format(sys.executable))
 | 
			
		||||
        print("LXBUILDENV_REEXEC={}".format(os.environ["LXBUILDENV_REEXEC"]))
 | 
			
		||||
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
 | 
			
		||||
# Equivalent to the powershell Get-Command, and kinda like `which`
 | 
			
		||||
def get_command(cmd):
 | 
			
		||||
    if os.name == 'nt':
 | 
			
		||||
        path_ext = os.environ["PATHEXT"].split(os.pathsep)
 | 
			
		||||
    else:
 | 
			
		||||
        path_ext = [""]
 | 
			
		||||
    for ext in path_ext:
 | 
			
		||||
        for path in os.environ["PATH"].split(os.pathsep):
 | 
			
		||||
 | 
			
		||||
            if os.path.exists(path + os.path.sep + cmd + ext):
 | 
			
		||||
                return path + os.path.sep + cmd + ext
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
def check_python_version(args):
 | 
			
		||||
    import platform
 | 
			
		||||
    # Litex / Migen require Python 3.5 or newer.  Ensure we're running
 | 
			
		||||
    # under a compatible version of Python.
 | 
			
		||||
    if sys.version_info[:3] < (3, 5):
 | 
			
		||||
        return (False,
 | 
			
		||||
            "python: You need Python 3.5+ (version {} found)".format(sys.version_info[:3]))
 | 
			
		||||
    return (True, "python 3.5+: ok (Python {} found)".format(platform.python_version()))
 | 
			
		||||
 | 
			
		||||
def check_vivado(args):
 | 
			
		||||
    vivado_path = get_command("vivado")
 | 
			
		||||
    if vivado_path == None:
 | 
			
		||||
        # Look for the default Vivado install directory
 | 
			
		||||
        if os.name == 'nt':
 | 
			
		||||
            base_dir = r"C:\Xilinx\Vivado"
 | 
			
		||||
        else:
 | 
			
		||||
            base_dir = "/opt/Xilinx/Vivado"
 | 
			
		||||
        if os.path.exists(base_dir):
 | 
			
		||||
            for file in os.listdir(base_dir):
 | 
			
		||||
                bin_dir = base_dir + os.path.sep + file + os.path.sep + "bin"
 | 
			
		||||
                if os.path.exists(bin_dir + os.path.sep + "vivado"):
 | 
			
		||||
                    os.environ["PATH"] += os.pathsep + bin_dir
 | 
			
		||||
                    vivado_path = bin_dir
 | 
			
		||||
                    break
 | 
			
		||||
    if vivado_path == None:
 | 
			
		||||
        return (False, "toolchain not found in your PATH", "download it from https://www.xilinx.com/support/download.html")
 | 
			
		||||
    return (True, "found at {}".format(vivado_path))
 | 
			
		||||
 | 
			
		||||
def check_cmd(args, cmd, name=None, fix=None):
 | 
			
		||||
    if name is None:
 | 
			
		||||
        name = cmd
 | 
			
		||||
    path = get_command(cmd)
 | 
			
		||||
    if path == None:
 | 
			
		||||
        return (False, name + " not found in your PATH", fix)
 | 
			
		||||
    return (True, "found at {}".format(path))
 | 
			
		||||
 | 
			
		||||
def check_make(args):
 | 
			
		||||
    return check_cmd(args, "make", "GNU Make")
 | 
			
		||||
 | 
			
		||||
def check_riscv(args):
 | 
			
		||||
    riscv64 = check_cmd(args, "riscv64-unknown-elf-gcc", "riscv toolchain", "download it from https://www.sifive.com/boards/")
 | 
			
		||||
    if riscv64[0] == True:
 | 
			
		||||
        return riscv64
 | 
			
		||||
 | 
			
		||||
    riscv32 = check_cmd(args, "riscv32-unknown-elf-gcc", "riscv toolchain", "download it from https://www.sifive.com/boards/")
 | 
			
		||||
    if riscv32[0] == True:
 | 
			
		||||
        return riscv32
 | 
			
		||||
 | 
			
		||||
    return riscv64
 | 
			
		||||
 | 
			
		||||
def check_yosys(args):
 | 
			
		||||
    return check_cmd(args, "yosys")
 | 
			
		||||
 | 
			
		||||
def check_arachne(args):
 | 
			
		||||
    return check_cmd(args, "arachne-pnr")
 | 
			
		||||
 | 
			
		||||
def check_icestorm(args):
 | 
			
		||||
    return check_cmd(args, "icepack") and check_cmd(args, "nextpnr-ice40")
 | 
			
		||||
 | 
			
		||||
dependency_checkers = {
 | 
			
		||||
    'python': check_python_version,
 | 
			
		||||
    'vivado': check_vivado,
 | 
			
		||||
    'make': check_make,
 | 
			
		||||
    'riscv': check_riscv,
 | 
			
		||||
    'yosys': check_yosys,
 | 
			
		||||
    'arachne-pnr': check_arachne,
 | 
			
		||||
    'icestorm': check_icestorm,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Validate that the required dependencies (Vivado, compilers, etc.)
 | 
			
		||||
# have been installed.
 | 
			
		||||
def check_dependencies(args, dependency_list):
 | 
			
		||||
 | 
			
		||||
    dependency_errors = 0
 | 
			
		||||
    for dependency_name in dependency_list:
 | 
			
		||||
        if not dependency_name in dependency_checkers:
 | 
			
		||||
            print('WARNING: Unrecognized dependency "{}"'.format(dependency_name))
 | 
			
		||||
            continue
 | 
			
		||||
        result = dependency_checkers[dependency_name](args)
 | 
			
		||||
        if result[0] == False:
 | 
			
		||||
            if len(result) > 2:
 | 
			
		||||
                print('{}: {} -- {}'.format(dependency_name, result[1], result[2]))
 | 
			
		||||
            else:
 | 
			
		||||
                print('{}: {}'.format(dependency_name, result[1]))
 | 
			
		||||
            dependency_errors = dependency_errors + 1
 | 
			
		||||
 | 
			
		||||
        elif args.lx_check_deps or args.lx_verbose:
 | 
			
		||||
            print('dependency: {}: {}'.format(dependency_name, result[1]))
 | 
			
		||||
    if dependency_errors > 0:
 | 
			
		||||
        if args.lx_ignore_deps:
 | 
			
		||||
            print('{} missing dependencies were found but continuing anyway'.format(dependency_errors))
 | 
			
		||||
        else:
 | 
			
		||||
            raise SystemExit(str(dependency_errors) +
 | 
			
		||||
                             " missing dependencies were found")
 | 
			
		||||
 | 
			
		||||
    if args.lx_check_deps:
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
 | 
			
		||||
# Return True if the given tree needs to be initialized
 | 
			
		||||
def check_module_recursive(root_path, depth, verbose=False, breadcrumbs=[]):
 | 
			
		||||
    if verbose:
 | 
			
		||||
        print('git-dep: checking if "{}" requires updating (depth: {})...'.format(root_path, depth))
 | 
			
		||||
 | 
			
		||||
    # If the directory isn't a valid git repo, initialization is required
 | 
			
		||||
    git_dir_cmd = subprocess.Popen(["git", "rev-parse", "--show-toplevel"],
 | 
			
		||||
                        cwd=root_path,
 | 
			
		||||
                        stdout=subprocess.PIPE,
 | 
			
		||||
                        stderr=subprocess.PIPE)
 | 
			
		||||
    (git_stdout, _) = git_dir_cmd.communicate()
 | 
			
		||||
    if git_dir_cmd.wait() != 0:
 | 
			
		||||
        if verbose:
 | 
			
		||||
            print('git-dep: missing git directory, starting update...')
 | 
			
		||||
        return True
 | 
			
		||||
    git_dir = git_stdout.decode().strip()
 | 
			
		||||
 | 
			
		||||
    if git_dir in breadcrumbs:
 | 
			
		||||
        if verbose:
 | 
			
		||||
            print('git-dep: root path {} is not in git path'.format(root_path))
 | 
			
		||||
        return True
 | 
			
		||||
    breadcrumbs.append(git_dir)
 | 
			
		||||
 | 
			
		||||
    if not os.path.exists(git_dir + os.path.sep + '.git'):
 | 
			
		||||
        if verbose:
 | 
			
		||||
            print('git-dep: .git not found in "{}"'.format(git_dir))
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    # If there are no submodules, no initialization needs to be done
 | 
			
		||||
    if not os.path.isfile(git_dir + os.path.sep + '.gitmodules'):
 | 
			
		||||
        if verbose:
 | 
			
		||||
            print('git-dep: .gitmodules not found in "{}", so not updating'.format(git_dir))
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    # Loop through the gitmodules to check all submodules
 | 
			
		||||
    gitmodules = open(git_dir + os.path.sep + '.gitmodules', 'r')
 | 
			
		||||
    for line in gitmodules:
 | 
			
		||||
        parts = line.split("=", 2)
 | 
			
		||||
        if parts[0].strip() == "path":
 | 
			
		||||
            path = parts[1].strip()
 | 
			
		||||
            if check_module_recursive(git_dir + os.path.sep + path, depth + 1, verbose=verbose, breadcrumbs=breadcrumbs):
 | 
			
		||||
                return True
 | 
			
		||||
    return False
 | 
			
		||||
 | 
			
		||||
# Determine whether we need to invoke "git submodules init --recurse"
 | 
			
		||||
def check_submodules(script_path, args):
 | 
			
		||||
    if check_module_recursive(script_path, 0, verbose=args.lx_verbose):
 | 
			
		||||
        print("Missing submodules -- updating")
 | 
			
		||||
        subprocess.Popen(["git", "submodule", "update",
 | 
			
		||||
                          "--init", "--recursive"], cwd=script_path).wait()
 | 
			
		||||
    elif args.lx_verbose:
 | 
			
		||||
        print("Submodule check: Submodules found")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def lx_git(cmd, *args):
 | 
			
		||||
    import subprocess
 | 
			
		||||
    git_cmd = ["git", cmd]
 | 
			
		||||
    if args is not None:
 | 
			
		||||
        for arg in args:
 | 
			
		||||
            git_cmd = git_cmd + [arg]
 | 
			
		||||
    subprocess.call(git_cmd)
 | 
			
		||||
 | 
			
		||||
def lx_print_deps():
 | 
			
		||||
    print('Known dependencies:')
 | 
			
		||||
    for dep in dependency_checkers.keys():
 | 
			
		||||
        print('    {}'.format(dep))
 | 
			
		||||
    print('To define a dependency, add a variable inside {} at the top level called LX_DEPENDENCIES and assign it a list or tuple.'.format(sys.argv[0]))
 | 
			
		||||
    print('For example:')
 | 
			
		||||
    print('LX_DEPENDENCIES = ("riscv", "vivado")')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def lx_main(args):
 | 
			
		||||
    if args.lx_print_env:
 | 
			
		||||
        fixup_env(script_path, args)
 | 
			
		||||
 | 
			
		||||
    elif args.lx_print_deps:
 | 
			
		||||
        lx_print_deps()
 | 
			
		||||
 | 
			
		||||
    elif args.lx_run is not None:
 | 
			
		||||
        script_name=args.lx_run[0]
 | 
			
		||||
        get_required_dependencies(script_name)
 | 
			
		||||
 | 
			
		||||
        fixup_env(script_path, args)
 | 
			
		||||
        check_submodules(script_path, args)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            sys.exit(subprocess.Popen(
 | 
			
		||||
                [sys.executable] + [script_name] + args.lx_run[1:]).wait())
 | 
			
		||||
        except:
 | 
			
		||||
            sys.exit(1)
 | 
			
		||||
    elif args.init:
 | 
			
		||||
        if args.main is None:
 | 
			
		||||
            main_name = os.getcwd().split(os.path.sep)[-1] + '.py'
 | 
			
		||||
            new_main_name = input('What would you like your main program to be called? [' + main_name + '] ')
 | 
			
		||||
            if new_main_name is not None and new_main_name != "":
 | 
			
		||||
                main_name = new_main_name
 | 
			
		||||
        else:
 | 
			
		||||
            main_name = args.main
 | 
			
		||||
        if not main_name.endswith('.py'):
 | 
			
		||||
            main_name = main_name + '.py'
 | 
			
		||||
 | 
			
		||||
        if args.no_git:
 | 
			
		||||
            print("skipping git initialization")
 | 
			
		||||
        else:
 | 
			
		||||
            if not os.path.exists(DEPS_DIR):
 | 
			
		||||
                os.mkdir(DEPS_DIR)
 | 
			
		||||
 | 
			
		||||
            if not os.path.exists(".git"):
 | 
			
		||||
                print("initializing git repository")
 | 
			
		||||
                lx_git('init')
 | 
			
		||||
            else:
 | 
			
		||||
                print("using existing git repository")
 | 
			
		||||
            lx_git('add', str(__file__))
 | 
			
		||||
 | 
			
		||||
            for dep_name, dep_url in DEFAULT_DEPS.items():
 | 
			
		||||
                dest_path = '{}{}{}'.format(DEPS_DIR, '/', dep_name)
 | 
			
		||||
                if not os.path.exists(dest_path):
 | 
			
		||||
                    lx_git('submodule', 'add', dep_url, dest_path)
 | 
			
		||||
                    lx_git('add', dest_path)
 | 
			
		||||
 | 
			
		||||
            lx_git('submodule', 'update', '--init', '--recursive')
 | 
			
		||||
 | 
			
		||||
        if args.no_bin:
 | 
			
		||||
            print("skipping bin/ initialization")
 | 
			
		||||
        elif os.path.exists("bin"):
 | 
			
		||||
            print("bin/ directory exists -- remove bin/ directory to re-initialize")
 | 
			
		||||
        else:
 | 
			
		||||
            bin_tools = {
 | 
			
		||||
                'mkmscimg':           'litex.soc.software.mkmscimg',
 | 
			
		||||
                'litex_term':         'litex.tools.litex_term',
 | 
			
		||||
                'litex_server':       'litex.tools.litex_server',
 | 
			
		||||
                'litex_sim':          'litex.tools.litex_sim',
 | 
			
		||||
                'litex_read_verilog': 'litex.tools.litex_read_verilog',
 | 
			
		||||
                'litex_simple':       'litex.boards.targets.simple',
 | 
			
		||||
            }
 | 
			
		||||
            bin_template = """#!/usr/bin/env python3
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
# This script lives in the "bin" directory, but uses a helper script in the parent
 | 
			
		||||
# directory.  Obtain the current path so we can get the absolute parent path.
 | 
			
		||||
script_path = os.path.dirname(os.path.realpath(
 | 
			
		||||
    __file__)) + os.path.sep + os.path.pardir + os.path.sep
 | 
			
		||||
sys.path.insert(0, script_path)
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
            print("Creating binaries")
 | 
			
		||||
            os.mkdir("bin")
 | 
			
		||||
            for bin_name, python_module in bin_tools.items():
 | 
			
		||||
                with open('bin' + os.path.sep + bin_name, 'w', newline='\n') as new_bin:
 | 
			
		||||
                    new_bin.write(bin_template)
 | 
			
		||||
                    new_bin.write('from ' + python_module + ' import main\n')
 | 
			
		||||
                    new_bin.write('main()\n')
 | 
			
		||||
                import stat
 | 
			
		||||
                os.chmod('bin' + os.path.sep + bin_name, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
 | 
			
		||||
                if not args.no_git:
 | 
			
		||||
                    lx_git('add', '--chmod=+x', 'bin' + os.path.sep + bin_name)
 | 
			
		||||
 | 
			
		||||
        if os.path.exists(main_name):
 | 
			
		||||
            print("skipping creation of {}: file exists".format(main_name))
 | 
			
		||||
        else:
 | 
			
		||||
            print("creating main program {}".format(main_name))
 | 
			
		||||
            with open(main_name, 'w') as m:
 | 
			
		||||
                program_template = """#!/usr/bin/env python3
 | 
			
		||||
# This variable defines all the external programs that this module
 | 
			
		||||
# relies on.  lxbuildenv reads this variable in order to ensure
 | 
			
		||||
# the build will finish without exiting due to missing third-party
 | 
			
		||||
# programs.
 | 
			
		||||
LX_DEPENDENCIES = ["riscv", "vivado"]
 | 
			
		||||
 | 
			
		||||
# Import lxbuildenv to integrate the deps/ directory
 | 
			
		||||
import lxbuildenv
 | 
			
		||||
 | 
			
		||||
# Disable pylint's E1101, which breaks completely on migen
 | 
			
		||||
#pylint:disable=E1101
 | 
			
		||||
 | 
			
		||||
from migen import *
 | 
			
		||||
from litex.build.xilinx import VivadoProgrammer, XilinxPlatform
 | 
			
		||||
from litex.build.generic_platform import Pins, IOStandard
 | 
			
		||||
from litex.soc.integration import SoCSDRAM
 | 
			
		||||
from litex.soc.integration.builder import Builder
 | 
			
		||||
from litex.soc.integration.soc_core import csr_map_update
 | 
			
		||||
 | 
			
		||||
_io = [
 | 
			
		||||
    ("clk50", 0, Pins("J19"), IOStandard("LVCMOS33")),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
class Platform(XilinxPlatform):
 | 
			
		||||
    def __init__(self, toolchain="vivado", programmer="vivado", part="35"):
 | 
			
		||||
        part = "xc7a" + part + "t-fgg484-2"
 | 
			
		||||
    def create_programmer(self):
 | 
			
		||||
        if self.programmer == "vivado":
 | 
			
		||||
            return VivadoProgrammer(flash_part="n25q128-3.3v-spi-x1_x2_x4")
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError("{} programmer is not supported"
 | 
			
		||||
                             .format(self.programmer))
 | 
			
		||||
 | 
			
		||||
    def do_finalize(self, fragment):
 | 
			
		||||
        XilinxPlatform.do_finalize(self, fragment)
 | 
			
		||||
 | 
			
		||||
class BaseSoC(SoCSDRAM):
 | 
			
		||||
    csr_peripherals = [
 | 
			
		||||
        "ddrphy",
 | 
			
		||||
#        "dna",
 | 
			
		||||
        "xadc",
 | 
			
		||||
        "cpu_or_bridge",
 | 
			
		||||
    ]
 | 
			
		||||
    csr_map_update(SoCSDRAM.csr_map, csr_peripherals)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, platform, **kwargs):
 | 
			
		||||
        clk_freq = int(100e6)
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    platform = Platform()
 | 
			
		||||
    soc = BaseSoC(platform)
 | 
			
		||||
    builder = Builder(soc, output_dir="build", csr_csv="test/csr.csv")
 | 
			
		||||
    vns = builder.build()
 | 
			
		||||
    soc.do_exit(vns)
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
"""
 | 
			
		||||
                m.write(program_template)
 | 
			
		||||
                if not args.no_git:
 | 
			
		||||
                    lx_git("add", main_name)
 | 
			
		||||
    else:
 | 
			
		||||
        return False
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
# For the main command, parse args and hand it off to main()
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    parser = argparse.ArgumentParser(
 | 
			
		||||
        description="Wrap Python code to enable quickstart",
 | 
			
		||||
        add_help=False)
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "-h", "--help", '--lx-help', help="show this help message and exit", action="help"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '-i', '--init', '--lx-init', help='initialize a new project', action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '-m', '--main', '--lx-main', help='name of main project'
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--no-bin', '--lx-no-bin', help="don't create a bin/ directory"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '--no-git', '--lx-no-git', help="Don't create a git repository"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '-e', '--print-env', '--lx-print-env', dest="lx_print_env", help="print environment variable listing for pycharm, vscode, or bash", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '-d', '--print-deps', '--lx-print-deps', dest="lx_print_deps", help="print all possible dependencies and then exit", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--lx-verbose", help="increase verboseness of some processes", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        '-r', '--run', '--lx-run', dest='lx_run', help="run the given script under lxbuildenv", nargs=argparse.REMAINDER
 | 
			
		||||
    )
 | 
			
		||||
    args = parser.parse_args()
 | 
			
		||||
 | 
			
		||||
    if not lx_main(args):
 | 
			
		||||
        parser.print_help()
 | 
			
		||||
 | 
			
		||||
elif not os.path.isfile(sys.argv[0]):
 | 
			
		||||
    print("lxbuildenv doesn't operate while in interactive mode")
 | 
			
		||||
 | 
			
		||||
elif "LXBUILDENV_REEXEC" not in os.environ:
 | 
			
		||||
    parser = argparse.ArgumentParser(
 | 
			
		||||
        description="Wrap Python code to enable quickstart",
 | 
			
		||||
        add_help=False)
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--lx-verbose", help="increase verboseness of some processes", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--lx-print-env", help="print environment variable listing for pycharm, vscode, or bash", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--lx-check-deps", help="check build environment for dependencies such as compiler and fpga tools and then exit", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--lx-print-deps", help="print all possible dependencies and then exit", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--lx-help", action="help"
 | 
			
		||||
    )
 | 
			
		||||
    parser.add_argument(
 | 
			
		||||
        "--lx-ignore-deps", help="try building even if dependencies are missing", action="store_true"
 | 
			
		||||
    )
 | 
			
		||||
    (args, rest) = parser.parse_known_args()
 | 
			
		||||
 | 
			
		||||
    if args.lx_print_deps:
 | 
			
		||||
        lx_print_deps()
 | 
			
		||||
        sys.exit(0)
 | 
			
		||||
 | 
			
		||||
    deps = get_required_dependencies(sys.argv[0])
 | 
			
		||||
 | 
			
		||||
    fixup_env(script_path, args)
 | 
			
		||||
    check_dependencies(args, deps)
 | 
			
		||||
    check_submodules(script_path, args)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        sys.exit(subprocess.Popen(
 | 
			
		||||
            [sys.executable] + [sys.argv[0]] + rest).wait())
 | 
			
		||||
    except:
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
else:
 | 
			
		||||
    # Overwrite the deps directory.
 | 
			
		||||
    # Because we're running with a predefined PYTHONPATH, you'd think that
 | 
			
		||||
    # the DEPS_DIR would be first.
 | 
			
		||||
    # Unfortunately, setuptools causes the sitewide packages to take precedence
 | 
			
		||||
    # over the PYTHONPATH variable.
 | 
			
		||||
    # Work around this bug by inserting paths into the first index.
 | 
			
		||||
    for path in get_python_path(script_path, None):
 | 
			
		||||
        sys.path.insert(0, path)
 | 
			
		||||
							
								
								
									
										3578
									
								
								hw/rtl/2-stage-1024-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3578
									
								
								hw/rtl/2-stage-1024-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5
									
								
								hw/rtl/2-stage-1024-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								hw/rtl/2-stage-1024-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 4}
 | 
			
		||||
iBus: !!vexriscv.BusReport
 | 
			
		||||
  flushInstructions: [4111, 19, 19, 19]
 | 
			
		||||
  info: !!vexriscv.CacheReport {bytePerLine: 32, size: 1024}
 | 
			
		||||
  kind: cached
 | 
			
		||||
							
								
								
									
										3289
									
								
								hw/rtl/2-stage-1024-cache.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3289
									
								
								hw/rtl/2-stage-1024-cache.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4
									
								
								hw/rtl/2-stage-1024-cache.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								hw/rtl/2-stage-1024-cache.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
iBus: !!vexriscv.BusReport
 | 
			
		||||
  flushInstructions: [4111, 19, 19, 19]
 | 
			
		||||
  info: !!vexriscv.CacheReport {bytePerLine: 32, size: 1024}
 | 
			
		||||
  kind: cached
 | 
			
		||||
							
								
								
									
										3578
									
								
								hw/rtl/2-stage-2048-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3578
									
								
								hw/rtl/2-stage-2048-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5
									
								
								hw/rtl/2-stage-2048-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								hw/rtl/2-stage-2048-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 4}
 | 
			
		||||
iBus: !!vexriscv.BusReport
 | 
			
		||||
  flushInstructions: [4111, 19, 19, 19]
 | 
			
		||||
  info: !!vexriscv.CacheReport {bytePerLine: 32, size: 2048}
 | 
			
		||||
  kind: cached
 | 
			
		||||
							
								
								
									
										3297
									
								
								hw/rtl/2-stage-2048-cache.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3297
									
								
								hw/rtl/2-stage-2048-cache.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4
									
								
								hw/rtl/2-stage-2048-cache.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								hw/rtl/2-stage-2048-cache.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
iBus: !!vexriscv.BusReport
 | 
			
		||||
  flushInstructions: [4111, 19, 19, 19]
 | 
			
		||||
  info: !!vexriscv.CacheReport {bytePerLine: 32, size: 2048}
 | 
			
		||||
  kind: cached
 | 
			
		||||
							
								
								
									
										3769
									
								
								hw/rtl/2-stage-512-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3769
									
								
								hw/rtl/2-stage-512-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5
									
								
								hw/rtl/2-stage-512-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								hw/rtl/2-stage-512-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 4}
 | 
			
		||||
iBus: !!vexriscv.BusReport
 | 
			
		||||
  flushInstructions: [16399, 19, 19, 19]
 | 
			
		||||
  info: !!vexriscv.CacheReport {bytePerLine: 32, size: 512}
 | 
			
		||||
  kind: cached
 | 
			
		||||
							
								
								
									
										3499
									
								
								hw/rtl/2-stage-no-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3499
									
								
								hw/rtl/2-stage-no-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								hw/rtl/2-stage-no-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								hw/rtl/2-stage-no-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 4}
 | 
			
		||||
							
								
								
									
										3965
									
								
								hw/rtl/4-stage-1024-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3965
									
								
								hw/rtl/4-stage-1024-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5
									
								
								hw/rtl/4-stage-1024-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								hw/rtl/4-stage-1024-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 4}
 | 
			
		||||
iBus: !!vexriscv.BusReport
 | 
			
		||||
  flushInstructions: [4111, 19, 19, 19]
 | 
			
		||||
  info: !!vexriscv.CacheReport {bytePerLine: 32, size: 1024}
 | 
			
		||||
  kind: cached
 | 
			
		||||
							
								
								
									
										3865
									
								
								hw/rtl/4-stage-no-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3865
									
								
								hw/rtl/4-stage-no-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								hw/rtl/4-stage-no-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								hw/rtl/4-stage-no-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 4}
 | 
			
		||||
							
								
								
									
										3902
									
								
								hw/rtl/5-stage-pipelined-no-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3902
									
								
								hw/rtl/5-stage-pipelined-no-cache-debug.v
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								hw/rtl/5-stage-pipelined-no-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								hw/rtl/5-stage-pipelined-no-cache-debug.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
debug: !!vexriscv.DebugReport {hardwareBreakpointCount: 4}
 | 
			
		||||
							
								
								
									
										579
									
								
								hw/rtl/spimemio.v
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										579
									
								
								hw/rtl/spimemio.v
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,579 @@
 | 
			
		||||
/*
 | 
			
		||||
 *  PicoSoC - A simple example SoC using PicoRV32
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2017  Clifford Wolf <clifford@clifford.at>
 | 
			
		||||
 *
 | 
			
		||||
 *  Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
 *  purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 *  copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module spimemio (
 | 
			
		||||
	input clk, resetn,
 | 
			
		||||
 | 
			
		||||
	input valid,
 | 
			
		||||
	output ready,
 | 
			
		||||
	input [23:0] addr,
 | 
			
		||||
	output reg [31:0] rdata,
 | 
			
		||||
 | 
			
		||||
	output flash_csb,
 | 
			
		||||
	output flash_clk,
 | 
			
		||||
 | 
			
		||||
	output flash_io0_oe,
 | 
			
		||||
	output flash_io1_oe,
 | 
			
		||||
	output flash_io2_oe,
 | 
			
		||||
	output flash_io3_oe,
 | 
			
		||||
 | 
			
		||||
	output flash_io0_do,
 | 
			
		||||
	output flash_io1_do,
 | 
			
		||||
	output flash_io2_do,
 | 
			
		||||
	output flash_io3_do,
 | 
			
		||||
 | 
			
		||||
	input  flash_io0_di,
 | 
			
		||||
	input  flash_io1_di,
 | 
			
		||||
	input  flash_io2_di,
 | 
			
		||||
	input  flash_io3_di,
 | 
			
		||||
 | 
			
		||||
	input   [3:0] cfgreg_we,
 | 
			
		||||
	input  [31:0] cfgreg_di,
 | 
			
		||||
	output [31:0] cfgreg_do
 | 
			
		||||
);
 | 
			
		||||
	reg        xfer_resetn;
 | 
			
		||||
	reg        din_valid;
 | 
			
		||||
	wire       din_ready;
 | 
			
		||||
	reg  [7:0] din_data;
 | 
			
		||||
	reg  [3:0] din_tag;
 | 
			
		||||
	reg        din_cont;
 | 
			
		||||
	reg        din_qspi;
 | 
			
		||||
	reg        din_ddr;
 | 
			
		||||
	reg        din_rd;
 | 
			
		||||
 | 
			
		||||
	wire       dout_valid;
 | 
			
		||||
	wire [7:0] dout_data;
 | 
			
		||||
	wire [3:0] dout_tag;
 | 
			
		||||
 | 
			
		||||
	reg [23:0] buffer;
 | 
			
		||||
 | 
			
		||||
	reg [23:0] rd_addr;
 | 
			
		||||
	reg rd_valid;
 | 
			
		||||
	reg rd_wait;
 | 
			
		||||
	reg rd_inc;
 | 
			
		||||
 | 
			
		||||
	assign ready = valid && (addr == rd_addr) && rd_valid;
 | 
			
		||||
	wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid;
 | 
			
		||||
 | 
			
		||||
	reg softreset;
 | 
			
		||||
 | 
			
		||||
	reg       config_en;      // cfgreg[31]
 | 
			
		||||
	reg       config_ddr;     // cfgreg[22]
 | 
			
		||||
	reg       config_qspi;    // cfgreg[21]
 | 
			
		||||
	reg       config_cont;    // cfgreg[20]
 | 
			
		||||
	reg [3:0] config_dummy;   // cfgreg[19:16]
 | 
			
		||||
	reg [3:0] config_oe;      // cfgreg[11:8]
 | 
			
		||||
	reg       config_csb;     // cfgreg[5]
 | 
			
		||||
	reg       config_clk;     // cfgref[4]
 | 
			
		||||
	reg [3:0] config_do;      // cfgreg[3:0]
 | 
			
		||||
 | 
			
		||||
	assign cfgreg_do[31] = config_en;
 | 
			
		||||
	assign cfgreg_do[30:23] = 0;
 | 
			
		||||
	assign cfgreg_do[22] = config_ddr;
 | 
			
		||||
	assign cfgreg_do[21] = config_qspi;
 | 
			
		||||
	assign cfgreg_do[20] = config_cont;
 | 
			
		||||
	assign cfgreg_do[19:16] = config_dummy;
 | 
			
		||||
	assign cfgreg_do[15:12] = 0;
 | 
			
		||||
	assign cfgreg_do[11:8] = {flash_io3_oe, flash_io2_oe, flash_io1_oe, flash_io0_oe};
 | 
			
		||||
	assign cfgreg_do[7:6] = 0;
 | 
			
		||||
	assign cfgreg_do[5] = flash_csb;
 | 
			
		||||
	assign cfgreg_do[4] = flash_clk;
 | 
			
		||||
	assign cfgreg_do[3:0] = {flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
 | 
			
		||||
 | 
			
		||||
	always @(posedge clk) begin
 | 
			
		||||
		softreset <= !config_en || cfgreg_we;
 | 
			
		||||
		if (!resetn) begin
 | 
			
		||||
			softreset <= 1;
 | 
			
		||||
			config_en <= 1;
 | 
			
		||||
			config_csb <= 0;
 | 
			
		||||
			config_clk <= 0;
 | 
			
		||||
			config_oe <= 0;
 | 
			
		||||
			config_do <= 0;
 | 
			
		||||
			config_ddr <= 0;
 | 
			
		||||
			config_qspi <= 0;
 | 
			
		||||
			config_cont <= 0;
 | 
			
		||||
			config_dummy <= 8;
 | 
			
		||||
		end else begin
 | 
			
		||||
			if (cfgreg_we[0]) begin
 | 
			
		||||
				config_csb <= cfgreg_di[5];
 | 
			
		||||
				config_clk <= cfgreg_di[4];
 | 
			
		||||
				config_do <= cfgreg_di[3:0];
 | 
			
		||||
			end
 | 
			
		||||
			if (cfgreg_we[1]) begin
 | 
			
		||||
				config_oe <= cfgreg_di[11:8];
 | 
			
		||||
			end
 | 
			
		||||
			if (cfgreg_we[2]) begin
 | 
			
		||||
				config_ddr <= cfgreg_di[22];
 | 
			
		||||
				config_qspi <= cfgreg_di[21];
 | 
			
		||||
				config_cont <= cfgreg_di[20];
 | 
			
		||||
				config_dummy <= cfgreg_di[19:16];
 | 
			
		||||
			end
 | 
			
		||||
			if (cfgreg_we[3]) begin
 | 
			
		||||
				config_en <= cfgreg_di[31];
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	wire xfer_csb;
 | 
			
		||||
	wire xfer_clk;
 | 
			
		||||
 | 
			
		||||
	wire xfer_io0_oe;
 | 
			
		||||
	wire xfer_io1_oe;
 | 
			
		||||
	wire xfer_io2_oe;
 | 
			
		||||
	wire xfer_io3_oe;
 | 
			
		||||
 | 
			
		||||
	wire xfer_io0_do;
 | 
			
		||||
	wire xfer_io1_do;
 | 
			
		||||
	wire xfer_io2_do;
 | 
			
		||||
	wire xfer_io3_do;
 | 
			
		||||
 | 
			
		||||
	reg xfer_io0_90;
 | 
			
		||||
	reg xfer_io1_90;
 | 
			
		||||
	reg xfer_io2_90;
 | 
			
		||||
	reg xfer_io3_90;
 | 
			
		||||
 | 
			
		||||
	always @(negedge clk) begin
 | 
			
		||||
		xfer_io0_90 <= xfer_io0_do;
 | 
			
		||||
		xfer_io1_90 <= xfer_io1_do;
 | 
			
		||||
		xfer_io2_90 <= xfer_io2_do;
 | 
			
		||||
		xfer_io3_90 <= xfer_io3_do;
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	assign flash_csb = config_en ? xfer_csb : config_csb;
 | 
			
		||||
	assign flash_clk = config_en ? xfer_clk : config_clk;
 | 
			
		||||
 | 
			
		||||
	assign flash_io0_oe = config_en ? xfer_io0_oe : config_oe[0];
 | 
			
		||||
	assign flash_io1_oe = config_en ? xfer_io1_oe : config_oe[1];
 | 
			
		||||
	assign flash_io2_oe = config_en ? xfer_io2_oe : config_oe[2];
 | 
			
		||||
	assign flash_io3_oe = config_en ? xfer_io3_oe : config_oe[3];
 | 
			
		||||
 | 
			
		||||
	assign flash_io0_do = config_en ? (config_ddr ? xfer_io0_90 : xfer_io0_do) : config_do[0];
 | 
			
		||||
	assign flash_io1_do = config_en ? (config_ddr ? xfer_io1_90 : xfer_io1_do) : config_do[1];
 | 
			
		||||
	assign flash_io2_do = config_en ? (config_ddr ? xfer_io2_90 : xfer_io2_do) : config_do[2];
 | 
			
		||||
	assign flash_io3_do = config_en ? (config_ddr ? xfer_io3_90 : xfer_io3_do) : config_do[3];
 | 
			
		||||
 | 
			
		||||
	wire xfer_dspi = din_ddr && !din_qspi;
 | 
			
		||||
	wire xfer_ddr = din_ddr && din_qspi;
 | 
			
		||||
 | 
			
		||||
	spimemio_xfer xfer (
 | 
			
		||||
		.clk          (clk         ),
 | 
			
		||||
		.resetn       (xfer_resetn ),
 | 
			
		||||
		.din_valid    (din_valid   ),
 | 
			
		||||
		.din_ready    (din_ready   ),
 | 
			
		||||
		.din_data     (din_data    ),
 | 
			
		||||
		.din_tag      (din_tag     ),
 | 
			
		||||
		.din_cont     (din_cont    ),
 | 
			
		||||
		.din_dspi     (xfer_dspi   ),
 | 
			
		||||
		.din_qspi     (din_qspi    ),
 | 
			
		||||
		.din_ddr      (xfer_ddr    ),
 | 
			
		||||
		.din_rd       (din_rd      ),
 | 
			
		||||
		.dout_valid   (dout_valid  ),
 | 
			
		||||
		.dout_data    (dout_data   ),
 | 
			
		||||
		.dout_tag     (dout_tag    ),
 | 
			
		||||
		.flash_csb    (xfer_csb    ),
 | 
			
		||||
		.flash_clk    (xfer_clk    ),
 | 
			
		||||
		.flash_io0_oe (xfer_io0_oe ),
 | 
			
		||||
		.flash_io1_oe (xfer_io1_oe ),
 | 
			
		||||
		.flash_io2_oe (xfer_io2_oe ),
 | 
			
		||||
		.flash_io3_oe (xfer_io3_oe ),
 | 
			
		||||
		.flash_io0_do (xfer_io0_do ),
 | 
			
		||||
		.flash_io1_do (xfer_io1_do ),
 | 
			
		||||
		.flash_io2_do (xfer_io2_do ),
 | 
			
		||||
		.flash_io3_do (xfer_io3_do ),
 | 
			
		||||
		.flash_io0_di (flash_io0_di),
 | 
			
		||||
		.flash_io1_di (flash_io1_di),
 | 
			
		||||
		.flash_io2_di (flash_io2_di),
 | 
			
		||||
		.flash_io3_di (flash_io3_di)
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	reg [3:0] state;
 | 
			
		||||
 | 
			
		||||
	always @(posedge clk) begin
 | 
			
		||||
		xfer_resetn <= 1;
 | 
			
		||||
		din_valid <= 0;
 | 
			
		||||
 | 
			
		||||
		if (!resetn || softreset) begin
 | 
			
		||||
			state <= 0;
 | 
			
		||||
			xfer_resetn <= 0;
 | 
			
		||||
			rd_valid <= 0;
 | 
			
		||||
			din_tag <= 0;
 | 
			
		||||
			din_cont <= 0;
 | 
			
		||||
			din_qspi <= 0;
 | 
			
		||||
			din_ddr <= 0;
 | 
			
		||||
			din_rd <= 0;
 | 
			
		||||
		end else begin
 | 
			
		||||
			if (dout_valid && dout_tag == 1) buffer[ 7: 0] <= dout_data;
 | 
			
		||||
			if (dout_valid && dout_tag == 2) buffer[15: 8] <= dout_data;
 | 
			
		||||
			if (dout_valid && dout_tag == 3) buffer[23:16] <= dout_data;
 | 
			
		||||
			if (dout_valid && dout_tag == 4) begin
 | 
			
		||||
				rdata <= {dout_data, buffer};
 | 
			
		||||
				rd_addr <= rd_inc ? rd_addr + 4 : addr;
 | 
			
		||||
				rd_valid <= 1;
 | 
			
		||||
				rd_wait <= rd_inc;
 | 
			
		||||
				rd_inc <= 1;
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			if (valid)
 | 
			
		||||
				rd_wait <= 0;
 | 
			
		||||
 | 
			
		||||
			case (state)
 | 
			
		||||
				0: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_data <= 8'h ff;
 | 
			
		||||
					din_tag <= 0;
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 1;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				1: begin
 | 
			
		||||
					if (dout_valid) begin
 | 
			
		||||
						xfer_resetn <= 0;
 | 
			
		||||
						state <= 2;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				2: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_data <= 8'h ab;
 | 
			
		||||
					din_tag <= 0;
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 3;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				3: begin
 | 
			
		||||
					if (dout_valid) begin
 | 
			
		||||
						xfer_resetn <= 0;
 | 
			
		||||
						state <= 4;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				4: begin
 | 
			
		||||
					rd_inc <= 0;
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_tag <= 0;
 | 
			
		||||
					case ({config_ddr, config_qspi})
 | 
			
		||||
						2'b11: din_data <= 8'h ED;
 | 
			
		||||
						2'b01: din_data <= 8'h EB;
 | 
			
		||||
						2'b10: din_data <= 8'h BB;
 | 
			
		||||
						2'b00: din_data <= 8'h 03;
 | 
			
		||||
					endcase
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 5;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				5: begin
 | 
			
		||||
					if (valid && !ready) begin
 | 
			
		||||
						din_valid <= 1;
 | 
			
		||||
						din_tag <= 0;
 | 
			
		||||
						din_data <= addr[23:16];
 | 
			
		||||
						din_qspi <= config_qspi;
 | 
			
		||||
						din_ddr <= config_ddr;
 | 
			
		||||
						if (din_ready) begin
 | 
			
		||||
							din_valid <= 0;
 | 
			
		||||
							state <= 6;
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				6: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_tag <= 0;
 | 
			
		||||
					din_data <= addr[15:8];
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 7;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				7: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_tag <= 0;
 | 
			
		||||
					din_data <= addr[7:0];
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						din_data <= 0;
 | 
			
		||||
						state <= config_qspi || config_ddr ? 8 : 9;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				8: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_tag <= 0;
 | 
			
		||||
					din_data <= config_cont ? 8'h A5 : 8'h FF;
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_rd <= 1;
 | 
			
		||||
						din_data <= config_dummy;
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 9;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				9: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_tag <= 1;
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 10;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				10: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_data <= 8'h 00;
 | 
			
		||||
					din_tag <= 2;
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 11;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				11: begin
 | 
			
		||||
					din_valid <= 1;
 | 
			
		||||
					din_tag <= 3;
 | 
			
		||||
					if (din_ready) begin
 | 
			
		||||
						din_valid <= 0;
 | 
			
		||||
						state <= 12;
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				12: begin
 | 
			
		||||
					if (!rd_wait || valid) begin
 | 
			
		||||
						din_valid <= 1;
 | 
			
		||||
						din_tag <= 4;
 | 
			
		||||
						if (din_ready) begin
 | 
			
		||||
							din_valid <= 0;
 | 
			
		||||
							state <= 9;
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			endcase
 | 
			
		||||
 | 
			
		||||
			if (jump) begin
 | 
			
		||||
				rd_inc <= 0;
 | 
			
		||||
				rd_valid <= 0;
 | 
			
		||||
				xfer_resetn <= 0;
 | 
			
		||||
				if (config_cont) begin
 | 
			
		||||
					state <= 5;
 | 
			
		||||
				end else begin
 | 
			
		||||
					state <= 4;
 | 
			
		||||
					din_qspi <= 0;
 | 
			
		||||
					din_ddr <= 0;
 | 
			
		||||
				end
 | 
			
		||||
				din_rd <= 0;
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
module spimemio_xfer (
 | 
			
		||||
	input clk, resetn,
 | 
			
		||||
 | 
			
		||||
	input            din_valid,
 | 
			
		||||
	output           din_ready,
 | 
			
		||||
	input      [7:0] din_data,
 | 
			
		||||
	input      [3:0] din_tag,
 | 
			
		||||
	input            din_cont,
 | 
			
		||||
	input            din_dspi,
 | 
			
		||||
	input            din_qspi,
 | 
			
		||||
	input            din_ddr,
 | 
			
		||||
	input            din_rd,
 | 
			
		||||
 | 
			
		||||
	output           dout_valid,
 | 
			
		||||
	output     [7:0] dout_data,
 | 
			
		||||
	output     [3:0] dout_tag,
 | 
			
		||||
 | 
			
		||||
	output reg flash_csb,
 | 
			
		||||
	output reg flash_clk,
 | 
			
		||||
 | 
			
		||||
	output reg flash_io0_oe,
 | 
			
		||||
	output reg flash_io1_oe,
 | 
			
		||||
	output reg flash_io2_oe,
 | 
			
		||||
	output reg flash_io3_oe,
 | 
			
		||||
 | 
			
		||||
	output reg flash_io0_do,
 | 
			
		||||
	output reg flash_io1_do,
 | 
			
		||||
	output reg flash_io2_do,
 | 
			
		||||
	output reg flash_io3_do,
 | 
			
		||||
 | 
			
		||||
	input      flash_io0_di,
 | 
			
		||||
	input      flash_io1_di,
 | 
			
		||||
	input      flash_io2_di,
 | 
			
		||||
	input      flash_io3_di
 | 
			
		||||
);
 | 
			
		||||
	reg [7:0] obuffer;
 | 
			
		||||
	reg [7:0] ibuffer;
 | 
			
		||||
 | 
			
		||||
	reg [3:0] count;
 | 
			
		||||
	reg [3:0] dummy_count;
 | 
			
		||||
 | 
			
		||||
	reg xfer_cont;
 | 
			
		||||
	reg xfer_dspi;
 | 
			
		||||
	reg xfer_qspi;
 | 
			
		||||
	reg xfer_ddr;
 | 
			
		||||
	reg xfer_ddr_q;
 | 
			
		||||
	reg xfer_rd;
 | 
			
		||||
	reg [3:0] xfer_tag;
 | 
			
		||||
	reg [3:0] xfer_tag_q;
 | 
			
		||||
 | 
			
		||||
	reg [7:0] next_obuffer;
 | 
			
		||||
	reg [7:0] next_ibuffer;
 | 
			
		||||
	reg [3:0] next_count;
 | 
			
		||||
 | 
			
		||||
	reg fetch;
 | 
			
		||||
	reg next_fetch;
 | 
			
		||||
	reg last_fetch;
 | 
			
		||||
 | 
			
		||||
	always @(posedge clk) begin
 | 
			
		||||
		xfer_ddr_q <= xfer_ddr;
 | 
			
		||||
		xfer_tag_q <= xfer_tag;
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	assign din_ready = din_valid && resetn && next_fetch;
 | 
			
		||||
 | 
			
		||||
	assign dout_valid = (xfer_ddr_q ? fetch && !last_fetch : next_fetch && !fetch) && resetn;
 | 
			
		||||
	assign dout_data = ibuffer;
 | 
			
		||||
	assign dout_tag = xfer_tag_q;
 | 
			
		||||
 | 
			
		||||
	always @* begin
 | 
			
		||||
		flash_io0_oe = 0;
 | 
			
		||||
		flash_io1_oe = 0;
 | 
			
		||||
		flash_io2_oe = 0;
 | 
			
		||||
		flash_io3_oe = 0;
 | 
			
		||||
 | 
			
		||||
		flash_io0_do = 0;
 | 
			
		||||
		flash_io1_do = 0;
 | 
			
		||||
		flash_io2_do = 0;
 | 
			
		||||
		flash_io3_do = 0;
 | 
			
		||||
 | 
			
		||||
		next_obuffer = obuffer;
 | 
			
		||||
		next_ibuffer = ibuffer;
 | 
			
		||||
		next_count = count;
 | 
			
		||||
		next_fetch = 0;
 | 
			
		||||
 | 
			
		||||
		if (dummy_count == 0) begin
 | 
			
		||||
			casez ({xfer_ddr, xfer_qspi, xfer_dspi})
 | 
			
		||||
				3'b 000: begin
 | 
			
		||||
					flash_io0_oe = 1;
 | 
			
		||||
					flash_io0_do = obuffer[7];
 | 
			
		||||
 | 
			
		||||
					if (flash_clk) begin
 | 
			
		||||
						next_obuffer = {obuffer[6:0], 1'b 0};
 | 
			
		||||
						next_count = count - |count;
 | 
			
		||||
					end else begin
 | 
			
		||||
						next_ibuffer = {ibuffer[6:0], flash_io1_di};
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					next_fetch = (next_count == 0);
 | 
			
		||||
				end
 | 
			
		||||
				3'b 01?: begin
 | 
			
		||||
					flash_io0_oe = !xfer_rd;
 | 
			
		||||
					flash_io1_oe = !xfer_rd;
 | 
			
		||||
					flash_io2_oe = !xfer_rd;
 | 
			
		||||
					flash_io3_oe = !xfer_rd;
 | 
			
		||||
 | 
			
		||||
					flash_io0_do = obuffer[4];
 | 
			
		||||
					flash_io1_do = obuffer[5];
 | 
			
		||||
					flash_io2_do = obuffer[6];
 | 
			
		||||
					flash_io3_do = obuffer[7];
 | 
			
		||||
 | 
			
		||||
					if (flash_clk) begin
 | 
			
		||||
						next_obuffer = {obuffer[3:0], 4'b 0000};
 | 
			
		||||
						next_count = count - {|count, 2'b00};
 | 
			
		||||
					end else begin
 | 
			
		||||
						next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					next_fetch = (next_count == 0);
 | 
			
		||||
				end
 | 
			
		||||
				3'b 11?: begin
 | 
			
		||||
					flash_io0_oe = !xfer_rd;
 | 
			
		||||
					flash_io1_oe = !xfer_rd;
 | 
			
		||||
					flash_io2_oe = !xfer_rd;
 | 
			
		||||
					flash_io3_oe = !xfer_rd;
 | 
			
		||||
 | 
			
		||||
					flash_io0_do = obuffer[4];
 | 
			
		||||
					flash_io1_do = obuffer[5];
 | 
			
		||||
					flash_io2_do = obuffer[6];
 | 
			
		||||
					flash_io3_do = obuffer[7];
 | 
			
		||||
 | 
			
		||||
					next_obuffer = {obuffer[3:0], 4'b 0000};
 | 
			
		||||
					next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di};
 | 
			
		||||
					next_count = count - {|count, 2'b00};
 | 
			
		||||
 | 
			
		||||
					next_fetch = (next_count == 0);
 | 
			
		||||
				end
 | 
			
		||||
				3'b ??1: begin
 | 
			
		||||
					flash_io0_oe = !xfer_rd;
 | 
			
		||||
					flash_io1_oe = !xfer_rd;
 | 
			
		||||
 | 
			
		||||
					flash_io0_do = obuffer[6];
 | 
			
		||||
					flash_io1_do = obuffer[7];
 | 
			
		||||
 | 
			
		||||
					if (flash_clk) begin
 | 
			
		||||
						next_obuffer = {obuffer[5:0], 2'b 00};
 | 
			
		||||
						next_count = count - {|count, 1'b0};
 | 
			
		||||
					end else begin
 | 
			
		||||
						next_ibuffer = {ibuffer[5:0], flash_io1_di, flash_io0_di};
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					next_fetch = (next_count == 0);
 | 
			
		||||
				end
 | 
			
		||||
			endcase
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	always @(posedge clk) begin
 | 
			
		||||
		if (!resetn) begin
 | 
			
		||||
			fetch <= 1;
 | 
			
		||||
			last_fetch <= 1;
 | 
			
		||||
			flash_csb <= 1;
 | 
			
		||||
			flash_clk <= 0;
 | 
			
		||||
			count <= 0;
 | 
			
		||||
			dummy_count <= 0;
 | 
			
		||||
			xfer_tag <= 0;
 | 
			
		||||
			xfer_cont <= 0;
 | 
			
		||||
			xfer_dspi <= 0;
 | 
			
		||||
			xfer_qspi <= 0;
 | 
			
		||||
			xfer_ddr <= 0;
 | 
			
		||||
			xfer_rd <= 0;
 | 
			
		||||
		end else begin
 | 
			
		||||
			fetch <= next_fetch;
 | 
			
		||||
			last_fetch <= xfer_ddr ? fetch : 1;
 | 
			
		||||
			if (dummy_count) begin
 | 
			
		||||
				flash_clk <= !flash_clk && !flash_csb;
 | 
			
		||||
				dummy_count <= dummy_count - flash_clk;
 | 
			
		||||
			end else
 | 
			
		||||
			if (count) begin
 | 
			
		||||
				flash_clk <= !flash_clk && !flash_csb;
 | 
			
		||||
				obuffer <= next_obuffer;
 | 
			
		||||
				ibuffer <= next_ibuffer;
 | 
			
		||||
				count <= next_count;
 | 
			
		||||
			end
 | 
			
		||||
			if (din_valid && din_ready) begin
 | 
			
		||||
				flash_csb <= 0;
 | 
			
		||||
				flash_clk <= 0;
 | 
			
		||||
 | 
			
		||||
				count <= 8;
 | 
			
		||||
				dummy_count <= din_rd ? din_data : 0;
 | 
			
		||||
				obuffer <= din_data;
 | 
			
		||||
 | 
			
		||||
				xfer_tag <= din_tag;
 | 
			
		||||
				xfer_cont <= din_cont;
 | 
			
		||||
				xfer_dspi <= din_dspi;
 | 
			
		||||
				xfer_qspi <= din_qspi;
 | 
			
		||||
				xfer_ddr <= din_ddr;
 | 
			
		||||
				xfer_rd <= din_rd;
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
endmodule
 | 
			
		||||
		Reference in New Issue
	
	Block a user