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

Deprecate lambdasoc and update gateware to Amaranth 0.5 #33

Draft
wants to merge 33 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b72db77
repo: delete vendored code
antoinevg Sep 16, 2024
35a61ee
repo: re-organize repository layout
antoinevg Sep 16, 2024
6f36b17
repo: update __init__ files
antoinevg Sep 30, 2024
89d6e4a
cores.usb2: port usb peripheral to amaranth-soc
antoinevg Sep 30, 2024
78a75fe
cores.spiflash: port spiflash peripheral to amaranth-soc
antoinevg Sep 30, 2024
9396f04
core.blockram: port blockram peripheral to amaranth-soc
antoinevg Sep 30, 2024
e8aa81c
core.uart: port uart peripheral to amaranth-soc
antoinevg Sep 30, 2024
296ca2a
core.timer: port timer peripheral to amaranth-soc
antoinevg Sep 30, 2024
326f5d4
core.advertiser: port advertiser peripheral to amaranth-soc
antoinevg Sep 30, 2024
e4b5b65
core.info: port info peripheral to amaranth-soc
antoinevg Sep 30, 2024
4766029
core.ila: port ila peripheral to amaranth-soc
antoinevg Sep 30, 2024
b5a0e55
cpu: add cpu interrupt controller
antoinevg Sep 30, 2024
70926be
cpu: port vexriscv to amaranth-soc
antoinevg Sep 30, 2024
1adcdca
provider: add provider for Cynthion board
antoinevg Sep 30, 2024
fbaa5db
repo: rename luna_soc/generate/ modules
antoinevg Oct 11, 2024
c3a005a
generate: update svd generation for amaranth-soc
antoinevg Oct 11, 2024
bf69a73
provider: fix cynthion uart provider
antoinevg Oct 11, 2024
de33d2d
spiflash: fix bugs preventing bring-up
antoinevg Oct 11, 2024
ee1d2cd
uart: handle tri-state buffer correctly for tx signal
antoinevg Oct 14, 2024
d5fe3d2
repo: move advertiser and info cores to cynthion repo
antoinevg Oct 14, 2024
c768ad8
repo: post-rebase fixes
antoinevg Jan 6, 2025
c6e1373
repo: vendor in latest versions of amaranth_soc and amaranth_stdio
antoinevg Jan 7, 2025
266580f
svd: populate register description field with doc comments
antoinevg Jan 7, 2025
f0b0450
repo: bump luna-usb to next minor version
antoinevg Jan 7, 2025
84f8ce9
generate: move introspection code used by svd to introspect module
antoinevg Jan 15, 2025
8bb246e
generate: update rust linker script generation
antoinevg Jan 16, 2025
a83cb1d
generate: update c header & linker script generation code
antoinevg Jan 17, 2025
ec21665
examples: update hello-c example for luna-soc 0.3
antoinevg Jan 20, 2025
eb6c33a
example: update hello-rust example
antoinevg Jan 21, 2025
7b80eb8
core: add a mode register to the timer peripheral to allow one-shot o…
antoinevg Jan 21, 2025
763023d
examples: small fixes
antoinevg Jan 23, 2025
0741833
usb2: add documentation for irq events
antoinevg Jan 28, 2025
49038b5
repo: various cleanups
antoinevg Jan 30, 2025
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
Empty file added examples/.keep
Empty file.
14 changes: 9 additions & 5 deletions examples/hello-c/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
*/
void print_char(char c)
{
while(!uart_tx_rdy_read());
uart_tx_data_write(c);
while(!uart0_tx_ready_read());
uart0_tx_data_write(c);
}

/**
Expand All @@ -39,17 +39,21 @@ int main(void)
uint8_t led_value = 0b110000;

// Set up our timer to periodically move the LEDs.
timer_en_write(1);
timer_reload_write(0x0C0000);
timer0_reload_write(6000000);
timer0_enable_write(1);

// And blink our LEDs.
while(1) {

// Skip all iterations that aren't our main one...
if (timer_ctr_read()) {
if (timer0_counter_read()) {
continue;
}

// Reset timer...
timer0_enable_write(0);
timer0_enable_write(1);

// ... compute our pattern ...
if (shifting_right) {
led_value >>= 1;
Expand Down
56 changes: 28 additions & 28 deletions examples/hello-c/riscv_application.ld
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,36 @@ ENTRY(_start)

SECTIONS
{
. = ORIGIN(ram);
. = ORIGIN(blockram);

/* Start of day code. */
.init :
{
*(.init) *(.init.*)
} > ram
.text :
{
*(.text) *(.text.*)
} > ram
/* Start of day code. */
.init :
{
*(.init) *(.init.*)
} > blockram
.text :
{
*(.text) *(.text.*)
} > blockram

