Skip to content
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
10 changes: 9 additions & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,21 @@ jobs:
with:
submodules: true

- name: Check out chipflow-examples
- name: Check out chipflow-examples ${{ github.head_ref || 'refs/heads/main' }}
uses: actions/checkout@v4
continue-on-error: true
with:
repository: ChipFlow/chipflow-examples
path: chipflow-examples
ref: ${{ github.head_ref || 'refs/heads/main' }}

- name: Check out chipflow-examples main
uses: actions/checkout@v4
if: ${{ failure() && steps.step2.conclusion == 'failure' }} }}
with:
repository: ChipFlow/chipflow-examples
path: chipflow-examples

- name: Set up PDM
uses: pdm-project/setup-pdm@v4
with:
Expand Down
20 changes: 15 additions & 5 deletions chipflow_digital_ip/base/_platform_timer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from amaranth import *
from amaranth.lib import wiring
from amaranth.lib.wiring import In, Out, flipped, connect

from amaranth_soc import csr

from chipflow_lib.platforms import SoftwareDriverSignature


__all__ = ["PlatformTimer"]

Expand Down Expand Up @@ -34,10 +35,19 @@ def __init__(self):

self._bridge = csr.Bridge(regs.as_memory_map())

super().__init__({
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
"irq": Out(unsigned(1)),
})
super().__init__(
SoftwareDriverSignature(
members={
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
"irq": Out(unsigned(1)),
},
component=self,
regs_struct='plat_timer_regs_t',
c_files=['drivers/plat_timer.c'],
h_files=['drivers/plat_timer.h'],
)
)

self.bus.memory_map = self._bridge.bus.memory_map

def elaborate(self, platform):
Expand Down
13 changes: 10 additions & 3 deletions chipflow_digital_ip/base/_soc_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from amaranth_soc import csr

from chipflow_lib.platforms import SoftwareDriverSignature

__all__ = ["SoCID"]

Expand All @@ -31,10 +32,16 @@ def __init__(self, *, type_id=0xbadca77e):
self._soc_version = regs.add("soc_version", self.Register(32), offset=0x4)

self._bridge = csr.Bridge(regs.as_memory_map())
super().__init__(
SoftwareDriverSignature(
members={
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
},
component=self,
regs_struct='soc_id_regs_t',
h_files=['drivers/soc_id.h'])
)

super().__init__({
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
})
self.bus.memory_map = self._bridge.bus.memory_map

def elaborate(self, platform):
Expand Down
14 changes: 14 additions & 0 deletions chipflow_digital_ip/base/drivers/plat_timer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#include "plat_timer.h"

uint64_t plat_timer_read(volatile plat_timer_regs_t *timer) {
uint32_t cnt_lo = timer->cnt_lo;
__asm__ volatile ("" : : : "memory");
return (((uint64_t)timer->cnt_hi) << 32ULL) | cnt_lo;
}

void plat_timer_schedule(volatile plat_timer_regs_t *timer, uint64_t val) {
timer->cmp_lo = val & 0xFFFFFFFFU;
__asm__ volatile ("" : : : "memory");
timer->cmp_hi = (val >> 32U) & 0xFFFFFFFFU;
}
17 changes: 17 additions & 0 deletions chipflow_digital_ip/base/drivers/plat_timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#ifndef PLAT_TIMER_H
#define PLAT_TIMER_H

#include <stdint.h>

typedef struct __attribute__((packed, aligned(4))) {
uint32_t cnt_lo;
uint32_t cnt_hi;
uint32_t cmp_lo;
uint32_t cmp_hi;
} plat_timer_regs_t;

uint64_t plat_timer_read(volatile plat_timer_regs_t *timer);
void plat_timer_schedule(volatile plat_timer_regs_t *timer, uint64_t val);

#endif
12 changes: 12 additions & 0 deletions chipflow_digital_ip/base/drivers/soc_id.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#ifndef SOC_ID_H
#define SOC_ID_H

#include <stdint.h>

typedef struct __attribute__((packed, aligned(4))) {
uint32_t type;
uint32_t version;
} soc_id_regs_t;

