Исследование параметризованного модуля LPM_FIFO. Устройство передачи данных с FIFO, страница 3

          variable count : integer range 0 to 3;

     BEGIN

          if (CLK25'event) and (CLK25 = '1') then

                count := (count + 1) mod 4;

                if (CLK_in = '1') then

                     if ( count = 3) then WRREQ_tmp <= '1';

                     else WRREQ_tmp <= '0';

                     end if;

                else WRREQ_tmp <= '0';

                end if;

          end if;

     END PROCESS;

END SYNCR_arch;

             Блок SYNCR необходим для синхронизации входных данных. Частота входного канала меньше, чем частота работы FIFO, поэтому в зависимости от  CLK_in, CLK25 необходимо формировать запрос разрешения записи в  FIFO.

            Синтезированная схема в RTL Viewer:


Рис. 2.2. Блок SYNCR.

             SYNCR состоит из счетчика по модулю 4, работающего по тактовому сигналу CLK25. И в зависимости от состояния счетчика и входной тактовой частоты подается сигнал разрешения записи в FIFO.

            Диаграмма работы  SYNCR.


Рис. 2.3. Диаграмма работы SYNCR.

Листинг 2TX_CONTROL.vhd.

LIBRARY IEEE;

USE IEEE.std_logic_1164.all;

USE IEEE.std_logic_arith.all;

ENTITY TX_CONTROL is

       port(

             CLK25:              in std_logic;

             D_FIFO:             in std_logic_vector (7 downto 0);

             EMPTY:              in std_logic;

             USEDW:       in unsigned (5 downto 0);

             DATA_out:    out std_logic_vector (7 downto 0);

             RDREQ:              out std_logic;

             CLK_out:     out std_logic

             );

END TX_CONTROL;

ARCHITECTURE TX_CONTROL_arch of TX_CONTROL is

       type   state_type is (q_H1,q_N,q_DATA,q_T1);

       signal TX_state:    state_type;

       signal COUNT_CLK:   integer range 0 to 1;

       signal CLKtmp:             std_logic;

       signal timer:       std_logic;

       signal COUNT_2us:   integer range 0 to 49;

       signal DATA_len:    integer range 0 to 8;

BEGIN

CLK_out <= CLKtmp;

PROCESS (CLK25,TX_state, USEDW, EMPTY)

       variable PACK_LEN : integer range 0 to 23;

BEGIN

       if rising_edge(CLK25) then

             COUNT_CLK <= (COUNT_CLK + 1) mod 2;

             CLKtmp <= '0';

              if (COUNT_CLK mod 4) = 1 then

                    CLKtmp <= '1';

             end if;

             if (COUNT_CLK mod 2) = 1 then

                    case TX_state is   

                           when q_H1 =>

                                  RDREQ <= '0';

                           when q_N =>

                                  if (DATA_len /= 0) then RDREQ <= '1';

                                  else RDREQ <= '0'; end if;

                           when q_DATA =>

                                  if (DATA_len > 1) then RDREQ <= '1';

                                  else RDREQ <= '0'; end if;

                           when q_T1 =>

                                  RDREQ <= '0';

                    end case;

             else

                    RDREQ <= '0';

             end if;

       end if;

END PROCESS;

PROCESS (CLKtmp)

BEGIN

       if falling_edge(CLKtmp) then

             case TX_state is