PyHDI/veriloggen

Convention violation of AXI Lite protocol on AxiLiteSlave

Closed this issue · 1 comments

About

AxisLiteRegister now accepts outstandings of 2 in read transactions.
The axi lite protocol requires that the number of outstandings be less than 1.

Expected

Set the maximum number of outstandings for AxiLiteSlave transactions to 1.

Environment

  • Ubuntu 18.04.4 LTS
  • Python 3.8.13
  • pyverilog 1.3.0
  • veriloggen v2.1.0 - v2.1.1

Debug

I suspect that the "ack" signal generated by push_read_data() in types/axi.py:AxiLiteSlave class is not correct.
In thread/axis.py, this "ack" is observed and FSM of AXISLiteRegister is set back to init.
The "ack" signal is not a handshake notification of rdata, but rather a push notification of rdata, so it make fsm into init, despite handshake for read channel has not been established.
The fsm state returns to init even if the handshake has not been established, and the next address request is accepted.
As a result, the number of outstandings seems to be more than 1.

  • https://github.com/PyHDI/veriloggen/blame/c548d58fc6c72efaf0994682a07d0a4f52b737cf/veriloggen/types/axi.py#L1850-L1877

    def push_read_data(self, data, cond=None):
    """
    @return ack
    """
    if self._read_disabled:
    raise TypeError('Read disabled.')
    if cond is not None:
    self.seq.If(cond)
    ack = vtypes.Ors(self.rdata.rready, vtypes.Not(self.rdata.rvalid))
    self.seq.If(ack)(
    self.rdata.rdata(data),
    self.rdata.rvalid(1)
    )
    # de-assert
    self.seq.Delay(1)(
    self.rdata.rvalid(0)
    )
    # retry
    self.seq.If(vtypes.Ands(self.rdata.rvalid, vtypes.Not(self.rdata.rready)))(
    self.rdata.rvalid(self.rdata.rvalid)
    )
    return ack

  • https://github.com/PyHDI/veriloggen/blame/c548d58fc6c72efaf0994682a07d0a4f52b737cf/veriloggen/thread/axis.py#L290-L325

    init_state = fsm.current
    # read
    read_state = fsm.current + 1
    fsm.If(readvalid).goto_from(init_state, read_state)
    fsm.set_index(read_state)
    rdata = self.m.TmpWire(self.datawidth, signed=True, prefix='axislite_rdata')
    pat = [(maskaddr == i, r) for i, r in enumerate(self.register)]
    pat.append((None, vtypes.IntX()))
    rval = vtypes.PatternMux(pat)
    rdata.assign(rval)
    flag = self.m.TmpWire(prefix='axislite_flag')
    pat = [(maskaddr == i, r) for i, r in enumerate(self.flag)]
    pat.append((None, vtypes.IntX()))
    rval = vtypes.PatternMux(pat)
    flag.assign(rval)
    resetval = self.m.TmpWire(self.datawidth, signed=True, prefix='axislite_resetval')
    pat = [(maskaddr == i, r) for i, r in enumerate(self.resetval)]
    pat.append((None, vtypes.IntX()))
    rval = vtypes.PatternMux(pat)
    resetval.assign(rval)
    ack = self.push_read_data(rdata, cond=fsm)
    # flag reset
    state_cond = fsm.state == fsm.current
    for i, r in enumerate(self.register):
    self.seq.If(state_cond, ack, flag, maskaddr == i)(
    self.register[i](resetval),
    self.flag[i](0)
    )
    fsm.If(ack).goto_init()

This issue has been resolved in c7dc37b .