Forum Discussion

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

Avalon ST custom IP component

Hello,

I'm having trouble creating my own component that uses Avalon Streaming Interface in QSys. Based on the VIP demonstartion for DE1-SoC I want to have a connection between the Altera VIP Frame Reader and Alpha Blending Mixer (to process the frames that are sent). In order to do that I created a VHDL file and created a new component in QSys, specyfing the data, valid, ready, startofpacket and endofpacket signals since these are the ones used by Frame Reader and Blending Mixer. I check if the valid and ready signals are asserted and then just pass the data, startofpacket and endofpacket signals through. In QSys I also needed to add Timing Adapters before and after my component because of Ready Latency. Unfortunately, the frames flows continously and are moving through the vga screen so I believe there's something wrong with the logic in my component. I check the signals at the rising edge of the clock. I'm new to the Avalon stuff and I'm sure I'm missing something really simple in the code. I attach it below. Could you help me find what's missing in here?


LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY simple_avalon_interface IS
PORT ( 
clock, resetn : IN STD_LOGIC;
din_startofpacket : in std_logic;
din_endofpacket : in std_logic;
din_valid : in std_LOGIC;
din_ready : out STD_LOGIC;
din_data : in STD_LOGIC_VECTOR(23 DOWNTO 0);
dout_startofpacket : out std_logic;
dout_endofpacket : out std_logic;
dout_valid : out std_LOGIC;
dout_ready : in STD_LOGIC;
dout_data : out STD_LOGIC_VECTOR(23 DOWNTO 0)
);
END simple_avalon_interface;
ARCHITECTURE Structure OF simple_avalon_interface IS
BEGIN
process (clock,dout_ready,din_valid)
begin
if (rising_edge(clock)) then
    if (dout_ready ='1' and din_valid = '1') then    
        dout_valid <= '1';
        din_ready <= '1';
        dout_data <= din_data;
        dout_startofpacket <= din_startofpacket;
        dout_endofpacket <= din_endofpacket;
    else 
        dout_valid <= '0';
        din_ready <= '0';
    end if;
end if;
end process;
END Structure;

14 Replies

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

    Yes, you'll not want to change the control packets. The first 4 bits of a packet (these are the lowest 4 bits in your data width, so if you're using 24 bits the first 24-bit word will have the code in bits 3-0 and 23-4 are not used) will have a code that shows whether it's a control packet or not. If the first 4 bits are 0 then it's a video packet, if it's 15 then it's a control packet. 1-8 are reserved for custom user packets, 9-12 for Altera future use, 13 = Ancillary data, 14 reserved for Altera future use.

    0 and 15 are definitely correct. The text suggests 7 user packets and 5 future Altera packets, so there is some ambiguity about the others. My guess is 8 is wrong as a user packet.

    I should add that it's all on page 2-10 of the ug_vip.pdf guide.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    G'day BadOmen,

    Thank you for taking the time to respond in detail. Your advice is really useful for newbies like me!

    Your clue later in this thread is vital: The Avalon-ST Video Protocol, detailed in Section 2 of the VIP Users Guide, is essential reading for implementers.

    It looks like the simple solution below may be *too* simple. We need to avoid processing control packets as if they contain pixel data, and the first value of every packet never contains pixel data. So the core can't just process sink data on every src_valid cycle.

    I'm working on a couple of cores with relatively deep pixel pipelines which, similar to this example, are insensitive to the content of the control packets. Is there a "right" way, in general, for managing control packets for such a core?

    Hopeful thanks ...

    --- Quote Start ---

    If your transform is combinatorial what you could do is create a component that has a source and a sink with the sink data transformed and sent to the source. Then you would wire the ready and valid bits directly so that all your component does is transform the data. Then if that's too much combinational delay and you need it pipelined put that Qsys pipeline stage after your core.

    Often when I'm building stuff like this I have FIFOs too which helps isolate the source and sink. Last but not least another thing you can do is pipeline the transformed data and the valid from the sink and use the ready from source to enable the registering of those two signals and specify in the component defining that it has a ready latency of 1. Something like this in Verilog:

    
    always @ (posedge clk)
    begin
      if ((snk_valid == 1) & (src_ready == 1)
      begin
        src_data <= transformed_snk_data;   // need to make sure data is held in cause the src_ready deasserts on the next clock cycle
      end
      src_valid <= snk_valid; 
    end
    

    That code above is only safe if the ready latency of the source port is declared as 1. What Qsys will do is resynchronize the data output from your core. So basically when your component is being fed valid data and the source is being told that the downstream is ready for data you capture your data. On the next clock cycle if the downstream IP is still ready for the data then it gets sent, and if it's not ready then the data is held. Since the ready latency of the source is 1 Qsys will put a timing adapter into the path that compensates for the fact that valid data takes an extra clock cycle to get through your core. You could build the same sort of compensation into your IP but then you are re-inventing the wheel. Hopefully you can now see why I put FIFOs in a lot of the streaming IP I build, it helps isolate the flow of data by decoupling the source from the sink.

    --- Quote End ---

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

    rockoff, if I understand correctly, you want to have a component that performs some computations on the pixel values so you want to avoid changing the control packets, right? If yes, then you can detect the start of packet input signal and then check the least for bits of data input. if they're "0000" then the next packet that will arrive is the pixel value. To give you an example:

    
     if DIN_SOP = '1' then
    	if DIN_DATA(3 downto 0) ="0000" then
    	      --set some signal to know that you're dealing with pixels next
                     data_pkt <= '1';		
    

    Hope this helps you a little
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Korn,

    Thank you for this helpful reply.

    Yes, I'm inserting pixel-processing components into a video pipeline. The new components must respect the VIP streaming protocol so that they'll interoperate correctly with VIP suite cores.

    One way or another, we're required to implement a state machine to keep track of what just came in on din_data.

    Indeed, checking the low-order nibble when SOP is asserted, as you suggest, is essential.

    I'm wrestling with a simplest such state machine. Since every single IP core to be connected to a VIP suite core requires this logic, I'm surprised that there is no example in the VIP Suite User Guide or on the forum. Maybe I'm just missing it?