Source code for hwtLib.xilinx.ipif.axi4Lite_to_ipif

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from hwt.code import Switch, If, FsmBuilder
from hwt.hdl.types.enum import HEnum
from hwt.interfaces.utils import addClkRstn

from hwtLib.amba.axi4Lite import Axi4Lite
from hwtLib.amba.constants import RESP_SLVERR, RESP_OKAY
from hwtLib.xilinx.ipif.intf import Ipif
from hwtLib.abstract.busBridge import BusBridge


[docs]class Axi4Lite_to_Ipif(BusBridge): """ Bridge from AxiLite interface to IPIF interface .. hwt-autodoc:: """ def _config(self) -> None: Ipif._config(self) def _declr(self) -> None: addClkRstn(self) with self._paramsShared(): self.s = Axi4Lite() self.m = Ipif()._m()
[docs] def handleResp(self): ipif = self.m axi = self.s resp = self._sig("resp", axi.r.resp._dtype) respTmp = self._sig("respTmp", resp._dtype) respReg = self._reg("respReg", resp._dtype) If(ipif.ip2bus_error, resp(RESP_SLVERR) ).Else( resp(RESP_OKAY) ) If(ipif.ip2bus_wrack | ipif.ip2bus_rdack, respReg(resp), respTmp(resp) ).Else( respTmp(respReg) ) axi.r.resp(respTmp) axi.b.resp(respTmp)
[docs] def handleAddr(self, st): st_t = st._dtype ipif = self.m axi = self.s addr = self._reg("addr", axi.aw.addr._dtype) If(st._eq(st_t.idle), If(axi.ar.valid, addr(axi.ar.addr) ).Elif(axi.aw.valid, addr(axi.aw.addr) ) ) ipif.bus2ip_addr(addr)
[docs] def mainFsm(self, dataRegR_vld): ipif = self.m axi = self.s st_t = HEnum("st_t", [ "idle", "write", "write_wait_data", "write_ack", "read", "read_ack" ]) st = FsmBuilder(self, st_t ).Trans(st_t.idle, # ready for new request (axi.ar.valid, st_t.read), (axi.aw.valid, st_t.write_wait_data), ).Trans(st_t.write_wait_data, # has address but needs data from axi (axi.w.valid, st_t.write), ).Trans(st_t.write, # has address and data from axi and writing to ipif (ipif.ip2bus_wrack & axi.b.ready, st_t.idle), (ipif.ip2bus_wrack, st_t.write_ack), ).Trans(st_t.write_ack, # data was writen waiting for write response to axi, (axi.b.ready, st_t.idle) ).Trans(st_t.read, # has address, reading from ipif ((ipif.ip2bus_rdack | dataRegR_vld) & axi.r.ready, st_t.idle), (ipif.ip2bus_rdack, st_t.read_ack), ).Trans(st_t.read_ack, # read from ipif complete, waiting for axi to accept data (axi.r.ready, st_t.idle) ).stateReg return st
def _impl(self) -> None: ipif = self.m axi = self.s r = self._reg dataRegR_vld = r("dataRegR_vld", def_val=0) st = self.mainFsm(dataRegR_vld) st_t = st._dtype self.handleResp() self.handleAddr(st) idle = st._eq(st_t.idle) axi.ar.ready(idle) axi.aw.ready(idle & ~axi.ar.valid) axi.w.ready(st._eq(st_t.write_wait_data)) dataRegR = r("dataR", axi.r.data._dtype) dataRegW = r("dataW", axi.w.data._dtype) strbRegW = r("strbW", axi.w.strb._dtype) If(((st._eq(st_t.idle) & axi.aw.valid & ~axi.ar.valid) | st._eq(st_t.write_wait_data)) & axi.w.valid, dataRegW(axi.w.data), strbRegW(axi.w.strb) ) If(ipif.ip2bus_rdack & ( (idle & axi.ar.valid) | st._eq(st_t.read)), dataRegR(ipif.ip2bus_data), ) If(idle, dataRegR_vld(ipif.ip2bus_rdack), ) If(idle, ipif.bus2ip_be(axi.w.strb) ).Else( ipif.bus2ip_be(strbRegW) ) Switch(st)\ .Case(st_t.read, If(dataRegR_vld, axi.r.data(dataRegR), axi.r.valid(1) ).Else( axi.r.data(ipif.ip2bus_data), axi.r.valid(ipif.ip2bus_rdack) ) ).Case(st_t.read_ack, axi.r.data(dataRegR), axi.r.valid(1), ).Default( axi.r.data(None), axi.r.valid(0) ) Switch(st)\ .Case(st_t.write, axi.b.valid(ipif.ip2bus_wrack) ).Case(st_t.write_ack, axi.b.valid(1) ).Default( axi.b.valid(0) ) ipif.bus2ip_data(dataRegW) ipif.bus2ip_cs(st._eq(st_t.write) | st._eq(st_t.read)) ipif.bus2ip_rnw(st._eq(st_t.read))
if __name__ == "__main__": from hwt.synthesizer.utils import to_rtl_str u = Axi4Lite_to_Ipif() print(to_rtl_str(u))