cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
schrepta
Observer
Observer
12,262 Views
Registered: ‎11-20-2013

Need help with PCIE endpoint example simple vhdl code modification

Jump to solution

Hello,

 

I am using the kc705 PCIE pio example code, which works fine by itself.

I tried to put in some vhdl code to latch 4 bits of data and direct it to the 4 leds on the board.

I placed the code in the  PIO_RX_ENGINE.vhd module.

Where ever there is a similar, existing line of code (there are multiple ones depending on the different types of write operations)...

 

wr_data <= m_axis_rx_tdata(127 downto 96) after TCQ; (existing line of code)

 

I would place this after it…

 

if(latch_data = '1') then

                 i_led_data <= m_axis_rx_tdata(99 downto 96) after TCQ;

end if;

 

…with the proper bit ranges.

 

Where…

 

latch_data <= (m_axis_rx_tvalid and m_axis_rx_tlast);

 

The assignment is made as follows…

 

led_data <= i_led_data;

 

where led_data is defined as…

led_data    :out std_logic_vector(3 downto 0);     in the port list of the entity of this module.

And i_led_data is a signal of std_logic_vector(3 downto 0);    

 

I have hierarchy connectivity all the way up to the led pins of the entire design. (I verified this by other means)

 

The core was generated with 128 bit AXI bus.  I can write and read data to the BRAM, but the leds show nothing, always off.

The AXI timing of my signal “ latch_data” should work to latch the data in a 4-bit register. The synthesized schematic shows these 4 registers.

I’m using Vivado 2013.3 (64-bit).

 

Has anyone made similar code changes?  I am getting started to use this example as a base for my project.  Thank you.

0 Kudos
1 Solution

Accepted Solutions
schrepta
Observer
Observer
19,172 Views
Registered: ‎11-20-2013

I am responding to my own post.

To recap, I added code to the PIO_RX_ENGINE.vhd module to register 4 data bits of a memory write TLP, and drive the 4 LEDs on the kc705 board.  As simple as this code Is, I could not get it to work.  The core was generated with 128 bit AXI bus.  I can write and read data to the BRAM as normal, but the leds show nothing, always off.

 

I believe I have found the problem.  Originally I was using "m_axis_rx_tlast" to latch 4 bits of "m_axis_rx_tdata" into a 4-bit register, which drives the 4 leds on the kc705 board.

This was not working.  So instead of using "m_axis_rx_tlast" , I used "m_axis_rx_tuser(21)" , which is the AXI EOF signal.  This worked.

Note, there is no extensive address decoding, so any memory write will work here, just to keep it simple as a first pass in developing with the core.

 

Note: These mods were implemented in the (C_DATA_WIDTH = 128) section of code.

 

    signal i_led_data     : std_logic_vector(3 downto 0);

    signal rx_eof_q         :std_logic;

    signal rx_eof           :std_logic;

 

--=========================================================

--new code added