#endif
27 changes: 17 additions & 10 deletions chipflow_digital_ip/io/_gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

from amaranth_soc import csr, gpio

from chipflow_lib.platforms import GPIOSignature
from chipflow_lib.platforms import GPIOSignature, SoftwareDriverSignature


__all__ = ["GPIOPeripheral"]

Expand Down Expand Up @@ -38,9 +39,9 @@ class GPIOPeripheral(wiring.Component):
Raises
------
:exc:`TypeError`
If ``pin_count`` is not a positive integer.
:exc:`TypeError`
If ``input_stages`` is not a non-negative integer.
If ``pin_count`` is not an integer.
:exc:`ValueError`
If ``pin_count`` is not in the supported range
"""

def __init__(self, *, pin_count, addr_width=4, data_width=8, input_stages=2):
Expand All @@ -49,18 +50,24 @@ def __init__(self, *, pin_count, addr_width=4, data_width=8, input_stages=2):

if pin_count > 32 or pin_count <= 0:
# TODO: why?
raise ValueError(f"Pin pin_count must be a postive integrer less than 32, not {pin_count}")
raise ValueError(f"Pin pin_count must be a positive integer 32 or less, not {pin_count}")

self._gpio = gpio.Peripheral(pin_count=pin_count,
addr_width=addr_width,
data_width=data_width,
input_stages=input_stages)
super().__init__(
SoftwareDriverSignature(
members={
"bus": In(csr.Signature(addr_width=addr_width, data_width=data_width)),
"pins": Out(GPIOSignature(pin_count)),
"alt_mode": Out(unsigned(pin_count)),
},
component=self,
regs_struct='gpio_regs_t',
h_files=['drivers/gpio.h'])
)

super().__init__({
"bus": In(csr.Signature(addr_width=addr_width, data_width=data_width)),
"pins": Out(GPIOSignature(pin_count)),
"alt_mode": Out(unsigned(pin_count)),
})
self.bus.memory_map = self._gpio.bus.memory_map

def elaborate(self, platform):
Expand Down
20 changes: 15 additions & 5 deletions chipflow_digital_ip/io/_i2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from amaranth.lib.wiring import In, Out, connect, flipped

from amaranth_soc import csr
from chipflow_lib.platforms import I2CSignature
from chipflow_lib.platforms import I2CSignature, SoftwareDriverSignature
from ._glasgow_i2c import I2CInitiator

__all__ = ["I2CPeripheral"]
Expand Down Expand Up @@ -55,10 +55,20 @@ def __init__(self):

self._bridge = csr.Bridge(regs.as_memory_map())

super().__init__({
"i2c_pins": Out(I2CSignature()),
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
})
super().__init__(
SoftwareDriverSignature(
members={
"i2c_pins": Out(I2CSignature()),
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
},
component=self,
regs_struct='i2c_regs_t',
c_files=['drivers/i2c.c'],
h_files=['drivers/i2c.h'],
)

)

self.bus.memory_map = self._bridge.bus.memory_map

def elaborate(self, platform):
Expand Down
20 changes: 15 additions & 5 deletions chipflow_digital_ip/io/_spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
from amaranth.lib.wiring import In, Out, connect, flipped

from amaranth_soc import csr
from chipflow_lib.platforms import SPISignature
from chipflow_lib.platforms import SPISignature, SoftwareDriverSignature


__all__ = ["SPIPeripheral"]


class SPIController(wiring.Component):
def __init__(self):
super().__init__({
Expand Down Expand Up @@ -149,10 +151,18 @@ def __init__(self):

self._bridge = csr.Bridge(regs.as_memory_map())

super().__init__({
"spi_pins": Out(SPISignature()),
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
})
super().__init__(
SoftwareDriverSignature(
members={
"spi_pins": Out(SPISignature()),
"bus": In(csr.Signature(addr_width=regs.addr_width, data_width=regs.data_width)),
},
component=self,
regs_struct='spi_regs_t',
c_files=['drivers/spi.c'],
h_files=['drivers/spi.h'])
)

self.bus.memory_map = self._bridge.bus.memory_map

def elaborate(self, platform):
Expand Down
19 changes: 13 additions & 6 deletions chipflow_digital_ip/io/_uart.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from amaranth_soc import csr
from amaranth_stdio.serial import AsyncSerialRX, AsyncSerialTX

from chipflow_lib.platforms import UARTSignature
from chipflow_lib.platforms import UARTSignature, SoftwareDriverSignature

from . import _rfc_uart

Expand Down Expand Up @@ -117,7 +117,6 @@ def elaborate(self, platform):

return m


class UARTPeripheral(wiring.Component):

"""Wrapper for amaranth_soc RFC UART with PHY and chipflow_lib.IOSignature support
Expand Down Expand Up @@ -149,10 +148,18 @@ def __init__(self, *, addr_width=5, data_width=8, init_divisor=0):
phy_config_init=phy_config_shape.const({"divisor": init_divisor}),
)

