Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
746 views
in Technique[技术] by (71.8m points)

fpga - FIFO implementation - VHDL

I come across one more difficulty while instantiate the fifo code to my top module. I want to store some set of data say "WELCOME TO THE WORLD OF FPGA" from my serial port ( receiving subsystem) then i want to retrieve it back say when button on fpga board is pressed or FIFO is full. I have my fifo code and serial communication code written. Idea is data sent from keyboard ->receiving subsystem -> FIFO -> transmitting subsystem -> hyperterminal. I am at present using fifo of 8 bit wide and say 28 deep just to store some small data. Please help me in this regard how can I implement it.I have byte coming from receiver saved in register_save. fifo code

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;      

Just added the corrected code now which seems to be working. Problem araises when increase the depth of fifo. When depth>2 then every third byte is missing. Please help, why I am loosing data.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The principe of a fifo is First In First Out. You have not to manage it.

  1. You place your data on input of fifo
  2. You set write enable bit to '1'
  3. You wait for one clock cycle
  4. You set write enable bit to '0'

then the data is store, you do it again to store another value.

When you want to read all data (Fifo full / any case you want)

You set Read enable bit to '1' and every clock cycle, you will receive a data.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...