mirror of
				https://github.com/Klagarge/Cursor.git
				synced 2025-10-31 05:59:18 +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;
 |