1
\$\begingroup\$

I want to develop an application that is able to get and store two input values, swap from lower case to upper case only the first value and finally output the two stored values. E.g.: if the input string is "john", then the output string should be "JoHn". The application should get "j" from user_w_write_8_data and store it into my_buffer_a, swap "j" into "J", then get "o" store it into my_buffer_b, then output "J", then output "o". After that the application should get "h" from user_w_write_8_data, swap "h" into "H", and store it into my_buffer_a, then get "n" store it into my_buffer_b, then output "H", then output "n". Basically, the application should store two characters, swap the first one and then output these two, store other two characters, swap the first one and then output these two characters etc. The problem of my application does not swap lower to upper characters that is stored into my_buffer_a. Instead of outputing "JoHn", my application outputs blank line and input random char. My app is based on this code link but I opened a new topic because this logic is quite different! As suggested, I control signals like wr_en , din and full of the XillyBus as well. One more thing, unfortunately I cannot run the simulation but only generate the bitfile and test it right away on my FPGA.

Thanks.

Here the code:

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_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 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 wr_en : std_logic := '0';
 signal rd_en : std_logic := '0';
 signal full : std_logic := '0';
 signal empty : std_logic := '0';
 signal my_buffer_a : std_logic_vector(7 downto 0) := (others => '0');
 signal my_buffer_b : std_logic_vector(7 downto 0) := (others => '0');
 signal counter : integer := 0;
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 => 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_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
 ram_addr <= conv_integer(user_mem_8_addr);
 process (bus_clk)
 begin 
 if (bus_clk'event and bus_clk = '1') then 
 wr_en <= user_w_write_8_wren;
 full <= user_w_write_8_full; 
 if (user_w_write_8_wren='1' and counter = 0) then
 my_buffer_a <= user_w_write_8_data;
 counter <= 1;
 elsif (user_w_write_8_wren='1' and counter = 1) then
 my_buffer_b <= user_w_write_8_data;
 counter <= 2;
 elsif (counter = 2) then
 full <= '1';
 din <= my_buffer_a;
 counter <= 3;
 elsif (counter = 3) then
 full <= '1';
 din <= my_buffer_b;
 counter <= 0;
 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 => user_r_read_32_rden,
 dout => user_r_read_32_data,
 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 => din,
 wr_en => wr_en,
 rd_en => user_r_read_8_rden,
 dout => 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 <= '0';
end sample_arch;

EDIT: Now, counter and buffers are signals instead of variables, so I'm sure they'll be sampled on the next clock cycle. Here, I would like to put some comments about my logic because I do not understand why it does not work.

begin 
if (bus_clk'event and bus_clk = '1') then 
 wr_en <= user_w_write_8_wren; --initialize wr_en
 full <= user_w_write_8_full; --initialize full 
 if (user_w_write_8_wren='1' and counter = 0) then --there data on write device file
 my_buffer_a <= user_w_write_8_data; --move the input data on buffer_a
 counter <= 1;
 elsif (user_w_write_8_wren='1' and counter = 1) then --there data on write device file
 my_buffer_b <= user_w_write_8_data; --move the input data on buffer_b
 counter <= 2;
 elsif (counter = 2) then
 full <= '1'; --do not accept more data
 din <= my_buffer_a; --take data stored in buffer_a and move it into read_device_file
 counter <= 3;
 elsif (counter = 3) then
 full <= '1'; --do not accept more data
 din <= my_buffer_b; --take data stored in buffer_b and move it into read_device_file
 counter <= 0;
 end if;
end if;
end process;

1-Why should I have to initialize rd_en and empty? Well, I don't understand where I have to use them in my logic. I think I do not need information about read_device_file such as no more data can be read or there is valid data on read_device_file.

2-Why does wr_en contain the old value of user_w_write_8_wren? Since I do wr_en <= user_w_write_8_wren;, wr_en should contain the actual value of user_w_write_8_wren, isn't it?

asked Dec 16, 2015 at 11:15
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Please note, that the code in the question you have linked is broken. Please read the documentation on XillyBus and start a new Implementation. \$\endgroup\$ Commented Dec 16, 2015 at 11:27
  • \$\begingroup\$ With this code I am able to generate the bitfile. I read the documentation and what I have got is that I have to play with user_w_write_8_data to get data from write device file and put it into FIFO and with user_r_mem_8_data to take data from FIFO and put it into read device file. I do all checks when the clock is 1. I don't understand why it does not work. Can you tell me where is broken? \$\endgroup\$ Commented Dec 16, 2015 at 12:44
  • 1
    \$\begingroup\$ You have to respect all the other control signals like rden , wren , full and empty of the XillyBus as well. \$\endgroup\$ Commented Dec 16, 2015 at 12:55
  • \$\begingroup\$ Now we have a better look. Please note that you rely on the old values of wr_en in the if(wr_en conditions. Is this really intended or do you want to check the actual value of user_w_write_8_wren. \$\endgroup\$ Commented Dec 16, 2015 at 17:44

1 Answer 1

1
\$\begingroup\$

1-Why should I have to initialize rd_en and empty?

You have not to "initialize" this signals. Just connect them properly to the XillyBus.

The output empty of the FIFO indicates whether data is available in the FIFO. If it's low, then more data can be read from the FIFO. This output should be connected to the signal user_r_read_8_empty which is connected to the same-named input of the XillyBus.

The input rd_en of the FIFO should be connected to the signal user_r_read_8_rden which is connected to the same-named output of the XillyBus. This signal is driven high by the XillyBus, if it wants to read data from the FIFO.

For you intended design, you have to replace the FIFO as described at the end of this answer.

2-Why does wr_en contain the old value of user_w_write_8_wren?

Because signal assigments in a process (with operator <=) are delayed until the next wait statement. Only variable assigments (with operator :=) have an immediate effect.

Your process(bus_clk) does not have an explicit wait statement. But, it has an implicit one, because a process with a sensitivity list (the (bus_clock)) is equal to a process without a sensitivity list with a wait on statement at the end. Thus, your code equals:

process
begin 
 if (bus_clk'event and bus_clk = '1') then 
 wr_en <= user_w_write_8_wren;
 full <= user_w_write_8_full; 
 if (user_w_write_8_wren='1' and counter = 0) then
 ...
 end if;
 end if;
 wait on bus_clock;
end process;

The signal assignments to wr_en and full (as well as all other signal assigments in this process) are applied at the end of the process. Thus, if you would check the value of wr_en in the if conditions, always the still valid old value would be used.

For example, in hardware the signal wr_en would be implemented with a D flip-flop which is triggered by the rising edge of bus_clk here. The signal wr_en would be the output of the D flip-flop and the expression on the right side of the signal assignment (user_w_write_8_wren) the input of this D flip-flop. Thus, wr_en is user_w_write_8_wren delayed by one clock cycle in this example.

How you should proceed:

I recommend to restart from the XillyBus loopback demo (xillydemo). Then you should encapsulate your own logic into a separaty entity which replaces the FIFO fifo_8. More on this topic, I have written in an answer to the other question.

answered Dec 19, 2015 at 10:49
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.