mirror of
				https://github.com/Klagarge/Cursor.git
				synced 2025-11-04 07:49:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			166 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
library Common;
 | 
						|
  use Common.CommonLib.all;
 | 
						|
 | 
						|
architecture RTL of FIFO_bram is
 | 
						|
 | 
						|
  subtype register_type is std_ulogic_vector(dataIn'high downto 0);
 | 
						|
  type memory_type is array (0 to depth-1) of register_type;
 | 
						|
 | 
						|
  signal writeCounter: unsigned(requiredBitNb(depth-1)-1 downto 0);
 | 
						|
  signal readCounter: unsigned(writeCounter'range);
 | 
						|
  signal memoryArray: memory_type;
 | 
						|
 | 
						|
  type fifoStateType is (
 | 
						|
    sEmpty, sFull,
 | 
						|
    sRead, sWrite, sWriteFirst,
 | 
						|
    sReadWrite, sWait
 | 
						|
  );
 | 
						|
  signal fifoState: fifoStateType;
 | 
						|
  signal emptyCondition, fullCondition, empty_int: std_ulogic;
 | 
						|
 | 
						|
begin
 | 
						|
  ------------------------------------------------------------------------------
 | 
						|
                                                      -- read and write counters
 | 
						|
  updateWriteCounter: process(reset, clock)
 | 
						|
  begin
 | 
						|
    if reset = '1' then
 | 
						|
      writeCounter <= (others => '0');
 | 
						|
    elsif rising_edge(clock) then
 | 
						|
      if (write = '1') and  (fullCondition = '0') then
 | 
						|
        writeCounter <= writeCounter + 1;
 | 
						|
      end if;
 | 
						|
    end if;
 | 
						|
  end process updateWriteCounter;
 | 
						|
 | 
						|
  updateReadCounter: process(reset, clock)
 | 
						|
  begin
 | 
						|
    if reset = '1' then
 | 
						|
      readCounter <= (others => '0');
 | 
						|
    elsif rising_edge(clock) then
 | 
						|
      if (read = '1') and  (empty_int = '0') then
 | 
						|
        readCounter <= readCounter + 1;
 | 
						|
      end if;
 | 
						|
    end if;
 | 
						|
  end process updateReadCounter;
 | 
						|
 | 
						|
  ------------------------------------------------------------------------------
 | 
						|
                                                                -- memory access
 | 
						|
  writeMem: process(clock)
 | 
						|
  begin
 | 
						|
    if rising_edge(clock) then
 | 
						|
      if (write = '1') and (fullCondition = '0') then
 | 
						|
        memoryArray(to_integer(writeCounter)) <= dataIn;
 | 
						|
      end if;
 | 
						|
    end if;
 | 
						|
  end process writeMem;
 | 
						|
 | 
						|
  readMem: process(reset, clock)
 | 
						|
  begin
 | 
						|
    if reset = '1' then
 | 
						|
      dataOut <= (others => '0');
 | 
						|
    elsif rising_edge(clock) then
 | 
						|
      if (read = '0') or (empty_int = '1') then
 | 
						|
        dataOut <= memoryArray(to_integer(readCounter));
 | 
						|
      else
 | 
						|
        dataOut <= memoryArray(to_integer(readCounter+1));
 | 
						|
      end if;
 | 
						|
    end if;
 | 
						|
  end process readMem;
 | 
						|
 | 
						|
  ------------------------------------------------------------------------------
 | 
						|
                                                                     -- controls
 | 
						|
  emptyCondition <= '1' when
 | 
						|
      ( (fifoState = sRead) and (writeCounter = readCounter) ) or
 | 
						|
        (fifoState = sEmpty)
 | 
						|
    else '0';
 | 
						|
 | 
						|
  fullCondition <= '1' when
 | 
						|
      ( (fifoState = sWrite) and (writeCounter = readCounter) ) or
 | 
						|
        (fifoState = sFull)
 | 
						|
    else '0';
 | 
						|
 | 
						|
 | 
						|
  fifoControl: process(reset, clock)
 | 
						|
  begin
 | 
						|
    if reset = '1' then
 | 
						|
      fifoState <= sEmpty;
 | 
						|
    elsif rising_edge(clock) then
 | 
						|
      case fifoState is
 | 
						|
        when sEmpty =>
 | 
						|
          if write = '1' then
 | 
						|
            fifoState <= sWriteFirst;
 | 
						|
          end if;
 | 
						|
        when sFull =>
 | 
						|
          if (read = '1') then
 | 
						|
            fifoState <= sRead;
 | 
						|
          end if;
 | 
						|
        when sRead =>
 | 
						|
          if (read = '1') and (write = '1') then
 | 
						|
            fifoState <= sReadWrite;
 | 
						|
          elsif write = '1' then
 | 
						|
            fifoState <= sWrite;
 | 
						|
		      elsif emptyCondition = '1' then
 | 
						|
            fifoState <= sEmpty;
 | 
						|
          elsif read = '1' then
 | 
						|
            fifoState <= sRead;
 | 
						|
          else
 | 
						|
            fifoState <= sWait;
 | 
						|
          end if;
 | 
						|
        when sWriteFirst =>
 | 
						|
          if (read = '1') and (write = '1') then
 | 
						|
            fifoState <= sReadWrite;
 | 
						|
          elsif write = '1' then
 | 
						|
            fifoState <= sWrite;
 | 
						|
          elsif read = '1' then
 | 
						|
            fifoState <= sRead;
 | 
						|
          else
 | 
						|
            fifoState <= sWait;
 | 
						|
          end if;
 | 
						|
        when sWrite =>
 | 
						|
          if (read = '1') and (write = '1') then
 | 
						|
            fifoState <= sReadWrite;
 | 
						|
          elsif read = '1' then
 | 
						|
            fifoState <= sRead;
 | 
						|
		      elsif fullCondition = '1' then
 | 
						|
            fifoState <= sFull;
 | 
						|
          elsif write = '1' then
 | 
						|
            fifoState <= sWrite;
 | 
						|
          else
 | 
						|
            fifoState <= sWait;
 | 
						|
          end if;
 | 
						|
        when sReadWrite =>
 | 
						|
          if (read = '0') and (write = '0') then
 | 
						|
            fifoState <= sWait;
 | 
						|
          elsif (read = '1') and (write = '0') then
 | 
						|
            fifoState <= sRead;
 | 
						|
          elsif (write = '1') and (read = '0') then
 | 
						|
            fifoState <= sWrite;
 | 
						|
          end if;
 | 
						|
        when sWait =>
 | 
						|
          if (read = '1') and (write = '1') then
 | 
						|
            fifoState <= sReadWrite;
 | 
						|
          elsif read = '1' then
 | 
						|
            fifoState <= sRead;
 | 
						|
          elsif write = '1' then
 | 
						|
            fifoState <= sWrite;
 | 
						|
          end if;
 | 
						|
        when others => null;
 | 
						|
      end case;
 | 
						|
    end if;
 | 
						|
  end process fifoControl;
 | 
						|
  
 | 
						|
 | 
						|
  full <= '1' when 
 | 
						|
        (fifoState = sFull) or
 | 
						|
        (fullCondition = '1')
 | 
						|
    else '0';
 | 
						|
 | 
						|
  empty_int <= '1' when
 | 
						|
        (fifoState = sEmpty) or
 | 
						|
        (fifoState = sWriteFirst) or
 | 
						|
        ( (emptyCondition = '1') and (fifoState = sRead) )
 | 
						|
    else '0';
 | 
						|
  empty <= empty_int;
 | 
						|
  
 | 
						|
end RTL;
 |