Questions regarding connection to Xillybus FIFO

Questions and discussions about the Xillybus IP core and drivers

Questions regarding connection to Xillybus FIFO

Postby Guest »

Hey guys, I'm pretty new to the Xillybus, and I'm trying to run some tests on it.
I am with some problems with connecting my implementation to the 32 bit FIFO from Xillybus.
To test it I have designed a VHDL code with a rolling window moving average.
The ideia is to receive a 19 values from the C program and return the value of the moving average ofc.
But for some reason it is not working quite well. The return is either a fixed number of bites or a complete different value of bits.
I have read a lot about the Xillybus recently but I could not understand exactly how to wire it to my solution.
PS:(the division has 12 bits of precision).

Is there anyone that could give me some help?


Xillybus code :


Code: Select all
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;

entity xillydemo is
  port (
    PCIE_PERST_B_LS : IN std_logic;
    PCIE_REFCLK_N : IN std_logic;
    PCIE_REFCLK_P : IN std_logic;
    PCIE_RX_N : IN std_logic_vector(7 DOWNTO 0);
    PCIE_RX_P : IN std_logic_vector(7 DOWNTO 0);
    GPIO_LED : OUT std_logic_vector(3 DOWNTO 0);
    PCIE_TX_N : OUT std_logic_vector(7 DOWNTO 0);
    PCIE_TX_P : OUT std_logic_vector(7 DOWNTO 0));
end xillydemo;


architecture sample_arch of xillydemo is
  component xillybus
    port (
      PCIE_PERST_B_LS : IN std_logic;
      PCIE_REFCLK_N : IN std_logic;
      PCIE_REFCLK_P : IN std_logic;
      PCIE_RX_N : IN std_logic_vector(7 DOWNTO 0);
      PCIE_RX_P : IN std_logic_vector(7 DOWNTO 0);
      GPIO_LED : OUT std_logic_vector(3 DOWNTO 0);
      PCIE_TX_N : OUT std_logic_vector(7 DOWNTO 0);
      PCIE_TX_P : OUT std_logic_vector(7 DOWNTO 0);
      bus_clk : OUT std_logic;
      quiesce : OUT std_logic;
      user_r_mem_8_rden : OUT std_logic;
      user_r_mem_8_empty : IN std_logic;
      user_r_mem_8_data : IN std_logic_vector(7 DOWNTO 0);
      user_r_mem_8_eof : IN std_logic;
      user_r_mem_8_open : OUT std_logic;
      user_w_mem_8_wren : OUT std_logic;
      user_w_mem_8_full : IN std_logic;
      user_w_mem_8_data : OUT std_logic_vector(7 DOWNTO 0);
      user_w_mem_8_open : OUT std_logic;
      user_mem_8_addr : OUT std_logic_vector(4 DOWNTO 0);
      user_mem_8_addr_update : OUT std_logic;
      user_r_read_32_rden : OUT std_logic;
      user_r_read_32_empty : IN std_logic;
      user_r_read_32_data : IN std_logic_vector(31 DOWNTO 0);
      user_r_read_32_eof : IN std_logic;
      user_r_read_32_open : OUT std_logic;
      user_r_read_8_rden : OUT std_logic;
      user_r_read_8_empty : IN std_logic;
      user_r_read_8_data : IN std_logic_vector(7 DOWNTO 0);
      user_r_read_8_eof : IN std_logic;
      user_r_read_8_open : OUT std_logic;
      user_w_write_32_wren : OUT std_logic;
      user_w_write_32_full : IN std_logic;
      user_w_write_32_data : OUT std_logic_vector(31 DOWNTO 0);
      user_w_write_32_open : OUT std_logic;
      user_w_write_8_wren : OUT std_logic;
      user_w_write_8_full : IN std_logic;
      user_w_write_8_data : OUT std_logic_vector(7 DOWNTO 0);
      user_w_write_8_open : OUT std_logic);
  end component;
 
     COMPONENT engine
   PORT(
      rst : IN std_logic;
      tick_in : IN std_logic_vector(31 downto 0);
      empty : IN std_logic;
      CLK : IN std_logic;         
      enable : OUT std_logic;
      tick_out : OUT std_logic_vector(31 downto 0)
      );
   END COMPONENT;

  component fifo_8x2048
    port (
      clk: IN std_logic;
      srst: IN std_logic;
      din: IN std_logic_VECTOR(7 downto 0);
      wr_en: IN std_logic;
      rd_en: IN std_logic;
      dout: OUT std_logic_VECTOR(7 downto 0);
      full: OUT std_logic;
      empty: OUT std_logic);
  end component;

  component fifo_32x512
    port (
      clk: IN std_logic;
      srst: IN std_logic;
      din: IN std_logic_VECTOR(31 downto 0);
      wr_en: IN std_logic;
      rd_en: IN std_logic;
      dout: OUT std_logic_VECTOR(31 downto 0);
      full: OUT std_logic;
      empty: OUT std_logic);
  end component;