.rodata :
{
*(.rodata) *(.rodata.*)
} > ram
.sdata :
{
PROVIDE(__global_pointer$ = .);
*(.sdata) *(.sdata.*)
}
.data :
{
*(.data) *(.data.*)
} > ram
.bss :
{
*(.bss) *(.bss.*)
} > ram
.rodata :
{
*(.rodata) *(.rodata.*)
} > blockram
.sdata :
{
PROVIDE(__global_pointer$ = .);
*(.sdata) *(.sdata.*)
}
.data :
{
*(.data) *(.data.*)
} > blockram
.bss :
{
*(.bss) *(.bss.*)
} > blockram

}

PROVIDE(__stack_top = ORIGIN(ram) + LENGTH(ram));
PROVIDE(__stack_top = ORIGIN(blockram) + LENGTH(blockram));
247 changes: 183 additions & 64 deletions examples/hello-c/top.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# This file is part of LUNA.
#
# Copyright (c) 2020 Great Scott Gadgets <[email protected]>
# Copyright (c) 2020-2025 Great Scott Gadgets <[email protected]>
# SPDX-License-Identifier: BSD-3-Clause

import logging
Expand All @@ -11,93 +11,212 @@
from luna import configure_default_logging
from luna.gateware.usb.usb2.device import USBDevice

from amaranth import Elaboratable, Module, Cat
from amaranth.hdl.rec import Record

from luna_soc.gateware.cpu.minerva import Minerva
from luna_soc.gateware.csr import GpioPeripheral, LedPeripheral
from luna_soc.gateware.lunasoc import LunaSoC

import luna_soc
from luna_soc.gateware.cpu import InterruptController, Minerva
from luna_soc.gateware.core import blockram, timer, uart
from luna_soc.gateware.provider import cynthion as provider
from luna_soc.util.readbin import get_mem_data

from amaranth import *
from amaranth.lib import wiring

from amaranth_soc import csr, gpio, wishbone
from amaranth_soc.csr.wishbone import WishboneCSRBridge

CLOCK_FREQUENCIES_MHZ = {
'sync': 60
}

# - HelloSoc ------------------------------------------------------------------

class HelloSoc(Elaboratable):
def __init__(self, clock_frequency):

# create a stand-in for our UART
self.uart_pins = Record([
('rx', [('i', 1)]),
('tx', [('o', 1)])
])

