Source code for hwtLib.amba.axi_comp.slave_timeout
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Optional
from hwt.code import If
from hwt.hdl.types.bits import HBits
from hwt.hwIOs.utils import addClkRstn
from hwt.hwParam import HwParam
from hwt.math import log2ceil
from hwt.pyUtils.typingFuture import override
from hwtLib.abstract.busBridge import BusBridge
from hwtLib.amba.constants import RESP_SLVERR
[docs]
class Axi4SlaveTimeout(BusBridge):
"""
Component witch has internal timeout for r/b channel and responds
with the error code if the slave does not respond in specified time
:note: blocks the overlapping transactions, it allows only
a single pending transaction per type
.. hwt-autodoc:: _example_Axi4SlaveTimeout
"""
[docs]
def __init__(self, hwIOCls, hdlName:Optional[str]=None):
self.hwIOCls = hwIOCls
super(Axi4SlaveTimeout, self).__init__(hdlName=hdlName)
@override
def hwConfig(self):
self.TIMEOUT = HwParam(4096)
self.hwIOCls.hwConfig(self)
@override
def hwDeclr(self):
addClkRstn(self)
self.HWIO_CLS = HwParam(self.hwIOCls)
with self._hwParamsShared():
self.s = self.hwIOCls()
self.m = self.hwIOCls()._m()
@override
def hwImpl(self):
timer_t = HBits(log2ceil(self.TIMEOUT - 1))
TIMER_MAX = self.TIMEOUT - 1
m, s = self.s, self.m
s.aw(m.aw)
s.ar(m.ar)
s.w(m.w)
r_pending = self._reg("r_pending", def_val=0)
r_timer = self._reg("timeout_timer_r", timer_t, def_val=TIMER_MAX)
r_id = self._reg("r_id", m.r.id._dtype)
If(r_pending,
r_timer(r_timer - 1),
If(r_timer._eq(0),
r_pending(0)
)
).Elif(m.ar.valid & s.ar.ready,
r_pending(~m.r.valid),
r_timer(TIMER_MAX),
r_id(m.ar.id),
)
r_timeout_case = []
if hasattr(m.r, "last"):
r_timeout_case.append(m.r.last(1))
If(r_pending & r_timer._eq(0),
m.r.valid(1),
m.r.id(r_id),
m.r.data(None),
m.r.resp(RESP_SLVERR),
s.r.ready(1),
*r_timeout_case,
).Else(
m.r(s.r)
)
b_pending = self._reg("b_pending", def_val=0)
# b_timer_rst = self._sig("timeout_timer_b_rst")
b_timer = self._reg("timeout_timer_b", timer_t, def_val=TIMER_MAX)
b_id = self._reg("b_id", m.aw.id._dtype)
If(m.aw.valid & s.aw.ready,
b_id(m.aw.id),
)
If(b_pending,
b_timer(b_timer - 1),
If(b_timer._eq(0),
b_pending(0)
)
).Elif(m.w.valid & s.w.ready & m.w.last,
b_pending(~s.b.valid),
b_timer(TIMER_MAX),
)
If(b_pending & b_timer._eq(0),
m.b.valid(1),
m.b.id(b_id),
m.b.resp(RESP_SLVERR),
s.b.ready(1),
).Else(
m.b(s.b)
)
[docs]
def _example_Axi4SlaveTimeout():
from hwtLib.amba.axi4 import Axi4
m = Axi4SlaveTimeout(Axi4)
return m
if __name__ == "__main__":
from hwt.synth import to_rtl_str
m = _example_Axi4SlaveTimeout()
print(to_rtl_str(m))