Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Avalon-ST backpressure with SGDMA

Hi,

I have a custom SOPC component with multiple Avalon streaming ports supporting backpressure, using a ready latency of 0. For testing, I've connected a sink port up to an Altera SGDMA component. Using signal tap, I noticed that the SGDMA component will not initially assert "valid" until my component asserts "ready". I would have thought that the SGDMA should assert valid as soon as it wants to source data, then my component would assert ready when it can accept it. This is what the Avalon Interface Specification says (March 2008 version) :

"When readyLatency=0, data is transferred only when ready and valid are asserted on the same cycle. In this mode of operation, the source does not receive the sink’s ready signal before it begins sending valid data. the source provides the data and asserts valid whenever it can and waits for the sink to capture the data and assert ready. The sink only captures input data from the source when ready and valid are both asserted."

Is this a problem with the SGDMA component, the Avalon-ST specification, or my interpretation of the spec :)? I'm using v7.2, sp3. Any insight is appreciated, thanks.

Paul

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I think what you are experiencing is due to the fact that the SGDMA is using a readyLatency of 1 instead of 0. The behavior you are describing matches that condition. See section 6.6 of the Avalon Interface Specifications document.

    SOPC builder is supposed to give you an error indicating that the source and sink interfaces have incompatible readyLatency values. I take it that's not the case. It doesn't surprise me. The SGDMA core in 7.2 had some issues. To my knowledge the SGDMA core has only been used by Altera for the TSE MAC. I'd be surprised if it's been tested with anything else.

    Jake
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I see what you mean about the resemblance to non-zero readyLatency. While the SGDMA documentation does not specify readyLatency, my local FAE indicated it was zero. And indeed, if I specify my custom component with a readyLatency of 1, SOPC Builder gives an error. For now, I've modified my component to act as though it has a non-zero readyLatency (by asserting ready before valid), but I specify 0 in component editor.

    What issues did the 7.2 SGMDA component have? The knowledgebase doesn't seem to document any.

    Paul
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I received this answer back from Altera:

    "Although the SG-DMA changes the status of valid signal after it receives the valid ready signal, it doesn’t impact the design of sink. Because sink can set its ready signal according its own status, and it samples the stream data when valid and ready assert in the same cycle. There is no necessary to wait the valid signal in order to output the ready signal."

    In other words, the SGDMA violates the Avalon-ST specification of zero-ready-latency devices, by not asserting valid until the sink asserts ready, but Altera is not going to fix it. I've asked that they at least update the Avalon-ST and/or SGDMA documentation.

    So, I was curious if their Avalon-ST Multiplexer would work with SGDMA? Well, it does. Looking at the generated verilog below for an 8:1 mux, they take the source valid signal and invert it to create the ready signal back to that source. So the ready signal for all inputs is asserted even though they're really not ready. This allows the SGDMA to assert valid, which it then holds until the mux sink is really ready.

    
       // ---------------------------------------------------------------------
       //| Back Pressure
       // ---------------------------------------------------------------------
       always @* begin
          in0_ready <= ~in0_valid	;
          in1_ready <= ~in1_valid	;
          in2_ready <= ~in2_valid	;
          in3_ready <= ~in3_valid	;
          in4_ready <= ~in4_valid	;
          in5_ready <= ~in5_valid	;
          in6_ready <= ~in6_valid	;
          in7_ready <= ~in7_valid	;
          case(select) 
             0 : in0_ready <= selected_ready;
             1 : in1_ready <= selected_ready;
             2 : in2_ready <= selected_ready;
             3 : in3_ready <= selected_ready;
             4 : in4_ready <= selected_ready;
             5 : in5_ready <= selected_ready;
             6 : in6_ready <= selected_ready;
             7 : in7_ready <= selected_ready;
             default : in0_ready <= selected_ready;
          endcase
       end