Source code for hwtLib.handshaked.ramAsHs

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

from hwt.code import If
from hwt.hdl.constants import DIRECTION
from hwt.hdl.types.defs import BIT
from hwt.hdl.types.struct import HStruct
from hwt.interfaces.agents.universalComposite import UniversalCompositeAgent
from hwt.interfaces.std import Handshaked, BramPort_withoutClk
from hwt.interfaces.utils import addClkRstn
from hwt.serializer.mode import serializeParamsUniq
from hwt.synthesizer.interface import Interface
from hwt.synthesizer.param import Param
from hwt.synthesizer.unit import Unit
from hwtLib.common_nonstd_interfaces.addr_data_hs import AddrDataHs
from hwtSimApi.hdlSimulator import HdlSimulator


[docs]class RamHsR(Interface): """ Handshaked RAM port .. hwt-autodoc:: """ def _config(self): self.ADDR_WIDTH = Param(8) self.DATA_WIDTH = Param(8) def _declr(self): a = self.addr = Handshaked() a.DATA_WIDTH = self.ADDR_WIDTH with self._paramsShared(): self.data = Handshaked(masterDir=DIRECTION.IN)
[docs] def _initSimAgent(self, sim: HdlSimulator): self._ag = UniversalCompositeAgent(sim, self)
[docs]@serializeParamsUniq class RamAsHs(Unit): """ Converter from a single ram port to handshaked interfaces .. hwt-autodoc:: """ def _config(self): BramPort_withoutClk._config(self) def _declr(self): assert self.HAS_R or self.HAS_W addClkRstn(self) with self._paramsShared(): if self.HAS_R: self.r = RamHsR() if self.HAS_W: self.w = AddrDataHs() self.w.HAS_MASK = self.HAS_BE self.ram = BramPort_withoutClk()._m()
[docs] def read_logic(self, r: RamHsR, ram: BramPort_withoutClk): readDataPending = self._reg("readDataPending", def_val=0) readData = self._reg("readData", HStruct((r.data.data._dtype, "data"), (BIT, "vld")), def_val={"vld": 0} ) readDataOverflow = self._reg("readDataOverflow", readData._dtype, def_val={"vld": 0}) rEn = (~readDataOverflow.vld | r.data.rd) & (~readData.vld | r.data.rd) readDataPending(r.addr.vld & rEn) If(readDataPending, If(~readData.vld | r.data.rd, # can store directly to readData register readData.data(ram.dout), readData.vld(1), readDataOverflow.vld(0), ).Else( # need to store to overflow register readDataOverflow.data(ram.dout), readDataOverflow.vld(1), ), ).Else( If(r.data.rd, # pop data from readDataOverflow register readData.data(readDataOverflow.data), readData.vld(readDataOverflow.vld), readDataOverflow.vld(0) ) ) r.addr.rd(rEn) return rEn, readData
def _impl(self): ram = self.ram if self.HAS_R: r = self.r rEn, readData = self.read_logic(r, ram) if self.HAS_W: # read/write w = self.w if self.HAS_BE: ram.be(w.mask) If(rEn & r.addr.vld, ram.we(0), ram.addr(r.addr.data) ).Else( ram.we(1), ram.addr(w.addr) ) wEn = ~rEn | ~r.addr.vld w.rd(wEn) ram.din(w.data) ram.en((rEn & r.addr.vld) | w.vld) r.data.data(readData.data) r.data.vld(readData.vld) else: # read only ram.addr(r.addr.data) ram.en(rEn & r.addr.vld) r.data.data(readData.data) r.data.vld(readData.vld) elif self.HAS_W: # write only w = self.w w.rd(1) if self.HAS_BE: ram.we(w.mask) ram.addr(w.addr) ram.din(w.data) ram.en(w.vld)
if __name__ == "__main__": from hwt.synthesizer.utils import to_rtl_str u = RamAsHs() print(to_rtl_str(u))