gw: get i2c up and running (ish) in simulation

This commit is contained in:
David Lenfesty 2023-03-21 20:09:04 -06:00
parent ea32a00b68
commit f846cc1fab
3 changed files with 59 additions and 10 deletions

View File

@ -5,21 +5,30 @@ extern crate panic_halt;
use core::{arch::asm, ptr::{write, read}};
use embedded_hal::prelude::_embedded_hal_blocking_i2c_Write;
use riscv_rt::entry;
mod eth;
mod i2c;
// use `main` as the entry point of this application
// `main` is not allowed to return
#[entry]
fn main() -> ! {
eth::init();
//unsafe { eth::init(); }
let blink_period = if eth::is_wishbone_correct() {
10_000_000
} else {
500_000
};
//let blink_period = unsafe {
// if eth::is_wishbone_correct() {
// 10_000_000
// } else {
// 500_000
// }
//};
let blink_period = 10_000_000u32;
let mut i2c = i2c::AmlibI2c::new(0x01003000);
let data = [0u8, 2u8];
i2c.write(0xAA, &data).unwrap();
loop {
//eth::tranmsit();

View File

@ -63,7 +63,7 @@ class I2C(Elaboratable):
# Set up CSR bus
addr_width = ceil(log2(64)) # Support up to 64 registers just because
data_width = 32 # 32 bit bus
data_width = 8 # 32 bit bus
self._csr_mux = Multiplexer(addr_width=addr_width, data_width=data_width)
# TODO export the addresses of these somehow
self._csr_mux.add(self.CR)

View File

@ -4,6 +4,9 @@ from amaranth import *
from amaranth.sim import *
from amaranth_boards import colorlight_i9
from amaranth_soc.wishbone import *
from amaranth_soc import csr
from amaranth_soc.csr.wishbone import WishboneCSRBridge
from amaranth.lib.io import pin_layout
from minerva.core import Minerva
@ -38,6 +41,18 @@ def load_firmware_for_mem() -> List[int]:
return out
class I2CPads:
"""Small structure to avoid using record. Unsure what the proper solution is"""
class Pad:
def __init__(self):
self.o = Signal()
self.i = Signal()
self.oe = Signal()
def __init__(self):
self.scl = self.Pad()
self.sda = self.Pad()
class Core(Elaboratable):
def __init__(self, clk25, led_signal, eth_interface):
self.count = Signal(64)
@ -124,12 +139,36 @@ class Core(Elaboratable):
start, _stop, _step = self.decoder.add(self.led)
print(f"LED added at 0x{start:08x}")
m.submodules.uart = uart.UART(10e6)
# TODO how to set addr_width?
# Create CSR bus and connect it to Wishbone
self.csr = csr.Decoder(addr_width=10, data_width=8)
m.submodules.csr = self.csr
print(f"CSR bus added at 0x{start:08x}")
# I2C (connected to DAC for VCO and ADC?)
Signal()
if platform is not None:
i2c_pads = platform.request("i2c")
else:
# TODO this is hacky crap
i2c_pads = I2CPads()
with m.If(i2c_pads.scl.oe):
m.d.comb += i2c_pads.scl.i.eq(0)
with m.Else():
m.d.comb += i2c_pads.scl.i.eq(1)
self.i2c = i2c.I2C(50e6, 100e3, i2c_pads)
m.submodules.i2c = self.i2c
self.csr.add(self.i2c.bus)
self.csr_bridge = WishboneCSRBridge(self.csr.bus, data_width=32, name="CSR")
m.submodules.csr_bridge = self.csr_bridge
# TODO shouldn't have to hard-specify this address
start, _stop, _step = self.decoder.add(self.csr_bridge.wb_bus, addr=0x01003000)
# Ethernet
self.eth = LiteEth(self.eth_interface)
m.submodules.eth = self.eth
start, _stop, _step = self.decoder.add(self.eth, addr=0x02000000)
#start, _stop, _step = self.decoder.add(self.eth, addr=0x02000000)
print(f"LiteETH added at 0x{start:08x}")
# Connect arbiter to decoder
@ -167,7 +206,7 @@ def run_sim():
sim = Simulator(dut)
def proc():
for i in range(1000):
for i in range(10000):
yield Tick()
sim.add_clock(1e-6)
@ -205,5 +244,6 @@ if __name__ == "__main__":
unittest.main(module=mod, argv=[sys.argv[0]])
if args.sim:
print("Running simulation...")
run_sim()