Cómo convertir datos antes de enviarlos a FIFO [Xillybus - VHDL]

0

Conecté mi propio FIFO a xillydemo. Más precisamente, xillydemo recibe algunos datos, tiene que convertir los datos y enviar los datos a FIFO. a su vez, el FIFO debe enviar datos a xillydemo. Lo que quiero hacer es convertir (en xillydemo.vhd ) uno cada ocho caracteres de mayúsculas a minúsculas (y viceversa) y luego enviarlos a STD_FIFO. (Por ejemplo, la cadena de entrada en xillydemo.vhd es "HelloMyNameIsJohnAndIWorkInUK", la cadena que se enviará a STD_FIFO debe ser "helloMyNAmeIsJohNAndIWorKInUK").

Para hacer esto, definí 4 señales wr_en , full , din y counter en xillydemo.vhd. wr_en , full y din están conectados a user_w_write_8_wren , user_w_write_8_full y user_w_write_8_data xillydemosignals respectivamente. El counter se usa para contar de 0 a 7 para convertir solo el primer char. El problema de mi código es que no genera nada. Por ejemplo, si la cadena de entrada xillydemo es "HelloMyNameIsJohnAndIWorkInUK", la cadena enviada de STD_FIFO a xillydemo está vacía.

NOTA: el problema no es similar a este pregunta porque el usuario sugirió ir a esta otra pregunta . La diferencia entre esta pregunta y las dos preguntas vinculadas es que aquí quiero enviar a FIFO los caracteres intercambiados y no convertirlos en lógica FIFO.

Aquí 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;

Aquí el código FIFO

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;
    
pregunta Message Passing

2 respuestas

1

Una solución simple sería utilizar una Mealy Machine . Aquí, solo interceptaría los datos user_w_write_8_data que se escribirán en el FIFO. Todas las señales de control asociadas con el lado de escritura deben dejarse como en la demostración original de XillyBus. Por lo tanto, la creación de instancias de su STD_FIFO será:

  my_fifo : STD_FIFO
    port map(
          CLK       => bus_clk,
          RST       => reset_8,
          DataIn    => din,                 -- modified data to write
          WriteEn   => user_w_write_8_wren, -- as in original demo!
          ReadEn    => user_r_read_8_rden,
          DataOut   => user_r_read_8_data,
          Full      => user_w_write_8_full, -- as in original demo!
          Empty     => user_r_read_8_empty
      );

En lugar de STD_FIFO , también puedes usar el componente fifo_8x2048 de la demostración de XillyBus.

La máquina Mealy tendrá un contador que se incrementa con cada escritura. Cuando el estado del contador es 0, los datos de escritura user_w_write_8_data se modifican y asignan a la señal din que está conectada a la FIFO. En todos los demás casos, el valor original de user_w_write_8_data se asigna a din .

Por lo tanto, el código del proceso cronometrado se vería así:

  process (bus_clk)
  begin 
        if (bus_clk'event and bus_clk = '1') then
            if (reset_8 = '1') then 
                counter <= 0;
             elsif (user_w_write_8_wren='1') then
                if counter = 7 then counter <= 0;
                else                counter <= counter + 1;
                end if;
             end if;
        end if;
  end process;

La máquina Mealy tendrá otro proceso que define la salida para el ciclo actual en función del estado actual del contador (o de cualquier otra variable de estado). Debe enumerar todas las señales en cualquier expresión en la lista de sensibilidad del proceso. También debe asignar un valor a cada salida en cada ruta de control, de lo contrario obtendrá pestillos involuntarios. Esto último se garantiza asignando un valor predeterminado al comienzo del proceso y sobrescribiéndolo más adelante. Siempre gana la última asignación (antes de wait ).

  process(counter, user_w_write_8_data)
  begin
     -- This is the default assignment which might be overriden below.
     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
            --
            -- And so on
            --
        end if;
     end if;
  end process;
    
respondido por el Martin Zabel
0

No tengo suficiente reputación para comentar, pero debes ser más específico sobre el problema.

  • ¿Está en simulación que tu código no funciona?
  • ¿Qué salida está vacía?
  • ¿Cuál es la entrada de FIFO?
respondido por el Rasmus B. Sorensen

Lea otras preguntas en las etiquetas