Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] VHDL FIFO Implementation

Status
Not open for further replies.

chandlerbing65nm

Member level 5
Joined
Apr 5, 2018
Messages
80
Helped
0
Reputation
0
Reaction score
1
Trophy points
8
Activity points
709
I'm having difficulty in understanding the VHDL template for FIFO my instructor gave to me. Below is the instruction:

Using VHDL, Design a FIFO memory. Make it 8-deep, 9 bits wide. When a read signal is asserted, the output of the FIFO should be enabled, otherwise it should be high impedance. When the write signal is asserted, write to one of the 9 bit registers. Use RdInc and WrInc as input signals to increment the pointers that indicate which register to read or write. Use RdPtrClr and WrPtrClr as input signals which reset the pointers to point to the first register in the array. Do not implement full or empty signals.

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity FIFO8x9 is
   port(
      clk, rst:				in std_logic;
      RdPtrClr, WrPtrClr:	in std_logic;    
      RdInc, WrInc:			in std_logic;
      DataIn:	 			in std_logic_vector(8 downto 0);
      DataOut: 				out std_logic_vector(8 downto 0);
      rden, wren: 			in std_logic
	);
end entity FIFO8x9;

architecture RTL of FIFO8x9 is
	--signal declarations
	type fifo_array is array(7 downto 0) of std_logic_vector(8 downto 0);  -- makes use of VHDL’s enumerated type
	signal fifo:  fifo_array;
	signal wrptr, rdptr: unsigned(2 downto 0);
	signal en: std_logic_vector(7 downto 0);
	signal dmuxout: std_logic_vector(8 downto 0);

begin

So, there are no flags in this template. There should be no edit in the port list and signal/variable list.

Could anyone please give me information about how to use these in the code:
RdPtrClr -- Read Pointer Clear, to reset the read pointer
WrPtrClr -- Write Pointer Clear, to reset the write pointer
rdinc -- Read pointer increment signal
wrinc -- Write pointer increment signal

Seems to me that
signal en: std_logic_vector(7 downto 0);
is the incremental element, i.e en <= en + 1.

I have an idea in mind how to code this problem but not really sure if I'm correct especially the
signal wrptr, rdptr: unsigned(2 downto 0);
. How could I use this?
 
Last edited:

Looks like the FIFO memory is really just a register file with internal read write pointers, which makes the requirement of a "When a read signal is asserted, the output of the FIFO should be enabled, otherwise it should be high impedance" easy as there is no delay to read an actual RAM block (with a clock cycle delay).

for a signal you want to increment use unsigned and the numeric_std and numeric_unsigned packages. You will have to convert them to integers with to_integer function when you use them as indexes into the muxes/demuxes which selects one of the 8 registers.

I've probably already have said too much, for a homework problem, so I won't help any further.
 
