Skip to content

Commit

Permalink
interconnect/ahb: Cleanup and document a bit.
Browse files Browse the repository at this point in the history
  • Loading branch information
enjoy-digital committed Aug 1, 2023
1 parent 87e2456 commit bfd4dcd
Showing 1 changed file with 59 additions and 39 deletions.
98 changes: 59 additions & 39 deletions litex/soc/interconnect/ahb.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,87 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2021 Ilia Sergachev <[email protected]>
# Copyright (c) 2023 Florent Kermarrec <[email protected]>
# SPDX-License-Identifier: BSD-2-Clause

"""AHB support for LiteX"""

from enum import IntEnum

from migen import *

from litex.gen import *

# Helpers ------------------------------------------------------------------------------------------

class TransferType(IntEnum):
IDLE = 0
BUSY = 1
"""Defines types of AHB transfers."""
IDLE = 0
BUSY = 1
NONSEQUENTIAL = 2
SEQUENTIAL = 3
SEQUENTIAL = 3

# AHB Interface ------------------------------------------------------------------------------------

class Interface(Record):
adr_width = 32
data_width = 32

"""Sets up the AHB interface signals for master and slave."""
adr_width = 32
data_width = 32
master_signals = [
('addr', adr_width),
('burst', 3),
('mastlock', 1),
('prot', 4),
('size', 3),
('trans', 2),
('wdata', data_width),
('write', 1),
('sel', 1),
("addr", adr_width),
("burst", 3),
("mastlock", 1),
("prot", 4),
("size", 3),
("trans", 2),
("wdata", data_width),
("write", 1),
("sel", 1),
]

slave_signals = [
('rdata', data_width),
('readyout', 1),
('resp', 1),
("rdata", data_width),
("readyout", 1),
("resp", 1),
]

def __init__(self):
Record.__init__(self, set_layout_parameters(self.master_signals + self.slave_signals))

# AHB to Wishbone ---------------------------------------------------------------------------------

class AHB2Wishbone(LiteXModule):
"""
This module converts AHB protocol transactions to the Wishbone protocol.
class AHB2Wishbone(Module):
It takes as input an AHB interface and a Wishbone interface and does the conversion.
"""
def __init__(self, ahb, wishbone):
wb = wishbone
wishbone_adr_shift = log2_int(ahb.data_width // 8)
assert ahb.data_width == wb.data_width
assert ahb.adr_width == wb.adr_width + wishbone_adr_shift
assert ahb.data_width == wishbone.data_width
assert ahb.adr_width == wishbone.adr_width + wishbone_adr_shift

self.comb += [
ahb.resp.eq(wb.err),
]
self.comb += ahb.resp.eq(wishbone.err)

self.submodules.fsm = fsm = FSM()
self.fsm = fsm = FSM()
fsm.act("IDLE",
ahb.readyout.eq(1),
If(ahb.sel & (ahb.size == wishbone_adr_shift) & (ahb.trans == TransferType.NONSEQUENTIAL),
NextValue(wb.adr, ahb.addr[2:]),
NextValue(wb.dat_w, ahb.wdata),
NextValue(wb.we, ahb.write),
NextValue(wb.sel, 2 ** len(wb.sel) - 1),
NextState('ACT'),
If(ahb.sel &
(ahb.size == wishbone_adr_shift) &
(ahb.trans == TransferType.NONSEQUENTIAL),
NextValue(wishbone.adr, ahb.addr[2:]),
NextValue(wishbone.dat_w, ahb.wdata),
NextValue(wishbone.we, ahb.write),
NextValue(wishbone.sel, 2**len(wishbone.sel) - 1),
NextState("ACT"),
)
)
fsm.act("ACT",
wb.stb.eq(1),
wb.cyc.eq(1),
If(wb.ack,
If(~wb.we, NextValue(ahb.rdata, wb.dat_r)),
NextState("IDLE")
wishbone.stb.eq(1),
wishbone.cyc.eq(1),
If(wishbone.ack,
If(~wishbone.we,
NextValue(ahb.rdata, wishbone.dat_r)
),
NextState("IDLE")
)
)

0 comments on commit bfd4dcd

Please sign in to comment.