interconnect/wishbone: add minimal UpConverter.

This commit is contained in:
Florent Kermarrec 2020-07-21 19:35:14 +02:00
parent 9fc488bdf6
commit 47ce15b431
2 changed files with 79 additions and 2 deletions

View File

@ -3,6 +3,8 @@
# This file is Copyright (c) 2018 Tim 'mithro' Ansell <me@mith.ro>
# License: BSD
from math import log2
from functools import reduce
from operator import or_
@ -229,7 +231,7 @@ class DownConverter(Module):
"""
def __init__(self, master, slave):
dw_from = len(master.dat_r)
dw_from = len(master.dat_w)
dw_to = len(slave.dat_w)
ratio = dw_from//dw_to
@ -275,6 +277,25 @@ class DownConverter(Module):
self.comb += master.dat_r.eq(Cat(dat_r[dw_to:], slave.dat_r))
self.sync += If(slave.ack | skip, dat_r.eq(master.dat_r))
class UpConverter(Module):
"""UpConverter"""
def __init__(self, master, slave):
dw_from = len(master.dat_w)
dw_to = len(slave.dat_w)
ratio = dw_to//dw_from
# # #
self.comb += master.connect(slave, omit={"adr", "sel", "dat_w", "dat_r"})
cases = {}
for i in range(ratio):
cases[i] = [
slave.adr.eq(master.adr[int(log2(ratio)):]),
slave.sel[i*dw_from//8:(i+1)*dw_from//8].eq(2**(dw_from//8) - 1),
slave.dat_w[i*dw_from:(i+1)*dw_from].eq(master.dat_w),
master.dat_r.eq(slave.dat_r[i*dw_from:(i+1)*dw_from]),
]
self.comb += Case(master.adr[:int(log2(ratio))], cases)
class Converter(Module):
"""Converter
@ -295,7 +316,8 @@ class Converter(Module):
downconverter = DownConverter(master, slave)
self.submodules += downconverter
elif dw_from < dw_to:
raise NotImplementedError
upconverter = UpConverter(master, slave)
self.submodules += upconverter
else:
self.comb += master.connect(slave)

55
test/test_wishbone.py Normal file
View File

@ -0,0 +1,55 @@
# This file is Copyright (c) 2019 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD
import unittest
from migen import *
from litex.soc.interconnect import wishbone
# TestWishbone -------------------------------------------------------------------------------------
class TestWishbone(unittest.TestCase):
def test_upconverter_16_32(self):
def generator(dut):
yield from dut.wb16.write(0x0000, 0x1234)
yield from dut.wb16.write(0x0001, 0x5678)
yield from dut.wb16.write(0x0002, 0xdead)
yield from dut.wb16.write(0x0003, 0xbeef)
self.assertEqual((yield from dut.wb16.read(0x0000)), 0x1234)
self.assertEqual((yield from dut.wb16.read(0x0001)), 0x5678)
self.assertEqual((yield from dut.wb16.read(0x0002)), 0xdead)
self.assertEqual((yield from dut.wb16.read(0x0003)), 0xbeef)
class DUT(Module):
def __init__(self):
self.wb16 = wishbone.Interface(data_width=16)
wb32 = wishbone.Interface(data_width=32)
up_converter = wishbone.UpConverter(self.wb16, wb32)
self.submodules += up_converter
wishbone_mem = wishbone.SRAM(32, bus=wb32)
self.submodules += wishbone_mem
dut = DUT()
run_simulation(dut, generator(dut))
def test_converter_32_64_32(self):
def generator(dut):
yield from dut.wb32.write(0x0000, 0x12345678)
yield from dut.wb32.write(0x0001, 0xdeadbeef)
self.assertEqual((yield from dut.wb32.read(0x0000)), 0x12345678)
self.assertEqual((yield from dut.wb32.read(0x0001)), 0xdeadbeef)
class DUT(Module):
def __init__(self):
self.wb32 = wishbone.Interface(data_width=32)
wb64 = wishbone.Interface(data_width=64)
wb32 = wishbone.Interface(data_width=32)
up_converter = wishbone.UpConverter(self.wb32, wb64)
down_converter = wishbone.DownConverter(wb64, wb32)
self.submodules += up_converter, down_converter
wishbone_mem = wishbone.SRAM(32, bus=wb32)
self.submodules += wishbone_mem
dut = DUT()
run_simulation(dut, generator(dut))