I arrived with this code: (I found a code snippet in the internet and thought I could use it but I'm stuck)

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity FIFO8x9 is
   port(
      clk, rst:				in std_logic;
      RdPtrClr, WrPtrClr:	in std_logic;    
      RdInc, WrInc:			in std_logic;
      DataIn:	 			in std_logic_vector(8 downto 0);
      DataOut: 				out std_logic_vector(8 downto 0);
      rden, wren: 			in std_logic
	);
end entity FIFO8x9;

architecture RTL of FIFO8x9 is
	
	type fifo_array is array(7 downto 0) of std_logic_vector(8 downto 0);  -- makes use of VHDL’s enumerated type
	signal fifo:  fifo_array;
	
	signal wrptr, rdptr: unsigned(2 downto 0); --read/write pointer
	
	signal en: unsigned(7 downto 0); --count 
	
	signal dmuxout: std_logic_vector(8 downto 0); --DataOut
		
		begin fifo: process(clk, rst) 
			begin
				if rising_edge(clk) then
					if rst = '1' then
						wrptr <= 0;
						rdptr <= 0;
						en <= 0;
					else
					
						-- Keeps track of the total number of words in the FIFO
						if wren = '1' and rden = '1' then
						en <= en + 1;
						elsif wren = '0' and rden = '1' then
						en <= en - 1;
						end if;
						
						-- Keeps track of the write pointer (and controls roll-over)
						if (wren = '1' and WrPtrClr = '0') then
							if wrptr = "111" then
							wrptr <= "000";
							elsif WrInc = '1' then
							wrptr <= wrptr + 1;
							end if;
						end if;
						
						-- Keeps track of the read pointer (and controls roll-over) 
						if (rden = '1' and RdPtrClr = '0') then
							if rdptr = "111" then
							rdptr <= "000";
							elsif RdInc = '1' then
							rdptr <= rdptr + 1;
							end if;
						end if;
						
						-- Registers the input data when there is a write
						if wren = '1' then
						fifo(to_integer(wrptr)) <= DataIn;
						end if;
					end if;
				end if;
			end process fifo;
			DataOut <= fifo(to_integer(rdptr));
		end RTL;

Please tell me my mistakes here. Also, to what could I use the signal en and signal dmuxout. Badly need help, Thanks.
 

Got the final code:

Code:
library ieee;
--library work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; 

entity FIFO8x9 is
   port(
      clk, rst:				in std_logic;
      RdPtrClr, WrPtrClr:	in std_logic;    
      RdInc, WrInc:			in std_logic;
      DataIn:	 			in std_logic_vector(8 downto 0);
      DataOut: 				out std_logic_vector(8 downto 0);
      rden, wren: 			in std_logic
	);
end entity FIFO8x9;

architecture RTL of FIFO8x9 is
	
	type fifo_array is array(7 downto 0) of std_logic_vector(8 downto 0);  -- makes use of VHDL’s enumerated type
	signal fifo: fifo_array;
	signal wrptr, rdptr: unsigned(2 downto 0);
	signal en: std_logic_vector(7 downto 0);
	signal dmuxout: std_logic_vector(8 downto 0);
		
	begin

		-- fifo register array:
		reg_array: process (rst, clk)
		begin
			if rst = '1' then
                for i in 7 downto 0 loop
                fifo(i) <= (others => '0');
                end loop;
			elsif (clk'event and clk = '1') then
                if wren = '1' then
                    for i in 7 downto 0 loop
                         if en(i) = '1' then
                         fifo(i) <= DataIn;
                         else
                         fifo(i) <= fifo(i);
                         end if;
                     end loop;
                end if;
			end if;
		end process reg_array;

		-- read pointer
		read_count: process (rst, clk)
		begin
			if rst = '1' then
            rdptr <= (others => '0');
			elsif (clk'event and clk='1') then
                if rdptrclr = '1' then
                rdptr <= (others => '0');
                elsif rdinc = '1' then
                rdptr <= rdptr + 1;
                end if;
			end if;
		end process read_count;

		-- write pointer
		write_count: process (rst, clk)
		begin
			if rst = '1' then
            wrptr <= (others => '0');
			elsif (clk'event and clk='1') then
                if wrptrclr = '1' then
                wrptr <= (others => '0');
                elsif wrinc = '1' then
                wrptr <= wrptr + 1;
                end if;
			end if;
		end process write_count;

		-- 8:1 output data mux
		with std_logic_vector(rdptr) select
			dmuxout <=      fifo(0) when "000",
							fifo(1) when "001",
							fifo(2) when "010",
							fifo(3) when "011",
							fifo(4) when "100",
							fifo(5) when "101",
							fifo(6) when "110",
							fifo(7) when others;

		-- FIFO register selector decoder
		with std_logic_vector(wrptr) select
			en <=   "00000001" when "000",
					"00000010" when "001",
					"00000100" when "010",
					"00001000" when "011",
					"00010000" when "100",
					"00100000" when "101",
					"01000000" when "110",
					"10000000" when others;

		-- three-state control of outputs
		three_state: process (rden, dmuxout)
		begin
			DataOut <= dmuxout when rden = '1' else "ZZZZZZZZZ";
		end process three_state;
end RTL;
 

Got the final code:

Code:
library ieee;
--library work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity FIFO8x9 is
   port(
      clk, rst:                in std_logic;
      RdPtrClr, WrPtrClr:    in std_logic;   
      RdInc, WrInc:            in std_logic;
      DataIn:                 in std_logic_vector(8 downto 0);
      DataOut:                 out std_logic_vector(8 downto 0);
      rden, wren:             in std_logic
    );
end entity FIFO8x9;

architecture RTL of FIFO8x9 is
   
    type fifo_array is array(7 downto 0) of std_logic_vector(8 downto 0);  -- makes use of VHDL’s enumerated type
    signal fifo: fifo_array;
    signal wrptr, rdptr: unsigned(2 downto 0);
    signal en: std_logic_vector(7 downto 0);
    signal dmuxout: std_logic_vector(8 downto 0);
       
    begin

        -- fifo register array:
        reg_array: process (rst, clk)
        begin
            if rst = '1' then
                for i in 7 downto 0 loop
                fifo(i) <= (others => '0');
                end loop;
            elsif (clk'event and clk = '1') then
                if wren = '1' then
                    for i in 7 downto 0 loop
                         if en(i) = '1' then
                         fifo(i) <= DataIn;
                         else
                         fifo(i) <= fifo(i);
                         end if;
                     end loop;
                end if;
            end if;
        end process reg_array;

        -- read pointer
        read_count: process (rst, clk)
        begin
            if rst = '1' then
            rdptr <= (others => '0');
            elsif (clk'event and clk='1') then
                if rdptrclr = '1' then
                rdptr <= (others => '0');
                elsif rdinc = '1' then
                rdptr <= rdptr + 1;
                end if;
            end if;
        end process read_count;

        -- write pointer
        write_count: process (rst, clk)
        begin
            if rst = '1' then
            wrptr <= (others => '0');
            elsif (clk'event and clk='1') then
                if wrptrclr = '1' then
                wrptr <= (others => '0');
                elsif wrinc = '1' then
                wrptr <= wrptr + 1;
                end if;
            end if;
        end process write_count;

        -- 8:1 output data mux
        with std_logic_vector(rdptr) select
            dmuxout <=      fifo(0) when "000",
                            fifo(1) when "001",
                            fifo(2) when "010",
                            fifo(3) when "011",
                            fifo(4) when "100",
                            fifo(5) when "101",
                            fifo(6) when "110",
                            fifo(7) when others;

        -- FIFO register selector decoder
        with std_logic_vector(wrptr) select
            en <=   "00000001" when "000",
                    "00000010" when "001",
                    "00000100" when "010",
                    "00001000" when "011",
                    "00010000" when "100",
                    "00100000" when "101",
                    "01000000" when "110",
                    "10000000" when others;

        -- three-state control of outputs
        three_state: process (rden, dmuxout)
        begin
            DataOut <= dmuxout when rden = '1' else "ZZZZZZZZZ";
        end process three_state;
end RTL;

I'm getting error saying error: Illegal sequential statement in ModelSim
 

"when" was only added to process in vhdl-2008.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top