-- Synplicity black box declaration
  attribute syn_black_box : boolean;
  attribute syn_black_box of fifo_32x512: component is true;
  attribute syn_black_box of fifo_8x2048: component is true;

  type demo_mem is array(0 TO 31) of std_logic_vector(7 DOWNTO 0);
  signal demoarray : demo_mem;
 
  signal bus_clk :  std_logic;
  signal quiesce : std_logic;

  signal reset_8 : std_logic;
  signal reset_32 : std_logic;

  signal ram_addr : integer range 0 to 31;
 
  signal user_r_mem_8_rden :  std_logic;
  signal user_r_mem_8_empty :  std_logic;
  signal user_r_mem_8_data :  std_logic_vector(7 DOWNTO 0);
  signal user_r_mem_8_eof :  std_logic;
  signal user_r_mem_8_open :  std_logic;
  signal user_w_mem_8_wren :  std_logic;
  signal user_w_mem_8_full :  std_logic;
  signal user_w_mem_8_data :  std_logic_vector(7 DOWNTO 0);
  signal user_w_mem_8_open :  std_logic;
  signal user_mem_8_addr :  std_logic_vector(4 DOWNTO 0);
  signal user_mem_8_addr_update :  std_logic;
  signal user_r_read_32_rden :  std_logic;
  signal user_r_read_32_empty :  std_logic;
  signal user_r_read_32_data :  std_logic_vector(31 DOWNTO 0);
  signal user_r_read_32_eof :  std_logic;
  signal user_r_read_32_open :  std_logic;
  signal user_r_read_8_rden :  std_logic;
  signal user_r_read_8_empty :  std_logic;
  signal user_r_read_8_data :  std_logic_vector(7 DOWNTO 0);
  signal user_r_read_8_eof :  std_logic;
  signal user_r_read_8_open :  std_logic;
  signal user_w_write_32_wren :  std_logic;
  signal user_w_write_32_full :  std_logic;
  signal user_w_write_32_data :  std_logic_vector(31 DOWNTO 0);
  signal user_w_write_32_open :  std_logic;
  signal user_w_write_8_wren :  std_logic;
  signal user_w_write_8_full :  std_logic;
  signal user_w_write_8_data :  std_logic_vector(7 DOWNTO 0);
  signal user_w_write_8_open :  std_logic;
  signal saida8 : std_logic_vector(7 DOWNTO 0);
  signal saida32 :  std_logic_vector(31 DOWNTO 0);
  signal user_r_read_32_data_fifo : std_logic_vector(31 DOWNTO 0);
  signal enable_engine : std_logic;
 

