Реализация FIFO - VHDL

Я столкнулся с еще одной трудностью при создании экземпляра кода fifo в моем верхнем модуле. Я хочу сохранить некоторый набор данных, скажем "ДОБРО ПОЖАЛОВАТЬ В МИР ПЛИС", из моего последовательного порта (принимающей подсистемы), а затем я хочу получить его обратно, скажем, когда кнопка на плате fpga нажата или FIFO заполнен. У меня есть мой код fifo и код последовательной связи. Идея - данные, отправленные с клавиатуры -> принимающая подсистема -> FIFO -> передающая подсистема -> гипертерминал. В настоящее время я использую FIFO шириной 8 бит и говорю 28 глубиной только для хранения небольших данных. Пожалуйста, помогите мне в этом отношении, как я могу реализовать это. У меня есть байт, поступающий от получателя, сохраненный в register_save. код FIFO

inst_bit8_recieve_unit : entity work.byte_recieve_8N1  
port map ( ck => ck,
         reset => reset, 
         new_byte_in_buffer => new_byte_in_buffer,
         byte_read_from_buffer => byte_read_from_buffer,
         recieve_buffer => register_save,
         JA_2 => JA(2));

---------------------FIFO instantiate-------------------------------
inst_of_fifo_Recieve_unit : entity work.fifo
generic map (B => data_bits, W => fifo_width)
port map ( ck => ck,
            reset => reset, 
            rd => rd_rx, 
            wr => wr_rx,
            write_data => num_recieved,
            read_data => num_recieved_fifo,
            empty => empty_rx,
            full => full_rx );

inst_bit8_transmit_unit : entity work.byte_transmit_8N1  
port map ( ck => ck,
           reset => reset, 
           send_byte_ready => send_byte_ready,
           send_byte_done => send_byte_done , 
           send_buffer => num_send, 
           JAOUT_0 => JAOUT );
proc_send5byte: process(ck, reset, state_byte5, send_byte_done, num_send, state_button_0, num_recieved_fifo, rd_rx) 

begin

if reset = '1' THEN
            state_byte5 <= idle;
            send_byte_ready <='0';
            num_send <= "00000000" ;

  else
  if rising_edge(ck) then

    case state_byte5 is 

         when idle =>          ---- in this, if btn(0) is high i.e pressed then only state_byte5 will go to next state
                if state_button_0 = transit_pressed then
                     state_byte5 <= byte;
                     end if; 
            -----===============================================================      
            when byte =>
                    if (not empty_rx = '1') then

                           if send_byte_ready ='0' and send_byte_done = '0'  then    ----here if condition is satified the send_byte_ready will be set
                                    send_byte_ready <='1';  --------- shows next byte is ready 
                                    num_send <= num_recieved_fifo;
                                     rd_rx <='1';

                         end if;
                            end if; 

                       if send_byte_ready = '1' and send_byte_done = '1'  then  --- during load state send_byte will be resets 
                         send_byte_ready <='0';  
                         rd_rx <= '0';                               
                              state_byte5  <= idle;         ----------- go back to idle
                       end if;
                --end if;  
            ---===============================================================

         when others =>
                        state_byte5 <= idle;     ------------- for other cases state state _byte5 will be in idle
                        send_byte_ready <= '0';
                            rd_rx <= '0';   
       end case;

   end if;
end if; 
end process;
proc_recieving_byte : process (ck, reset, register_save, new_byte_in_buffer, full_rx, num_recieved, wr_rx)
begin

if reset = '1' then
  byte_read_from_buffer <= '0';
  else

      if rising_edge(ck) then
                     if full_rx = '0' then     
                         if new_byte_in_buffer = '1' and byte_read_from_buffer = '0' then
                              byte_read_from_buffer <= '1'; 
                       wr_rx <= '1';                      
                             num_recieved(7 downto 0 ) <= register_save( 7 downto 0);   

                    end if;   
                        end if; 
                            if new_byte_in_buffer = '0' then
                               byte_read_from_buffer <= '0';
                                wr_rx <= '0';
                       end if;                      
                   --end if;
     end if;
end if;
end process;      

Просто добавил исправленный код, который сейчас работает. Проблема возникает при увеличении глубины fifo. Когда глубина>2, то каждый третий байт отсутствует. Пожалуйста, помогите, почему я теряю данные.

2 ответа

Принцип пятерки - "первым пришел - первым вышел". Вы не должны управлять этим.

  1. Вы размещаете свои данные на входе fifo
  2. Вы установили бит разрешения записи на "1"
  3. Вы ждете один такт
  4. Вы установили бит разрешения записи на "0"

затем данные сохраняются, вы делаете это снова, чтобы сохранить другое значение.

Когда вы хотите прочитать все данные (Fifo полный / любой случай, который вы хотите)

Вы устанавливаете бит разрешения чтения на "1", и каждый тактовый цикл вы будете получать данные.

--- process for recieving bytes and sent to fifo input with write enable signal------------ 

proc_recieving_byte : process (ck, reset, register_save, new_byte_in_buffer, full_rx, num_recieved, wr_rx)
begin

if reset = '1' then
  byte_read_from_buffer <= '0';
  else

   if rising_edge(ck) then
           if full_rx = '0' then     
               if new_byte_in_buffer = '1' and byte_read_from_buffer = '0' then
                  byte_read_from_buffer <= '1'; 
                 wr_rx <= '1';                      
                     num_recieved(7 downto 0 ) <= register_save( 7 downto 0);   
               else
                      wr_rx <= '0';
             end if;      
            end if; 
            if new_byte_in_buffer = '0' then
               byte_read_from_buffer <= '0';
                wr_rx <= '0';
           end if;                      
   end if;
end if;
end process;      
------------------------------------------------------------------------------------------------------------------- 


---- this process checks first button state and then  transmission occurs from fifo untill empty------

proc_send5byte: process(ck, reset, state_byte5, send_byte_done, num_send, state_button_0, num_recieved_fifo, rd_rx) 

begin

if reset = '1' THEN
            state_byte5 <= idle;
            send_byte_ready <='0';
            num_send <= "00000000" ;

  else
  if rising_edge(ck) then
    case state_byte5 is 
         when idle =>          ---- in this, if btn(0) is high i.e pressed then only state_byte5 will go to next state
                if state_button_0 = transit_pressed then
                     state_byte5 <= byte;
                     end if; 
            -----===============================================================      
            when byte =>
               if (not empty_rx = '1') then
                        if send_byte_ready ='0' and send_byte_done = '0'  then    ----here if condition is satified the send_byte_ready will be set
                             send_byte_ready <='1';  --------- shows next byte is ready 
                            num_send <= num_recieved_fifo;
                             rd_rx <='1';
                   else 
                         rd_rx <='0';
                   end if;
                    end if; 

                if send_byte_ready = '1' and send_byte_done = '1'  then  --- during load state send_byte will be resets 
                  send_byte_ready <='0';  
                  rd_rx <= '0';                              
                       state_byte5  <= idle;         ----------- go back to idle
                   end if;
            ---===============================================================

       when others =>
                  state_byte5 <= idle;    
                  send_byte_ready <= '0';
                    rd_rx <= '0';   
    end case;

  end if;
end if; 

end process;

Просто нашел ошибку и исправил, как указано выше, которая работает очень хорошо. Комментарии к улучшению приветствуются.

Другие вопросы по тегам