--=========================================================

 

    rx_eof <= m_axis_rx_tuser(21);  --m_axis_rx_tlast does not work

 

    process(clk,rst_n,rx_eof)

    begin

        if(clk'event and clk = '1') then

                  if(rst_n = '0') then

                     rx_eof_q <= '0';

                  else

                     rx_eof_q <= rx_eof; --eof

                  end if;

        end if;

    end process;

                   

    led_data <= i_led_data; --drive the leds

 

--=========================================================

 

--existing case with new code added

--

when RX_MEM_WR32_FMT_TYPE => --32 bit address mem write, DW3DW2DW1DW0 = Data,Address,Header1,Header0 [127:0]

                                                    -- it's all there in one clock cycle.

                         if (m_axis_rx_tdata(9 downto 0) = "0000000001") then --we only want a tlp of data length 1

                           wr_be <= m_axis_rx_tdata(39 downto 32) after TCQ;

                           --lower qw

                           wr_data <= m_axis_rx_tdata(127 downto 96) after TCQ;

                           

                           --==============================================================

                           --new code added

                           --==============================================================

                           if(rx_eof = '1' AND rx_eof_q = '0') then

                                i_led_data <= m_axis_rx_tdata(99 downto 96) after TCQ;

                           end if;

                           --==============================================================

                          

                           wr_en <= '1' after TCQ;

                           wr_addr <= (region_select(1 downto 0) & m_axis_rx_tdata(74 downto 66)) after TCQ;

                           wr_en <= '1' after TCQ;

                           state <= PIO_128_RX_WAIT_STATE after TCQ;

                         else

                           state <= PIO_128_RX_RST_STATE after TCQ;

                         end if;

 

 

 

--existing case with new code added

--

when PIO_128_RX_MEM_WR32_DW1DW2 => --32 bit addressing mem write

                 if ((m_axis_rx_tvalid) = '1') then

                

                 --==============================================================

                 --new code added

                 --==============================================================

                 if(rx_eof = '1' AND rx_eof_q = '0') then

                        i_led_data <= m_axis_rx_tdata(35 downto 32) after TCQ;

                 end if;

                 --==============================================================

                

                   wr_data <= m_axis_rx_tdata(63 downto 32) after TCQ;

                   wr_en <= '1' after TCQ;

                   m_axis_rx_tready_v6pcie0 <= '0' after TCQ;

                   wr_addr <= (region_select(1 downto 0) & m_axis_rx_tdata(10 downto 2)) after TCQ;

                   state <= PIO_128_RX_WAIT_STATE after TCQ;

                 else

                   state <= PIO_128_RX_MEM_WR32_DW1DW2 after TCQ;--stay here until the core presents valid data and address

                 end if;

 

 

 

These two signals look to operate the same according to the timing diagrams in the PG054 document, but apparently the "m_axis_rx_tlast" does not.

I'm not sure if this is an issue with the core.

 

View solution in original post

0 Kudos
5 Replies
kotir
Scholar
Scholar
12,244 Views
Registered: ‎02-03-2010

Hi ,

 

I would suggest you to so a simulation.

If you send a Write transaction from rootport model would the nets which are connected to LED I/O on the top level togle depending ont he written data to the register ?

 

 

 

Regards,

Koti Reddy

--------------------------------------------------​--------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful.
--------------------------------------------------​-------------------------------------------
0 Kudos
schrepta
Observer
Observer
19,173 Views
Registered: ‎11-20-2013

I am responding to my own post.

To recap, I added code to the PIO_RX_ENGINE.vhd module to register 4 data bits of a memory write TLP, and drive the 4 LEDs on the kc705 board.  As simple as this code Is, I could not get it to work.  The core was generated with 128 bit AXI bus.  I can write and read data to the BRAM as normal, but the leds show nothing, always off.

 

I believe I have found the problem.  Originally I was using "m_axis_rx_tlast" to latch 4 bits of "m_axis_rx_tdata" into a 4-bit register, which drives the 4 leds on the kc705 board.

This was not working.  So instead of using "m_axis_rx_tlast" , I used "m_axis_rx_tuser(21)" , which is the AXI EOF signal.  This worked.

Note, there is no extensive address decoding, so any memory write will work here, just to keep it simple as a first pass in developing with the core.

 

Note: These mods were implemented in the (C_DATA_WIDTH = 128) section of code.

 

    signal i_led_data     : std_logic_vector(3 downto 0);

    signal rx_eof_q         :std_logic;

    signal rx_eof           :std_logic;

 

--=========================================================

--new code added

--=========================================================

 

    rx_eof <= m_axis_rx_tuser(21);  --m_axis_rx_tlast does not work

 

    process(clk,rst_n,rx_eof)

    begin

        if(clk'event and clk = '1') then

                  if(rst_n = '0') then

                     rx_eof_q <= '0';

                  else

                     rx_eof_q <= rx_eof; --eof

                  end if;

        end if;

    end process;

                   

    led_data <= i_led_data; --drive the leds

 

--=========================================================

 

--existing case with new code added

--

when RX_MEM_WR32_FMT_TYPE => --32 bit address mem write, DW3DW2DW1DW0 = Data,Address,Header1,Header0 [127:0]

                                                    -- it's all there in one clock cycle.

                         if (m_axis_rx_tdata(9 downto 0) = "0000000001") then --we only want a tlp of data length 1

                           wr_be <= m_axis_rx_tdata(39 downto 32) after TCQ;

                           --lower qw

                           wr_data <= m_axis_rx_tdata(127 downto 96) after TCQ;

                           

                           --==============================================================

                           --new code added

                           --==============================================================

                           if(rx_eof = '1' AND rx_eof_q = '0') then

                                i_led_data <= m_axis_rx_tdata(99 downto 96) after TCQ;

                           end if;

                           --==============================================================

                          

                           wr_en <= '1' after TCQ;

                           wr_addr <= (region_select(1 downto 0) & m_axis_rx_tdata(74 downto 66)) after TCQ;

                           wr_en <= '1' after TCQ;

                           state <= PIO_128_RX_WAIT_STATE after TCQ;

                         else

                           state <= PIO_128_RX_RST_STATE after TCQ;

                         end if;

 

 

 

--existing case with new code added

--

when PIO_128_RX_MEM_WR32_DW1DW2 => --32 bit addressing mem write

                 if ((m_axis_rx_tvalid) = '1') then

                

                 --==============================================================

                 --new code added

                 --==============================================================

                 if(rx_eof = '1' AND rx_eof_q = '0') then

                        i_led_data <= m_axis_rx_tdata(35 downto 32) after TCQ;

                 end if;

                 --==============================================================

                

                   wr_data <= m_axis_rx_tdata(63 downto 32) after TCQ;

                   wr_en <= '1' after TCQ;

                   m_axis_rx_tready_v6pcie0 <= '0' after TCQ;

                   wr_addr <= (region_select(1 downto 0) & m_axis_rx_tdata(10 downto 2)) after TCQ;

                   state <= PIO_128_RX_WAIT_STATE after TCQ;

                 else

                   state <= PIO_128_RX_MEM_WR32_DW1DW2 after TCQ;--stay here until the core presents valid data and address

                 end if;

 

 

 

These two signals look to operate the same according to the timing diagrams in the PG054 document, but apparently the "m_axis_rx_tlast" does not.

I'm not sure if this is an issue with the core.

 

View solution in original post

0 Kudos
kotir
Scholar
Scholar
12,178 Views
Registered: ‎02-03-2010

Hi,

 

The tlast signal is asserted on on the final cycle of the transaction.

If you are using this signal you have to use m_axis_rx_tstrb signal also as this serves as indication of valid data.

I think this might be causing the data unable to latched in your case if you use tlast.

 

You can take look at the wave forms in the pg054 and look at your code.

 

Regards,

Koti reddy

 

 

--------------------------------------------------​--------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful.
--------------------------------------------------​-------------------------------------------
0 Kudos
schrepta
Observer
Observer
12,160 Views
Registered: ‎11-20-2013

Actually, m_axis_rx_tvalid is '1' during this time, which states that the data on the AXI4 bus is valid.

Additional support is looking at this, and determined, for some reason, that the m_axis_rx_tlast signal, from the core, is being grounded...strange. So the reason for this anomally is unknown at this time.

Thanks for your input.

0 Kudos
lbenites
Observer
Observer
10,464 Views
Registered: ‎08-15-2014

FYI, from pg023, page 159:

 

When the straddle option is enabled, Completion TLPs are transferred on the RC interface as a continuous stream, with no packet boundaries (from an AXI4-Stream perspective). Thus, the m_axis_rc_tkeep and m_axis_rc_tlast signals are not useful in determining the boundaries of Completion TLPs delivered on the interface (the integrated block sets m_axis_rc_tkeep to all 1s and m_axis_rc_tlast to 0 permanently when the straddle option is in use)

 

0 Kudos