Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add ICE40HX8K-B-EVN Platform #81

Merged
merged 3 commits into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ jobs:
- stage: Targets
env: C=lm32 P=galatea T="base"

- stage: Targets
env: C=lm32.lite P=ice40_hx8k_b_evn F=stub T="base"

- stage: Targets
env: C=lm32 P=mimasv2 T="base"

Expand Down
57 changes: 57 additions & 0 deletions platforms/ice40_hx8k_b_evn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform
from litex.build.lattice.programmer import IceStormProgrammer


_io = [
("user_led", 0, Pins("B5"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("B4"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("A2"), IOStandard("LVCMOS33")),
("user_led", 3, Pins("A1"), IOStandard("LVCMOS33")),
("user_led", 4, Pins("C5"), IOStandard("LVCMOS33")),
("user_led", 5, Pins("C4"), IOStandard("LVCMOS33")),
("user_led", 6, Pins("B3"), IOStandard("LVCMOS33")),
("user_led", 7, Pins("C3"), IOStandard("LVCMOS33")),

("serial", 0,
Subsignal("rx", Pins("B10")),
Subsignal("tx", Pins("B12"), Misc("PULLUP")),
Subsignal("rts", Pins("B13"), Misc("PULLUP")),
Subsignal("cts", Pins("A15"), Misc("PULLUP")),
Subsignal("dtr", Pins("A16"), Misc("PULLUP")),
Subsignal("dsr", Pins("B14"), Misc("PULLUP")),
Subsignal("dcd", Pins("B15"), Misc("PULLUP")),
IOStandard("LVCMOS33"),
),

("spiflash", 0,
Subsignal("cs_n", Pins("R12"), IOStandard("LVCMOS33")),
Subsignal("clk", Pins("R11"), IOStandard("LVCMOS33")),
Subsignal("mosi", Pins("P12"), IOStandard("LVCMOS33")),
Subsignal("miso", Pins("P11"), IOStandard("LVCMOS33")),
),

("clk12", 0, Pins("J3"), IOStandard("LVCMOS33"))
]


class Platform(LatticePlatform):
default_clk_name = "clk12"
default_clk_period = 83.333

gateware_size = 0x28000

# FIXME: Create a "spi flash module" object in the same way we have SDRAM
spiflash_model = "n25q32"
spiflash_read_dummy_bits = 8
spiflash_clock_div = 2
spiflash_total_size = int((32/8)*1024*1024) # 32Mbit
spiflash_page_size = 256
spiflash_sector_size = 0x10000

def __init__(self):
LatticePlatform.__init__(self, "ice40-hx8k-ct256", _io,
toolchain="icestorm")

def create_programmer(self):
return IceStormProgrammer()
66 changes: 66 additions & 0 deletions targets/ice40_hx8k_b_evn/Makefile.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# ice40_hx8k_b_evn targets

ifneq ($(PLATFORM),ice40_hx8k_b_evn)
$(error "Platform should be ice40_hx8k_b_evn when using this file!?")
endif

# Settings
DEFAULT_TARGET = base
TARGET ?= $(DEFAULT_TARGET)
BAUD ?= 115200

# Image
image-flash-$(PLATFORM):
iceprog $(IMAGE_FILE)

# Gateware
gateware-load-$(PLATFORM):
@echo "ICE40HX8K-B-EVN doesn't support loading, use the flash target instead."
@echo "make gateware-flash"
@false

# As with Mimasv2, if the user asks to flash the gateware only, the BIOS must
# be sent as well (because the BIOS is too big to fit into the bitstream).
GATEWARE_BIOS_FILE = $(TARGET_BUILD_DIR)/image-gateware+bios+none.bin

gateware-flash-$(PLATFORM): $(GATEWARE_BIOS_FILE)
iceprog $(GATEWARE_BIOS_FILE)

# To avoid duplicating the mkimage.py call here, if the user has not
# already built a image-gateware+bios+none.bin, we call make recursively
# to build one here, with the FIRMWARE=none override.
#
ifneq ($(GATEWARE_BIOS_FILE),$(IMAGE_FILE))
$(GATEWARE_BIOS_FILE): $(GATEWARE_FILEBASE).bin $(BIOS_FILE) mkimage.py
FIRMWARE=none make image
endif

# Firmware
firmware-load-$(PLATFORM):
@echo "Unsupported."
@false

firmware-flash-$(PLATFORM):
@echo "ICE40HX8K-B-EVN doesn't support just flashing firmware, use image target instead."
@echo "make image-flash"
@false

firmware-connect-$(PLATFORM):
flterm --port=$(COMM_PORT) --speed=$(BAUD)

firmware-clear-$(PLATFORM):
@echo "FIXME: Unsupported?."
@false

# Bios
bios-flash-$(PLATFORM):
@echo "Unsupported."
@false

# Extra commands
help-$(PLATFORM):
@true

reset-$(PLATFORM):
@echo "Unsupported."
@false
104 changes: 104 additions & 0 deletions targets/ice40_hx8k_b_evn/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import sys
import struct
import os.path
import argparse

from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer

from litex.build.generic_platform import Pins, Subsignal, IOStandard
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *

from gateware import cas
from gateware import spi_flash

from targets.utils import csr_map_update


class _CRG(Module):
def __init__(self, platform):
clk12 = platform.request("clk12")

self.clock_domains.cd_sys = ClockDomain()
self.reset = Signal()

# FIXME: Use PLL, increase system clock to 32 MHz, pending nextpnr
# fixes.
self.comb += self.cd_sys.clk.eq(clk12)

# POR reset logic- POR generated from sys clk, POR logic feeds sys clk
# reset.
self.clock_domains.cd_por = ClockDomain()
reset_delay = Signal(12, reset=4095)
self.comb += [
self.cd_por.clk.eq(self.cd_sys.clk),
self.cd_sys.rst.eq(reset_delay != 0)
]
self.sync.por += \
If(reset_delay != 0,
reset_delay.eq(reset_delay - 1)
)
self.specials += AsyncResetSynchronizer(self.cd_por, self.reset)


class BaseSoC(SoCCore):
csr_peripherals = (
"spiflash",
"cas",
)
csr_map_update(SoCCore.csr_map, csr_peripherals)

mem_map = {
"spiflash": 0x20000000, # (default shadow @0xa0000000)
}
mem_map.update(SoCCore.mem_map)

def __init__(self, platform, **kwargs):
if 'integrated_rom_size' not in kwargs:
kwargs['integrated_rom_size']=0
if 'integrated_sram_size' not in kwargs:
kwargs['integrated_sram_size']=0x2800

# FIXME: Force either lite or minimal variants of CPUs; full is too big.

clk_freq = int(12e6)

kwargs['cpu_reset_address']=self.mem_map["spiflash"]+platform.gateware_size
SoCCore.__init__(self, platform, clk_freq, **kwargs)

self.submodules.crg = _CRG(platform)
self.platform.add_period_constraint(self.crg.cd_sys.clk, 1e9/clk_freq)

# Control and Status
self.submodules.cas = cas.ControlAndStatus(platform, clk_freq)

# SPI flash peripheral
self.submodules.spiflash = spi_flash.SpiFlashSingle(
platform.request("spiflash"),
dummy=platform.spiflash_read_dummy_bits,
div=platform.spiflash_clock_div)
self.add_constant("SPIFLASH_PAGE_SIZE", platform.spiflash_page_size)
self.add_constant("SPIFLASH_SECTOR_SIZE", platform.spiflash_sector_size)
self.register_mem("spiflash", self.mem_map["spiflash"],
self.spiflash.bus, size=platform.spiflash_total_size)

bios_size = 0x8000
self.add_constant("ROM_DISABLE", 1)
self.add_memory_region("rom", kwargs['cpu_reset_address'], bios_size)
self.flash_boot_address = self.mem_map["spiflash"]+platform.gateware_size+bios_size

# We don't have a DRAM, so use the remaining SPI flash for user
# program.
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)

# 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"

SoC = BaseSoC