# create our SoC
internal_sram_addr = 0x40000000
internal_sram_size = 32768
self.soc = LunaSoC(
cpu=Minerva(
with_debug = False,
with_icache = True,
icache_nlines = 16,
icache_nwords = 4,
icache_nways = 1,
icache_base = internal_sram_addr,
icache_limit = internal_sram_addr + internal_sram_size,
with_dcache = True,
dcache_nlines = 16,
dcache_nwords = 4,
dcache_nways = 1,
dcache_base = internal_sram_addr,
dcache_limit = internal_sram_addr + internal_sram_size,
with_muldiv = False,
reset_address = internal_sram_addr,
),
clock_frequency=clock_frequency,
class HelloSoc(wiring.Component):
def __init__(self, clock_frequency_hz, domain):
super().__init__({})

self.clock_frequency_hz = clock_frequency_hz
self.domain = domain

# configuration
blockram_base = 0x00000000
blockram_size = 32768

csr_base = 0xf0000000
leds_base = 0x00000000
uart0_base = 0x00000300
timer0_base = 0x00000500

# cpu
self.cpu = Minerva(
with_icache = True,
icache_nlines = 16,
icache_nwords = 4,
icache_nways = 1,
icache_base = blockram_base,
icache_limit = blockram_base + blockram_size,
with_dcache = True,
dcache_nlines = 16,
dcache_nwords = 4,
dcache_nways = 1,
dcache_base = blockram_base,
dcache_limit = blockram_base + blockram_size,
with_muldiv = False,
reset_address = blockram_base,
)

# ... read our firmware binary ...
firmware = get_mem_data("firmware.bin", data_width=32, endianness="little")

# ... add core peripherals: memory, timer, uart ...
self.soc.add_core_peripherals(
uart_pins=self.uart_pins,
internal_sram_addr=internal_sram_addr,
internal_sram_size=internal_sram_size,
internal_sram_init=firmware,
# interrupt controller
self.interrupt_controller = InterruptController(width=len(self.cpu.irq_external))

# bus
self.wb_arbiter = wishbone.Arbiter(
addr_width=30,
data_width=32,
granularity=8,
features={"cti", "bte", "err"}
)
self.wb_decoder = wishbone.Decoder(
addr_width=30,
data_width=32,
granularity=8,
features={"cti", "bte", "err"}
)

# ... read our firmware binary ...
filename = "firmware.bin"
firmware = get_mem_data(filename, data_width=32, endianness="little")
if not firmware:
logging.warning(f"Firmware file '{filename}' could not be located.")
firmware = []

# blockram
self.blockram = blockram.Peripheral(size=blockram_size, init=firmware)
self.wb_decoder.add(self.blockram.bus, addr=blockram_base, name="blockram")

# csr decoder
self.csr_decoder = csr.Decoder(addr_width=28, data_width=8)

# leds
self.led_count = 6
self.leds = gpio.Peripheral(pin_count=self.led_count, addr_width=3, data_width=8)
self.csr_decoder.add(self.leds.bus, addr=leds_base, name="leds")

# uart0
uart_baud_rate = 115200
divisor = int(clock_frequency_hz // uart_baud_rate)
self.uart0 = uart.Peripheral(divisor=divisor)
self.csr_decoder.add(self.uart0.bus, addr=uart0_base, name="uart0")

# timer0
self.timer0 = timer.Peripheral(width=32)
self.csr_decoder.add(self.timer0.bus, addr=timer0_base, name="timer0")
self.interrupt_controller.add(self.timer0, number=0, name="timer0")

# wishbone csr bridge
self.wb_to_csr = WishboneCSRBridge(self.csr_decoder.bus, data_width=32)
self.wb_decoder.add(self.wb_to_csr.wb_bus, addr=csr_base, sparse=False, name="wb_to_csr")

# ... add our LED peripheral, for simple output.
self.leds = LedPeripheral()
self.soc.add_peripheral(self.leds, addr=0xf0001000)

def elaborate(self, platform):
m = Module()
m.submodules.soc = self.soc

# bus
m.submodules += [self.wb_arbiter, self.wb_decoder]
wiring.connect(m, self.wb_arbiter.bus, self.wb_decoder.bus)

# cpu
m.submodules += self.cpu
self.wb_arbiter.add(self.cpu.ibus)
self.wb_arbiter.add(self.cpu.dbus)

# interrupt controller
m.submodules += self.interrupt_controller
m.d.comb += self.cpu.irq_external.eq(self.interrupt_controller.pending)

# blockram
m.submodules += self.blockram

# csr decoder
m.submodules += self.csr_decoder

# leds
led_provider = provider.LEDProvider("led", pin_count=self.led_count)
m.submodules += [led_provider, self.leds]
for n in range(self.led_count):
wiring.connect(m, self.leds.pins[n], led_provider.pins[n])

# uart0
uart0_provider = provider.UARTProvider("uart", 0)
m.submodules += [uart0_provider, self.uart0]
wiring.connect(m, self.uart0.pins, uart0_provider.pins)

# timer0
m.submodules += self.timer0

# wishbone csr bridge
m.submodules += self.wb_to_csr

# wire up the cpu external reset signal
try:
user1_io = platform.request("button_user")
m.d.comb += self.cpu.ext_reset.eq(user1_io.i)
except:
logging.warning("Platform does not support a user button for cpu reset")

return DomainRenamer({
"sync": self.domain,
})(m)


# - module: Top ---------------------------------------------------------------

class Top(Elaboratable):
def __init__(self, clock_frequency_hz, domain="sync"):
self.clock_frequency_hz = clock_frequency_hz
self.domain = domain

self.soc = HelloSoc(clock_frequency_hz=self.clock_frequency_hz, domain=self.domain)

def elaborate(self, platform):
m = Module()

# generate our domain clocks/resets
m.submodules.car = platform.clock_domain_generator(clock_frequencies=CLOCK_FREQUENCIES_MHZ)

# connect up our UART
uart_io = platform.request("uart", 0)
m.d.comb += [
uart_io.tx.o.eq(self.uart_pins.tx),
self.uart_pins.rx.eq(uart_io.rx)
]
if hasattr(uart_io.tx, 'oe'):
m.d.comb += uart_io.tx.oe.eq(~self.soc.uart._phy.tx.rdy),
# add soc to design
m.submodules += self.soc

return m


# - main ----------------------------------------------------------------------

if __name__ == "__main__":
from luna_soc import top_level_cli

design = HelloSoc(clock_frequency=int(60e6))
top_level_cli(design)
from luna import configure_default_logging
from luna.gateware.platform import get_appropriate_platform
from luna_soc import top_level_cli

# configure logging
configure_default_logging()
logging.getLogger().setLevel(logging.DEBUG)

# select platform
platform = get_appropriate_platform()
if platform is None:
logging.error("Failed to identify a supported platform")
sys.exit(1)

# configure domain
domain = "sync"

# configure clock frequency
clock_frequency_hz = int(CLOCK_FREQUENCIES_MHZ[domain] * 1e6)
logging.info(f"Building for {platform} with domain {domain} and clock frequency: {clock_frequency_hz}")

# create design
design = Top(clock_frequency_hz=int(60e6), domain=domain)

# invoke cli
_overrides = {
"debug_verilog": False,
"verbose": False,
}
top_level_cli(design, **_overrides)
Loading