I connected my own FIFO to xillydemo. More precisely, xillydemo receives some data, it has to convert the data and the forward the data to FIFO. in turn the FIFO should send data back to xillydemo. What I want to do is to convert (in xillydemo.vhd
) one every eight characters from upper case to lower case (and viceversa) and then send all of them to STD_FIFO. (E.g: input string in xillydemo.vhd is "HelloMyNameIsJohnAndIWorkInUK" then the string to be sent to STD_FIFO should be "helloMyNAmeIsJohNAndIWorKInUK").
To do this, I defined 4 signals wr_en
, full
, din
and counter
in xillydemo.vhd. wr_en
, full
and din
are connected to user_w_write_8_wren
, user_w_write_8_full
and user_w_write_8_data
xillydemosignals respectively. The counter
is used to count from 0 to 7 in order to convert only the first char. The problem of my code is that it does not output anything. E.g., if the xillydemo input string is "HelloMyNameIsJohnAndIWorkInUK", the string sent back from STD_FIFO to xillydemo is empty.
NOTE: the problem is not similar to this question because the user suggested to go in this other question. The difference between this question and the two linked questions is that here I want to send to FIFO the swapped characters and not convert them into FIFO logic.
Here xillydmeo.vhd:
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(3 DOWNTO 0);
PCIE_RX_P : IN std_logic_vector(3 DOWNTO 0);
GPIO_LED : OUT std_logic_vector(3 DOWNTO 0);
PCIE_TX_N : OUT std_logic_vector(3 DOWNTO 0);
PCIE_TX_P : OUT std_logic_vector(3 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(3 DOWNTO 0);
PCIE_RX_P : IN std_logic_vector(3 DOWNTO 0);
GPIO_LED : OUT std_logic_vector(3 DOWNTO 0);
PCIE_TX_N : OUT std_logic_vector(3 DOWNTO 0);
PCIE_TX_P : OUT std_logic_vector(3 DOWNTO 0);
bus_clk : OUT std_logic;
quiesce : 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_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 STD_FIFO
port (
CLK: IN std_logic;
RST: IN std_logic;
DataIn: IN std_logic_VECTOR(7 downto 0);
WriteEn: IN std_logic;
ReadEn: IN std_logic;
DataOut: OUT std_logic_VECTOR(7 downto 0);
Full: OUT std_logic;
Empty: OUT std_logic);
end component;
signal bus_clk : std_logic;
signal quiesce : std_logic;
signal reset_8 : 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_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 wr_en : std_logic := '0';
signal din : std_logic_vector(user_w_write_8_data'range) := (others => '0');
signal counter : integer := 0;
signal full : std_logic := '0';
begin
xillybus_ins : xillybus
port map (
-- 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 => user_r_read_8_data,
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_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
);
process (bus_clk)
begin
if (bus_clk'event and bus_clk = '1') then
if (reset_8 = '1') then
counter <= 0;
else
wr_en <= user_w_write_8_wren;
full <= user_w_write_8_full;
if (user_w_write_8_wren='1') then
din <= user_w_write_8_data;
if counter=0 then
--From upper case to lower case
if (user_w_write_8_data="01000001") then --A
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01000010") then --B
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01000011") then --C
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01000100") then --D
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01000101") then --E
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01000110") then --F
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01000111") then --G
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001000") then --H
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001001") then --I
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001010") then --J
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001011") then --K
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001100") then --L
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001101") then --M
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001110") then --N
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01001111") then --O
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010000") then --P
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010001") then --Q
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010010") then --R
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010011") then --S
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010100") then --T
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010101") then --U
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010110") then --V
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01010111") then --W
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01011000") then --X
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01011001") then --Y
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01011010") then --Z
din(5) <= not user_w_write_8_data(5);
--From lower case to upper case
elsif (user_w_write_8_data="01100001") then --a
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01100010") then --b
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01100011") then --c
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01100100") then --d
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01100101") then --e
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01100110") then --f
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01100111") then --g
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101000") then --h
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101001") then --i
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101010") then --j
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101011") then --k
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101100") then --l
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101101") then --m
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101110") then --n
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01101111") then --o
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110000") then --p
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110001") then --q
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110010") then --r
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110011") then --s
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110100") then --t
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110101") then --u
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110110") then --v
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01110111") then --w
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01111000") then --x
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01111001") then --y
din(5) <= not user_w_write_8_data(5);
elsif (user_w_write_8_data="01111010") then --z
din(5) <= not user_w_write_8_data(5);
end if;
end if;
if (counter=7) then
counter <= 0;
else
counter <= counter+1;
end if;
end if;
end if;
end if;
end process;
my_fifo : STD_FIFO
port map(
CLK => bus_clk,
RST => reset_8,
DataIn => din,
WriteEn => wr_en,
ReadEn => user_r_read_8_rden,
DataOut => user_r_read_8_data,
Full => full,
Empty => user_r_read_8_empty
);
reset_8 <= not (user_w_write_8_open or user_r_read_8_open);
user_r_read_8_eof <= user_r_read_8_empty and not(user_w_write_8_open);
end sample_arch;
Here FIFO code
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
entity STD_FIFO is
Generic (
constant DATA_WIDTH : positive := 8;
constant FIFO_DEPTH : positive := 3
);
Port (
CLK : in STD_LOGIC;
RST : in STD_LOGIC;
WriteEn : in STD_LOGIC;
DataIn : in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
ReadEn : in STD_LOGIC;
DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
Empty : out STD_LOGIC;
Full : out STD_LOGIC
);
end STD_FIFO;
architecture Behavioral of STD_FIFO is
begin
-- Memory Pointer Process
fifo_proc : process (CLK)
type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
variable Memory : FIFO_Memory;
variable Head : natural range 0 to FIFO_DEPTH - 1;
variable Tail : natural range 0 to FIFO_DEPTH - 1;
variable Looped : boolean;
begin
if rising_edge(CLK) then
if RST = '1' then
Head := 0;
Tail := 0;
Looped := false;
Full <= '0';
Empty <= '1';
else
if (ReadEn = '1') then
if ((Looped = true) or (Head /= Tail)) then
-- Update data output
DataOut <= Memory(Tail);
-- Update Tail pointer as needed
if (Tail = FIFO_DEPTH - 1) then
Tail := 0;
Looped := false;
else
Tail := Tail + 1;
end if;
end if;
end if;
if (WriteEn = '1') then
if ((Looped = false) or (Head /= Tail)) then
-- Write Data to Memory
Memory(Head) := DataIn;
-- Increment Head pointer as needed
if (Head = FIFO_DEPTH - 1) then
Head := 0;
Looped := true;
else
Head := Head + 1;
end if;
end if;
end if;
-- Update Empty and Full flags
if (Head = Tail) then
if Looped then
Full <= '1';
else
Empty <= '1';
end if;
else
Empty <= '0';
Full <= '0';
end if;
end if;
end if;
end process;
end Behavioral;
Best Answer
A simple solution would be to use a Mealy Machine. Here, you would only intercept the data
user_w_write_8_data
which will be written to the FIFO. All control signals associated with the write side should be left as in the original XillyBus demo. Thus, the instantiation of yourSTD_FIFO
will be:Instead of
STD_FIFO
you can also use the componentfifo_8x2048
of the XillyBus demo.The Mealy Machine will then have a counter which is incremented with every write. Whenever the counter state is 0, the write data
user_w_write_8_data
is modified and assigned to signaldin
which is connected to the FIFO. In all other cases, the original value ofuser_w_write_8_data
is assigned todin
.Thus, the code of the clocked process would look like this:
The Mealy Machine will have another process which defines the output for the current cycle based on the current state of the counter (or any other state variable). You must list all signals in any expression in the process sensitivity list. You must also assign a value to every output in every control path, otherwise you will get unintended latches. The latter is ensured by assigning a default value at the beginning of the process and overwrite it later on. Always the last assignment (before a
wait
) wins.