begin
  xillybus_ins : xillybus
    port map (
      -- Ports related to /dev/xillybus_mem_8
      -- FPGA to CPU signals:
      user_r_mem_8_rden => user_r_mem_8_rden,
      user_r_mem_8_empty => user_r_mem_8_empty,
      user_r_mem_8_data => user_r_mem_8_data,
      user_r_mem_8_eof => user_r_mem_8_eof,
      user_r_mem_8_open => user_r_mem_8_open,
      -- CPU to FPGA signals:
      user_w_mem_8_wren => user_w_mem_8_wren,
      user_w_mem_8_full => user_w_mem_8_full,
      user_w_mem_8_data => user_w_mem_8_data,
      user_w_mem_8_open => user_w_mem_8_open,
      -- Address signals:
      user_mem_8_addr => user_mem_8_addr,
      user_mem_8_addr_update => user_mem_8_addr_update,

      -- Ports related to /dev/xillybus_read_32
      -- FPGA to CPU signals:
      user_r_read_32_rden => user_r_read_32_rden,
      user_r_read_32_empty => user_r_read_32_empty,
      user_r_read_32_data => user_r_read_32_data,
      user_r_read_32_eof => user_r_read_32_eof,
      user_r_read_32_open => user_r_read_32_open,

      -- Ports related to /dev/xillybus_read_8
      -- FPGA to CPU signals:
      user_r_read_8_rden => user_r_read_8_rden,
      user_r_read_8_empty => user_r_read_8_empty,
      user_r_read_8_data => saida8,
      user_r_read_8_eof => user_r_read_8_eof,
      user_r_read_8_open => user_r_read_8_open,

      -- Ports related to /dev/xillybus_write_32
      -- CPU to FPGA signals:
      user_w_write_32_wren => user_w_write_32_wren,
      user_w_write_32_full => user_w_write_32_full,
      user_w_write_32_data => user_w_write_32_data,
      user_w_write_32_open => user_w_write_32_open,

      -- Ports related to /dev/xillybus_write_8
      -- CPU to FPGA signals:
      user_w_write_8_wren => user_w_write_8_wren,
      user_w_write_8_full => user_w_write_8_full,
      user_w_write_8_data => user_w_write_8_data,
      user_w_write_8_open => user_w_write_8_open,

      -- General signals
      PCIE_PERST_B_LS => PCIE_PERST_B_LS,
      PCIE_REFCLK_N => PCIE_REFCLK_N,
      PCIE_REFCLK_P => PCIE_REFCLK_P,
      PCIE_RX_N => PCIE_RX_N,
      PCIE_RX_P => PCIE_RX_P,
      GPIO_LED => GPIO_LED,
      PCIE_TX_N => PCIE_TX_N,
      PCIE_TX_P => PCIE_TX_P,
      bus_clk => bus_clk,
      quiesce => quiesce
      );
