0
\$\begingroup\$
library IEEE;  
use IEEE.STD_LOGIC_1164.ALL;  
use IEEE.STD_LOGIC_ARITH.ALL;  
--use IEEE.STD_LOGIC_UNSIGNED.ALL;  
use ieee.std_logic_signed.all;  

entity fifo is  
    port (  clk : in std_logic;  
          read_data : in   std_logic;                                       --enable read,should be '0' when not in use.  
          insert : in   std_logic;                                          --enable write,should be '0' when not in use.  
          delete : in std_logic;  
          datain : in std_logic_vector (7 downto   0);                      --input data  
          dataout : out std_logic_vector(7 downto   0);                 --output data           
          empty : out std_logic :=   '1';                                   --set   as '1' when the queue is empty  
          full : out std_logic  :=   '0';                                       --set as '1' when the queue is full  
          no_insert : out std_logic;  
          no_delete : out std_logic  
         );  
end fifo;  

architecture Behavioral of fifo is  
    type memory_type is array (0 to 255) of std_logic_vector(7 downto 0);  
    signal memory : memory_type :=(others => (others =>   '0'));            --memory for queue.  
    signal rp,wp,tmp_ptr : std_logic_vector(7 downto 0) :="00000000";       --read and write pointers.  
    signal isfull : std_logic := '0';  
    signal isempty : std_logic := '1';  
    begin  
        --dataout <= "00000000";  
        process(clk)  
        begin  
            -- Reading Process                     
                -- Read when not empty  
                -- empty when Write_ptr = Read_ptr  
                -- increment as 0 1 2....255 0 1 2....255  
                -- If Last_wrt is high set low Last_rd,  
                -- overwrite Last_rd as high if actually   reading take place  
            if(clk'event and clk='1' and read_data ='1')   then                         --read the tail of FIFO  
                --if(isempty = '1') then  
                --  dataout <= "00000000";  
                --else   
                    dataout <= memory(conv_integer(rp));  
                --end if;  
            end if;  
            if(clk'event and clk='1' and insert ='1')   then                                --insert on the   top/head of FIFO  
                --if(isfull = '1') then   
                    --no_insert <= '1 ;  
                    --dataout <= "00000000";  
                --else  
                    no_insert <= '0';  
                    memory(conv_integer(wp)) <= datain;  
                    dataout <= datain;  
                    --if(wp = "11111111") then  
                    --  wp <= "00000000";  
                    --else   
                    --  wp <= wp + 1;  
                    --end if;  
                --end if;  
                --if(wp = rp) then  
                --      full <= '1';  
                --      isfull <= '1';  
                --  else   
                --      full <= '0';  
                --      isfull <= '0';  
                --end if;  
            end if;  

            if(clk'event and clk='1' and delete ='1')   then                            --pop/delete the tail   of FIFO  
                --if(isempty = '1') then  
                --  no_delete <='1';  
                --  dataout <= "00000000";  
                --else   
                    no_delete <= '0';  
                    dataout <= memory(conv_integer(rp));  
                --  if(rp = "11111111") then  
                --      rp <= "00000000";  
                --  else   
                        rp <= rp + 1;  
                --  end if;  
                --  if(rp = wp) then  
                --      empty <= '1';  
                --      isempty <= '1';  
                --  else  
                --      empty <= '0';  
                --      isempty <= '0';  
                --  end if;  
                --end if;  
            end if;  
            if(rp = "11111111")   then                                          --resetting read pointer.  
                rp <= "00000000";  
            end if;  
            if(wp = "11111111")   then                                          --resetting read pointer.  
                wp <= "00000000";  
            end if;  

            if(wp = rp and insert = '1')   then                                         --checking whether queue is full or not  
                full <='1';               
            else  
                full <='0';  
            end if;  

            if(wp = rp and delete = '1')   then                                     --checking whether queue is empty or not  
                empty <='1';  
            else  
                empty <='0';  
            end if;       
        end process;  

end Behavioral;

In the above vhdl code for FIFO I am not actually getting the write testbench simulation. Even though the FIFO buffer is not full then also full becomes equal to 1. Can some1 please help me sort out the error ?

when the process(clk) is run everytime on the clk tick then what exactly happens .... are all the ifs called simultaneously ?I mean all the different functions in the process(clk) block rum at the same time in parallel ?

\$\endgroup\$
  • 5
    \$\begingroup\$ Please consider removing all the commented code. I know you probably commented this out while debugging, but it does not help people on this site understand your problem. \$\endgroup\$ – Philippe Apr 25 '11 at 17:51
4
\$\begingroup\$

Your problem is that you are mixing combinational and sequential logic.

Each process should either be combinational, or sequential. Sequential processes have everything (except the reset statements inside a clock detection (if rising_edge(clk) or if clk'event and clk='1'). Combinational processes have a sensitivity list that contains all signals that you read.

While your code is perfectly legal and even deterministic, there is no easy way to predict how it will be synthesized, so it is not suited for RTL code.

\$\endgroup\$
  • \$\begingroup\$ Most synthers ignore the process sensitivity list anyway, so I imagine in practice that the code will synthesize valid RTL. His problem isn't really using combinatorial flags (which is perfectly valid), or forgetting to register the flags with clk'event (which is the smart thing to do). His problem is that the flags themselves are not generated correctly. See my comment below. \$\endgroup\$ – ajs410 Apr 27 '11 at 15:47
1
\$\begingroup\$

For your specific question on the full signal, it will definitely be full since both wp and rp are 0 at the start. Plus, you are not using a register to clock the full signal. This can potentially result in glitches in your output.

My advice to you would be to stop thinking of this in terms of code but to think of it in terms of hardware i.e. instead of asking if the 'ifs are called simultaneously' think of how the signals are wired up through multiplexers, registers and memory.

Then, code according to the hardware that you would like to generate, and not the other way around. There is a reason why it is a 'Hardware Description Language'.

As a start, there are any number of example FIFO designs around that you might want to study first.

Good luck!

\$\endgroup\$
1
\$\begingroup\$

The problem is that your full and empty flags are being enabled by the insert and delete control signals. The full flag will only be asserted when wp = rp and insert = '1'. If insert /= '1', then your full flag won't be asserted. So, unless you're actively inserting an item into the FIFO, it won't tell you that it's full.

Also, the full flag should be when the write pointer + 1 = read pointer (i.e. if adding an item would then make the write pointer equal the read pointer).

You should get rid of the "insert = '1'" and "delete = '1'" checks, so that your full and empty flags will be asserted regardless of the control signals.

Directly inside your Process block should be only a single if statement, which is clk'event or rising_edge (I prefer rising_edge). This represents the clock input of all the flops.

All of your other if statements are nested inside the rising_edge if. These would be like the enable input of the flops.

If the flags are outside of the rising_edge if, they will be combinational; i.e. they will be set regardless of the clock signal. To register the flags, include them inside the rising_edge if, and they will only change when the clock changes.

Regarding your question about the Process block, all if statements in a given Process block will execute simultaneously. HOWEVER, when mulitple if statements assign a value to the same signal, the last if statement will "win", because the statements inside the Process block are executed sequentially, despite occurring simultaneously.

You should have only one line of code with clk'event (though I prefer rising_edge myself). Nested inside this if (which kinda represents the clock inputs of all the flops in the process block), there are more ifs (which kinda represent the enable inputs for all the flops).

\$\endgroup\$
  • \$\begingroup\$ The statements inside a process are executed sequentially. They are, by definition, sequential statements. However, they are executed within the same delta cycle, which means that no simulated time passes. Compare that to statements inside an architecture, which are concurrent statements. \$\endgroup\$ – Philippe Apr 27 '11 at 8:19
  • 1
    \$\begingroup\$ Precisely, that's why I said everything inside the Process is executed concurrently (i.e. same delta cycle), yet the last of multiple assignments will win (i.e. executed sequentially) \$\endgroup\$ – ajs410 Apr 27 '11 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.