Hi Kevin,

To expand on Brian's and Rob's comments, one issue that often comes up is
user logic bugs related to AXI stream's tvalid / tready signaling. The
user's logic will pass their test bench but behave strangely or lock up
when running on hardware. I've found that before running on hardware, you
should at least test your block with randomized assertion of noc_shell's
tvalids / treadys. Here is one way to do it based on the rfnoc-example gain
block (
https://github.com/EttusResearch/uhd/blob/master/host/examples/rfnoc-example/fpga/rfnoc_block_gain/rfnoc_block_gain.v
):


  wire m_in_payload_tvalid_int, m_in_payload_tready_int;
  wire s_out_payload_tvalid_int, s_out_payload_tready_int;

  noc_shell_gain #(
    .CHDR_W      (CHDR_W),
    .THIS_PORTID (THIS_PORTID),
    .MTU         (MTU)
  ) noc_shell_gain_i (
    .rfnoc_chdr_clk      (rfnoc_chdr_clk),
    .rfnoc_ctrl_clk      (rfnoc_ctrl_clk),
    .rfnoc_chdr_rst      (),
    .rfnoc_ctrl_rst      (),
    .rfnoc_core_config   (rfnoc_core_config),
    .rfnoc_core_status   (rfnoc_core_status),
    .s_rfnoc_chdr_tdata  (s_rfnoc_chdr_tdata),
    .s_rfnoc_chdr_tlast  (s_rfnoc_chdr_tlast),
    .s_rfnoc_chdr_tvalid (s_rfnoc_chdr_tvalid),
    .s_rfnoc_chdr_tready (s_rfnoc_chdr_tready),
    .m_rfnoc_chdr_tdata  (m_rfnoc_chdr_tdata),
    .m_rfnoc_chdr_tlast  (m_rfnoc_chdr_tlast),
    .m_rfnoc_chdr_tvalid (m_rfnoc_chdr_tvalid),
    .m_rfnoc_chdr_tready (m_rfnoc_chdr_tready),
    .s_rfnoc_ctrl_tdata  (s_rfnoc_ctrl_tdata),
    .s_rfnoc_ctrl_tlast  (s_rfnoc_ctrl_tlast),
    .s_rfnoc_ctrl_tvalid (s_rfnoc_ctrl_tvalid),
    .s_rfnoc_ctrl_tready (s_rfnoc_ctrl_tready),
    .m_rfnoc_ctrl_tdata  (m_rfnoc_ctrl_tdata),
    .m_rfnoc_ctrl_tlast  (m_rfnoc_ctrl_tlast),
    .m_rfnoc_ctrl_tvalid (m_rfnoc_ctrl_tvalid),
    .m_rfnoc_ctrl_tready (m_rfnoc_ctrl_tready),
    .ctrlport_clk              (ctrlport_clk),
    .ctrlport_rst              (ctrlport_rst),
    .m_ctrlport_req_wr         (m_ctrlport_req_wr),
    .m_ctrlport_req_rd         (m_ctrlport_req_rd),
    .m_ctrlport_req_addr       (m_ctrlport_req_addr),
    .m_ctrlport_req_data       (m_ctrlport_req_data),
    .m_ctrlport_resp_ack       (m_ctrlport_resp_ack),
    .m_ctrlport_resp_data      (m_ctrlport_resp_data),
    .axis_data_clk (axis_data_clk),
    .axis_data_rst (axis_data_rst),
    .m_in_payload_tdata  (m_in_payload_tdata),
    .m_in_payload_tkeep  (m_in_payload_tkeep),
    .m_in_payload_tlast  (m_in_payload_tlast),

*    .m_in_payload_tvalid (m_in_payload_tvalid_int),
.m_in_payload_tready (m_in_payload_tready_int),*
    .m_in_context_tdata  (m_in_context_tdata),
    .m_in_context_tuser  (m_in_context_tuser),
    .m_in_context_tlast  (m_in_context_tlast),
    .m_in_context_tvalid (m_in_context_tvalid),
    .m_in_context_tready (m_in_context_tready),
    .s_out_payload_tdata  (s_out_payload_tdata),
    .s_out_payload_tkeep  (s_out_payload_tkeep),
    .s_out_payload_tlast  (s_out_payload_tlast),

*    .s_out_payload_tvalid (s_out_payload_tvalid_int),
.s_out_payload_tready (s_out_payload_tready_int),*
    .s_out_context_tdata  (s_out_context_tdata),
    .s_out_context_tuser  (s_out_context_tuser),
    .s_out_context_tlast  (s_out_context_tlast),
    .s_out_context_tvalid (s_out_context_tvalid),
    .s_out_context_tready (s_out_context_tready)
  );

  wire [31:0] rnd;
  rng rng (
    .clk(axis_data_clk),
    .rst(axis_data_rst),
    .out(rnd));

  assign m_in_payload_tvalid      = m_in_payload_tvalid_int  & rnd[0];
  assign m_in_payload_tready_int  = m_in_payload_tready      & rnd[0];

  assign s_out_payload_tvalid_int = s_out_payload_tvalid     & rnd[8];
  assign s_out_payload_tready     = s_out_payload_tready_int & rnd[8];


I suggest doing something similar with your block and see if it still
passes your test bench.

Jonathon

On Wed, Sep 14, 2022 at 3:33 PM Rob Kossler <rkoss...@nd.edu> wrote:

> Hi Kevin,
> If you run the rfnoc-example gain testbench, it should demonstrate that
> the testbench is providing a suitable environment for testing your custom
> logic or core.  Maybe see what is different between that and your
> testbench.
>
> If the problem turns out to be related to the "waiting for TREADY before
> asserting TVALID" issue presently discussed, it seems this can be solved by
> adding a buffer stage (register or FIFO) between your logic and the noc
> shell.
> Rob
>
> On Wed, Sep 14, 2022 at 2:11 PM Brian Padalino <bpadal...@gmail.com>
> wrote:
>
>> On Wed, Sep 14, 2022 at 1:55 PM Kevin Williams <zs1...@gmail.com> wrote:
>>
>>> Thanks Brian. I think the core gets generated in a way which respects
>>> back-pressure, so unless a TREADY is seen the core does not generate output
>>> samples. I have observed this by simulating the core in isolation.
>>>
>> On 14 Sep 2022, 17:49 +0200, Brian Padalino <bpadal...@gmail.com>, wrote:
>>>
>>> I believe the AXI spec says that data should be presented when valid,
>>> and the tready signal just accepts that data.  You can't rely on tready to
>>> be asserted before asserting tvalid.
>>>
>>> With that being said, I have no idea if this is the source of any of
>>> your issues.
>>>
>>> Brian
>>>
>>>
>> I don't quite understand what you said.  To copy from the AXI protocol
>> spec (
>> https://documentation-service.arm.com/static/60d5b244677cf7536a55c23e?token=)
>> section 2.2:
>>
>>   "A Transmitter is not permitted to wait until TREADY is asserted before
>> asserting TVALID. Once TVALID is
>> asserted, it must remain asserted until the handshake occurs.
>>
>>   A Receiver is permitted to wait for TVALID to be asserted before
>> asserting TREADY. It is permitted that a
>> Receiver asserts and deasserts TREADY without TVALID being asserted."
>>
>> Waiting for TREADY to be asserted is invalid as a transmitter.
>>
>> Is something not compliant and causing deadlock?
>>
>> Brian
>>
>
_______________________________________________
USRP-users mailing list -- usrp-users@lists.ettus.com
To unsubscribe send an email to usrp-users-le...@lists.ettus.com

Reply via email to