--  A simple inferred RAM
   
   saida8 <= user_r_read_8_data + 1;
   --saida32 <= user_r_read_32_data +1;
   
  ram_addr <= conv_integer(user_mem_8_addr);
 
  process (bus_clk)
  begin
    if (bus_clk'event and bus_clk = '1') then
      if (user_w_mem_8_wren = '1') then
        demoarray(ram_addr) <= user_w_mem_8_data;
      end if;
      if (user_r_mem_8_rden = '1') then
        user_r_mem_8_data <= demoarray(ram_addr);
      end if;
    end if;
  end process;

  user_r_mem_8_empty <= '0';
  user_r_mem_8_eof <= '0';
  user_w_mem_8_full <= '0';

--  32-bit loopback

  fifo_32 : fifo_32x512
    port map(
      clk        => bus_clk,
      srst       => reset_32,
      din        => user_w_write_32_data,
      wr_en      => user_w_write_32_wren,
      rd_en      => enable_engine,
      dout       => user_r_read_32_data_fifo,
      full       => user_w_write_32_full,
      empty      => user_r_read_32_empty
      );

  reset_32 <= not (user_w_write_32_open or user_r_read_32_open);

  user_r_read_32_eof <= '0';
 
--  8-bit loopback

  fifo_8 : fifo_8x2048
    port map(
      clk        => bus_clk,
      srst       => reset_8,
      din        => user_w_write_8_data,
      wr_en      => user_w_write_8_wren,
      rd_en      => user_r_read_8_rden,
      dout       => user_r_read_8_data,
      full       => user_w_write_8_full,
      empty      => user_r_read_8_empty
      );


   engine_ins : engine
    port map (   
       rst => reset_32,
       tick_in => user_r_read_32_data_fifo,
       empty => user_r_read_32_empty,
       CLK => bus_clk,
       enable => enable_engine,
       tick_out => user_r_read_32_data
   --    ;
   --    action_buy: out std_logic;
   --    action_sell: out std_logic;
   --    action_nothing: out std_logic
   );

    reset_8 <= not (user_w_write_8_open or user_r_read_8_open);

    user_r_read_8_eof <= '0';
 
end sample_arch;



My division engine
Code: Select all

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;


-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity engine is
--  Port ( );
generic(

N : NATURAL :=20;
precision_size : NATURAL :=32;
fraction_size : NATURAL :=12
);


port(
    rst: in std_logic;
    tick_in: in std_logic_vector(precision_size -1 downto 0);
    empty: in std_logic;
    CLK: in std_logic;
    enable : OUT std_logic;
    tick_out: out std_logic_vector(precision_size -1 downto 0)

);   

end engine;

architecture Behavioral of engine is

type reg_ticks_t IS ARRAY(0 to N-1) of unsigned(precision_size - 1 downto 0);
signal reg_ticks : reg_ticks_t;
signal psum : reg_ticks_t;
signal quotient_out : unsigned (precision_size- 1 DOWNTO 0);
signal enable_int : std_logic;

begin

enable <= enable_int;
tick_out <= std_logic_vector(quotient_out);
process(CLK,rst)
--variable reg_ticks : reg_ticks_t
    begin
        --enable_int <= '0';   
        if(rst = '1') then
            reg_ticks <= (others=>(others=>'0'));
            psum  <= (others=>(others=>'0'));
            enable_int <= '0';
        else
            if(empty = '0' and rising_edge(clk)) then
                for i in 0 to N-1 loop
                    if(i/=0) then
                        reg_ticks(i) <= reg_ticks(i-1);
                        --psum(i) <= psum(i) + reg_ticks(i);
                        psum(i) <= psum(i) + reg_ticks(i);
                    else
                        reg_ticks(0) <= unsigned(tick_in);
                        psum(0) <=  unsigned(tick_in);   
                    end if;
                   
                end loop;
                enable_int <= '1';
            end if;
       end if;

       enable_int <= '1';      
end process;

process(psum(N-1))
VARIABLE sum_reg : unsigned(precision_size - 1 DOWNTO 0);
begin
    sum_reg := (OTHERS => '0');
        FOR i IN 0 TO precision_size + N - 1 LOOP
        --report " entered FOR with i = " & integer'image(i) ;
        IF (i REM 4 = 0 AND i > 0) THEN
            sum_reg := sum_reg + resize(shift_right(unsigned(psum(0)), i - 1), precision_size);
            sum_reg := sum_reg + resize(shift_right(unsigned(psum(0)), i), precision_size);
        END IF;
    END LOOP;
    quotient_out <= shift_right(unsigned(sum_reg), 2);
end process;
   
end Behavioral;

Guest
 

Re: Questions regarding connection to Xillybus FIFO

Postby support »

Hello,

Frankly speaking, I can't figure out what you were trying to do. But I can see that you interface directly with the user_r_read_32_* signals, which is generally an indication that you're on the wrong path, except for special cases.

The way to interact with Xillybus' IP core is through a FIFO, not instead of it: You should feed the data you're generating (with "engine") into a FIFO (possibly fifo_32x512) by writing to it, and let the IP core fetch the data from it through the FIFO's read interface at will.

In other words, start from the original xillydemo.vhd and disconnect the user_w_write_32_* signals from the FIFO (this breaks the loopback, which is what you want). Then connect your own signals instead, so they write data into the FIFO. That's it.

I suggest making yourself acquainted with FPGA FIFOs in general. This might help: https://www.youtube.com/watch?v=Nr8q5VW-mXI

Regards,
Eli
support
 
Posts: 802
Joined:

Re: Questions regarding connection to Xillybus FIFO

Postby rsabedra »

Hey Eli,

Thank you so much for your quick and precise answer.
I have watched the video and it's pretty good.
I will update my code following your advice and post the results here, in order to help people
that may have the same mistake.

Best regards,

Ricardo.
rsabedra
 
Posts: 1
Joined:


Return to Xillybus