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;