def _declr(self): assert int( self.DEPTH ) > 0, "FifoAsync is disabled in this case, do not use it entirely" assert isPow2(self.DEPTH), "FifoAsync DEPTH has to be power of 2" # pow 2 because of gray conter counters if int(self.EXPORT_SIZE) or int(self.EXPORT_SPACE): raise NotImplementedError() self.dataIn_clk = Clk() self.dataOut_clk = Clk() self.rst_n = Rst_n() with self._paramsShared(): with self._associated(clk=self.dataIn_clk): self.dataIn = FifoWriter() with self._associated(clk=self.dataOut_clk): self.dataOut = FifoReader()._m() self.pWr = GrayCntr() self.pRd = GrayCntr() self.addrW = log2ceil(self.DEPTH) for cntr in [self.pWr, self.pRd]: cntr.DATA_WIDTH.set(self.addrW)
def _declr(self): assert isPow2(self.DEPTH - 1), ( "DEPTH has to be 2**n + 1" " because fifo has have DEPTH 2**n" " and 1 item is stored on output reg", self.DEPTH) self.dataIn_clk = Clk() self.dataOut_clk = Clk() with self._paramsShared(): with self._associated(clk=self.dataIn_clk): self.dataIn_rst_n = Rst_n() with self._associated(rst=self.dataIn_rst_n): self.dataIn = self.intfCls() with self._associated(clk=self.dataOut_clk): self.dataOut_rst_n = Rst_n() with self._associated(rst=self.dataOut_rst_n): self.dataOut = self.intfCls()._m() f = self.fifo = FifoAsync() f.IN_FREQ = self.IN_FREQ f.OUT_FREQ = self.OUT_FREQ DW = self.dataIn._bit_length() - 2 # 2 for control (valid, ready) f.DATA_WIDTH = DW # because the output register is used as another item storage f.DEPTH = self.DEPTH - 1 f.EXPORT_SIZE = self.EXPORT_SIZE f.EXPORT_SPACE = self.EXPORT_SPACE SIZE_W = log2ceil(self.DEPTH + 1 + 1) if self.EXPORT_SIZE: self.size = VectSignal(SIZE_W, signed=False) if self.EXPORT_SPACE: self.space = VectSignal(SIZE_W, signed=False)
def _declr(self): assert int( self.DEPTH ) > 0, "FifoAsync is disabled in this case, do not use it entirely" assert isPow2( self.DEPTH), f"DEPTH has to be power of 2, is {self.DEPTH:d}" # pow 2 because of gray conter counters if self.EXPORT_SIZE or self.EXPORT_SPACE: raise NotImplementedError() self.dataIn_clk = Clk() self.dataIn_clk.FREQ = self.IN_FREQ self.dataOut_clk = Clk() self.dataOut_clk.FREQ = self.OUT_FREQ with self._paramsShared(): with self._associated(clk=self.dataIn_clk): self.dataIn_rst_n = Rst_n() with self._associated(rst=self.dataIn_rst_n): self.dataIn = FifoWriter() with self._associated(clk=self.dataOut_clk): self.dataOut_rst_n = Rst_n() with self._associated(rst=self.dataOut_rst_n): self.dataOut = FifoReader()._m() self.AW = log2ceil(self.DEPTH)
class AxiBuffCdc(AxiBuff): """ Clock domain crossing with buffers for AXI3/4/Lite and others :note: for DEPTH = 1 CDC register is used, else AsyncFifo .. hwt-autodoc:: _example_AxiBuffCdc """ def _config(self): AxiBuff._config(self) self.ADDR_BUFF_DEPTH += 1 self.DATA_BUFF_DEPTH += 1 self.M_FREQ = Param(int(102e6)) self.S_FREQ = Param(int(102e6)) def _setup_clk_rst_n(self): self.clk.FREQ = self.M_FREQ self.rst_n._make_association(clk=self.clk) self.s._make_association(clk=self.clk, rst=self.rst_n) self.m_clk = Clk() self.m_clk.FREQ = self.S_FREQ self.m_rst_n = Rst_n() self.m_rst_n._make_association(clk=self.m_clk) self.m._make_association(clk=self.m_clk, rst=self.m_rst_n) assert self.ADDR_BUFF_DEPTH == 1 or isPow2(self.ADDR_BUFF_DEPTH - 1), ( self.ADDR_BUFF_DEPTH, "size 2**n + 1 for output reg") assert self.DATA_BUFF_DEPTH == 1 or isPow2(self.DATA_BUFF_DEPTH - 1), ( self.DATA_BUFF_DEPTH, "size 2**n + 1 for output reg") def _declr(self): super(AxiBuffCdc, self)._declr() self._setup_clk_rst_n() def _impl(self): ADDR_DEPTH = self.ADDR_BUFF_DEPTH DATA_DEPTH = self.DATA_BUFF_DEPTH for name, m, s, depth in [("ar", self.s.ar, self.m.ar, ADDR_DEPTH), ("aw", self.s.aw, self.m.aw, ADDR_DEPTH), ("w", self.s.w, self.m.w, DATA_DEPTH)]: i = AxiSBuilder(self, m, name).buff_cdc( items=depth, clk=self.m_clk, rst=self.m_rst_n, ).end s(i) for name, m, s, depth in [("r", self.m.r, self.s.r, DATA_DEPTH), ("b", self.m.b, self.s.b, ADDR_DEPTH)]: i = AxiSBuilder(self, m, name).buff_cdc( items=depth, clk=self.clk, rst=self.rst_n, ).end s(i)
def _declr(self): assert int(self.DEPTH) > 0, "FifoAsync is disabled in this case, do not use it entirely" assert isPow2(self.DEPTH), "FifoAsync DEPTH has to be power of 2" # pow 2 because of gray conter counters if int(self.EXPORT_SIZE) or int(self.EXPORT_SPACE): raise NotImplementedError() self.dataIn_clk = Clk() self.dataOut_clk = Clk() self.rst_n = Rst_n() with self._paramsShared(): with self._associated(clk=self.dataIn_clk): self.dataIn = FifoWriter() with self._associated(clk=self.dataOut_clk): self.dataOut = FifoReader()._m() self.pWr = GrayCntr() self.pRd = GrayCntr() self.addrW = log2ceil(self.DEPTH) for cntr in [self.pWr, self.pRd]: cntr.DATA_WIDTH.set(self.addrW)
def _declr(self): self.dataIn_clk = Clk() self.dataIn_clk.FREQ = self.IN_FREQ self.dataOut_clk = Clk() self.dataOut_clk.FREQ = self.OUT_FREQ with self._paramsShared(): with self._associated(clk=self.dataIn_clk): self.dataIn_rst_n = Rst_n() with self._associated(rst=self.dataIn_rst_n): self.dataIn = AxiStreamFullDuplex() with self._associated(clk=self.dataOut_clk): self.dataOut_rst_n = Rst_n() with self._associated(rst=self.dataOut_rst_n): self.dataOut = AxiStreamFullDuplex()._m()
def _setup_clk_rst_n(self): self.clk.FREQ = self.M_FREQ self.rst_n._make_association(clk=self.clk) self.s._make_association(clk=self.clk, rst=self.rst_n) self.m_clk = Clk() self.m_clk.FREQ = self.S_FREQ self.m_rst_n = Rst_n() self.m_rst_n._make_association(clk=self.m_clk) self.m._make_association(clk=self.m_clk, rst=self.m_rst_n) assert self.ADDR_BUFF_DEPTH == 1 or isPow2(self.ADDR_BUFF_DEPTH - 1), ( self.ADDR_BUFF_DEPTH, "size 2**n + 1 for output reg") assert self.DATA_BUFF_DEPTH == 1 or isPow2(self.DATA_BUFF_DEPTH - 1), ( self.DATA_BUFF_DEPTH, "size 2**n + 1 for output reg")
def _declr(self): I_CLS = self.intfCls self.dataIn_clk = Clk() self.dataIn_clk.FREQ = self.IN_FREQ with self._associated(self.dataIn_clk): self.dataIn_rst_n = Rst_n() self.dataOut_clk = Clk() self.dataOut_clk.FREQ = self.OUT_FREQ with self._associated(self.dataOut_clk): self.dataOut_rst_n = Rst_n() with self._paramsShared(): with self._associated(self.dataIn_clk, self.dataIn_rst_n): self.dataIn = I_CLS() with self._associated(self.dataOut_clk, self.dataOut_rst_n): self.dataOut = I_CLS()._m()
def _declr(self): addClkRstn(self) with self._paramsShared(): self.s = Axi4Lite() self.din0 = Handshaked() self.dout0 = Handshaked()._m() self.reg = HandshakedReg(Handshaked) self.din1 = Handshaked() self.dout1 = Handshaked()._m() self.other_clk = Clk() self.other_clk.FREQ = self.clk.FREQ * 2 with self._associated(clk=self.other_clk): self.other_rst_n = Rst_n() self.din2 = Handshaked() self.dout2 = Handshaked()._m()
def _declr(self): self.dataIn_clk = Clk() self.dataOut_clk = Clk() self.rst_n = Rst_n() with self._paramsShared(): with self._associated(self.dataIn_clk): self.dataIn = self.intfCls() with self._associated(self.dataOut_clk): self.dataOut = self.intfCls()._m() f = self.fifo = FifoAsync() DW = self.dataIn._bit_length() - 2 # 2 for control (valid, ready) f.DATA_WIDTH.set(DW) f.DEPTH.set(self.DEPTH - 1) # because there is an extra register f.EXPORT_SIZE.set(self.EXPORT_SIZE) if self.EXPORT_SIZE: self.size = VectSignal(log2ceil(self.DEPTH + 1 + 1), signed=False)
class FifoAsync(Fifo): """ Asynchronous fifo using BRAM memory, based on: http://www.asic-world.com/examples/vhdl/asyn_fifo.html .. hwt-schematic:: _example_FifoAsync """ def _declr(self): assert int(self.DEPTH) > 0, "FifoAsync is disabled in this case, do not use it entirely" assert isPow2(self.DEPTH), "FifoAsync DEPTH has to be power of 2" # pow 2 because of gray conter counters if int(self.EXPORT_SIZE) or int(self.EXPORT_SPACE): raise NotImplementedError() self.dataIn_clk = Clk() self.dataOut_clk = Clk() self.rst_n = Rst_n() with self._paramsShared(): with self._associated(clk=self.dataIn_clk): self.dataIn = FifoWriter() with self._associated(clk=self.dataOut_clk): self.dataOut = FifoReader()._m() self.pWr = GrayCntr() self.pRd = GrayCntr() self.addrW = log2ceil(self.DEPTH) for cntr in [self.pWr, self.pRd]: cntr.DATA_WIDTH.set(self.addrW) def _impl(self): ST_EMPTY, ST_FULL = 0, 1 memory_t = Bits(self.DATA_WIDTH)[self.DEPTH] memory = self._sig("memory", memory_t) full = self._sig("full", defVal=0) empty = self._sig("empty", defVal=1) status = self._sig("status", defVal=ST_EMPTY) In = self.dataIn InClk = self.dataIn_clk._onRisingEdge() Out = self.dataOut OutClk = self.dataOut_clk._onRisingEdge() self.pWr.en(In.en & ~full) self.pWr.clk(self.dataIn_clk) self.pWr.rst_n(self.rst_n) pNextWordToWrite = self.pWr.dataOut self.pRd.en(Out.en & ~empty) self.pRd.clk(self.dataOut_clk) self.pRd.rst_n(self.rst_n) pNextWordToRead = self.pRd.dataOut # data out logic If(OutClk, If(Out.en & ~empty, Out.data(memory[pNextWordToRead]) ) ) # data in logic If(InClk, If(In.en & ~full, memory[pNextWordToWrite](In.data) ) ) equalAddresses = pNextWordToWrite._eq(pNextWordToRead) aw = self.addrW nw = pNextWordToWrite nr = pNextWordToRead setStatus = nw[aw - 2]._eq(nr[aw - 1]) & (nw[aw - 1] ^ nr[aw - 2]) rstStatus = (nw[aw - 2] ^ nr[aw - 1]) & nw[aw - 1]._eq(nr[aw - 2]) # status latching If(rstStatus | self.rst_n._isOn(), status(ST_EMPTY) ).Elif(setStatus, status(ST_FULL) ) # data in logic presetFull = status & equalAddresses # D Flip-Flop with Asynchronous Preset. If(self.rst_n._isOn(), full(0) ).Elif(presetFull, full(1) ).Elif(InClk, full(0) ) In.wait(full) # data out logic presetEmpty = ~status & equalAddresses # D Flip-Flop w/ Asynchronous Preset. If(self.rst_n._isOn(), empty(0) ).Elif(presetEmpty, empty(1) ).Elif(OutClk, empty(0) ) Out.wait(empty)
def addClkRstn(obj): """ Construct clk, rst_n signal on object (usually Unit/Interface instance) """ obj.clk = Clk() obj.rst_n = Rst_n()
class FifoAsync(Fifo): """ Asynchronous fifo using BRAM memory, based on: http://www.asic-world.com/examples/vhdl/asyn_fifo.html .. hwt-schematic:: _example_FifoAsync """ def _declr(self): assert int( self.DEPTH ) > 0, "FifoAsync is disabled in this case, do not use it entirely" assert isPow2(self.DEPTH), "FifoAsync DEPTH has to be power of 2" # pow 2 because of gray conter counters if int(self.EXPORT_SIZE) or int(self.EXPORT_SPACE): raise NotImplementedError() self.dataIn_clk = Clk() self.dataOut_clk = Clk() self.rst_n = Rst_n() with self._paramsShared(): with self._associated(clk=self.dataIn_clk): self.dataIn = FifoWriter() with self._associated(clk=self.dataOut_clk): self.dataOut = FifoReader()._m() self.pWr = GrayCntr() self.pRd = GrayCntr() self.addrW = log2ceil(self.DEPTH) for cntr in [self.pWr, self.pRd]: cntr.DATA_WIDTH.set(self.addrW) def _impl(self): ST_EMPTY, ST_FULL = 0, 1 memory_t = Bits(self.DATA_WIDTH)[self.DEPTH] memory = self._sig("memory", memory_t) full = self._sig("full", defVal=0) empty = self._sig("empty", defVal=1) status = self._sig("status", defVal=ST_EMPTY) In = self.dataIn InClk = self.dataIn_clk._onRisingEdge() Out = self.dataOut OutClk = self.dataOut_clk._onRisingEdge() self.pWr.en(In.en & ~full) self.pWr.clk(self.dataIn_clk) self.pWr.rst_n(self.rst_n) pNextWordToWrite = self.pWr.dataOut self.pRd.en(Out.en & ~empty) self.pRd.clk(self.dataOut_clk) self.pRd.rst_n(self.rst_n) pNextWordToRead = self.pRd.dataOut # data out logic If(OutClk, If(Out.en & ~empty, Out.data(memory[pNextWordToRead]))) # data in logic If(InClk, If(In.en & ~full, memory[pNextWordToWrite](In.data))) equalAddresses = pNextWordToWrite._eq(pNextWordToRead) aw = self.addrW nw = pNextWordToWrite nr = pNextWordToRead setStatus = nw[aw - 2]._eq(nr[aw - 1]) & (nw[aw - 1] ^ nr[aw - 2]) rstStatus = (nw[aw - 2] ^ nr[aw - 1]) & nw[aw - 1]._eq(nr[aw - 2]) # status latching If(rstStatus | self.rst_n._isOn(), status(ST_EMPTY)).Elif(setStatus, status(ST_FULL)) # data in logic presetFull = status & equalAddresses # D Flip-Flop with Asynchronous Preset. If(self.rst_n._isOn(), full(0)).Elif(presetFull, full(1)).Elif(InClk, full(0)) In.wait(full) # data out logic presetEmpty = ~status & equalAddresses # D Flip-Flop w/ Asynchronous Preset. If(self.rst_n._isOn(), empty(0)).Elif(presetEmpty, empty(1)).Elif(OutClk, empty(0)) Out.wait(empty)