super().__init__({
"bus": In(csr.Signature(addr_width=addr_width, data_width=data_width)),
"pins": Out(UARTSignature()),
})
super().__init__(
SoftwareDriverSignature(
members={
"bus": In(csr.Signature(addr_width=addr_width, data_width=data_width)),
"pins": Out(UARTSignature()),
},
component=self,
regs_struct='uart_regs_t',
c_files=['drivers/uart.c'],
h_files=['drivers/uart.h'])
)

self.bus.memory_map = self._uart.bus.memory_map
self._phy = UARTPhy(ports=self.pins, init_divisor=init_divisor)

Expand Down
48 changes: 48 additions & 0 deletions chipflow_digital_ip/io/drivers/gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#ifndef GPIO_H
#define GPIO_H

#include <stdint.h>

typedef struct __attribute__((packed, aligned(2))) {
uint16_t mode;
uint8_t input;
uint8_t output;
uint16_t setclr;
} gpio_regs_t;

typedef enum {
#define _GPIO_PIN(n) \
GPIO_PIN ## n ## _INPUT_ONLY = (0 << 2 * (n)), \
GPIO_PIN ## n ## _PUSH_PULL = (1 << 2 * (n)), \
GPIO_PIN ## n ## _OPEN_DRAIN = (2 << 2 * (n)), \
GPIO_PIN ## n ## _ALTERNATE = (3 << 2 * (n))

_GPIO_PIN(0),
_GPIO_PIN(1),
_GPIO_PIN(2),
_GPIO_PIN(3),
_GPIO_PIN(4),
_GPIO_PIN(5),
_GPIO_PIN(6),
_GPIO_PIN(7),
#undef _GPIO_PIN
} gpio_mode_t;

typedef enum {
#define _GPIO_PIN(n) \
GPIO_PIN ## n ## _SET = (1 << 2 * (n)), \
GPIO_PIN ## n ## _CLEAR = (2 << 2 * (n))

_GPIO_PIN(0),
_GPIO_PIN(1),
_GPIO_PIN(2),
_GPIO_PIN(3),
_GPIO_PIN(4),
_GPIO_PIN(5),
_GPIO_PIN(6),
_GPIO_PIN(7),
#undef _GPIO_PIN
} gpio_setclr_t;

#endif
32 changes: 32 additions & 0 deletions chipflow_digital_ip/io/drivers/i2c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#include "i2c.h"

void i2c_init(volatile i2c_regs_t *i2c, uint32_t divider) {
i2c->divider = divider;
}

void i2c_start(volatile i2c_regs_t *i2c) {
i2c->action = (1<<1);
while (i2c->status & 0x1)
;
}

int i2c_write(volatile i2c_regs_t *i2c, uint8_t data) {
i2c->send_data = data;
while (i2c->status & 0x1)
;
return (i2c->status & 0x2) != 0; // check ACK
}

uint8_t i2c_read(volatile i2c_regs_t *i2c) {
i2c->action = (1<<3);
while (i2c->status & 0x1)
;
return i2c->receive_data;
}

void i2c_stop(volatile i2c_regs_t *i2c) {
i2c->action = (1<<2);
while (i2c->status & 0x1)
;
}
Loading
Loading