OpenCores
URL https://opencores.org/ocsvn/loadbalancer/loadbalancer/trunk

Subversion Repositories loadbalancer

[/] [loadbalancer/] [trunk/] [TABLE/] [mac_ram_table.vhd] - Rev 2

Compare with Previous | Blame | View Log

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std.all;
USE IEEE.STD_LOGIC_MISC.ALL;
USE WORK.CONFIG.ALL;
entity mac_ram_table is
generic (
        ADDR_WIDTH :integer := 10
    );
	port (
	clk: IN std_logic;
	reset : IN STD_LOGIC;
	in_mac_no_prt: IN std_logic_VECTOR(63 downto 0);--MAC NUMBER internal port
	in_address   : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
	in_wr: IN std_logic;
	in_check : IN STD_LOGIC;
	match_address : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
	match:  OUT STD_LOGIC;
	unmatch:  OUT STD_LOGIC;
	in_rd : IN STD_LOGIC;
	in_key : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
	last_address : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
	out_rd_rdy : OUT std_logic;
--	vd_add_rm_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
--	vd_rm_out :  OUT STD_LOGIC;
	out_port : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
    out_mac : OUT STD_LOGIC_VECTOR(47 DOWNTO 0)
	);
end mac_ram_table;
 
architecture Behavioral of mac_ram_table is
 
	----------------------------------------------------------------
	COMPONENT valid_address is
		generic (
				ADDR_WIDTH :integer := ADDR_WIDTH
			);
			port (
					clk: IN std_logic;
					reset : IN STD_LOGIC;
					in_wr_address : IN STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
					in_wr: IN std_logic;
					in_key : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
					in_rd : IN STD_LOGIC;
					in_rm_address_no : IN STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
					in_rm : IN STD_LOGIC;
					out_address : OUT STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
					out_rdy : OUT std_logic
 
			);
	end COMPONENT valid_address;
	------------------------
	COMPONENT Aging_Timer is
	   generic(
		  N: integer := 32;  -- 32 bits couter
		  M: integer := 125000  -- 125000  = 1 miliscond
	   );
	   port(
		  clk, reset: in std_logic;
		  timeout: out std_logic;
		  timer_aging_bit: out std_logic;
		  count_out: out std_logic_vector(31 downto 0)--N-1
	   );
	end COMPONENT Aging_Timer;
 
 
----------------------------------------------------------------------------
	-------COMPONENET SMALL FIFO
	COMPONENT  small_fifo IS
	GENERIC(WIDTH :INTEGER := 8;
			MAX_DEPTH_BITS :INTEGER := 5);
	 PORT(   
     SIGNAL din : IN STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);--input [WIDTH-1:0] din,     // Data in
     SIGNAL wr_en : IN STD_LOGIC;--input          wr_en,   // Write enable    
     SIGNAL rd_en : IN STD_LOGIC;--input          rd_en,   // Read the next word    
     SIGNAL dout :OUT STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0);--output reg [WIDTH-1:0]  dout,    // Data out
     SIGNAL full : OUT STD_LOGIC;--output         full,
     SIGNAL nearly_full : OUT STD_LOGIC;--output         nearly_full,
     SIGNAL empty : OUT STD_LOGIC;--output         empty,    	
     SIGNAL reset :IN STD_LOGIC;
     SIGNAL clk   :IN STD_LOGIC
	 );
	END COMPONENT;
-------COMPONENET SMALL FIFO	
------------------------------------------------------
 
------------------------------------------------------------
COMPONENT ram_256x48 is
 
	generic 
	(
		DATA_WIDTH : natural := 48;
		ADDR_WIDTH : natural := ADDR_WIDTH
	);
 
	port 
	(
		clk		: in std_logic;
		raddr	: in natural range 0 to 2**ADDR_WIDTH - 1;
		waddr	: in natural range 0 to 2**ADDR_WIDTH - 1;
		data	: in std_logic_vector((DATA_WIDTH-1) downto 0);
		we		: in std_logic := '1';
		q		: out std_logic_vector((DATA_WIDTH -1) downto 0)
	);
 
end COMPONENT ram_256x48;
	TYPE 		state_type 				IS(IDLE, ADD_1, ADD_2, SCAN_1, SCAN_2);
	SIGNAL 		state, state_next 	 : 	state_type;
	TYPE 		state_search_type 		IS(IDLE,  CHECK, FOUND, UNFOUND);
	SIGNAL 		state_search		 :  state_search_type;
	SIGNAL 		state_next_search 	 :  state_search_type;
	attribute 	enum_encoding 		 :  string;
	attribute 	enum_encoding of state_type : type is "onehot";
	------------------------------------------------------		
	SIGNAL 		in_mac_no_prt_i		:  STD_LOGIC_VECTOR(55 DOWNTO 0);
	SIGNAL 		mac_prt				:  STD_LOGIC_VECTOR(55 DOWNTO 0);
	SIGNAL 		q_mac_prt			:  STD_LOGIC_VECTOR(55 DOWNTO 0);
	SIGNAL 		cnt 				:  INTEGER ;
	SIGNAL 		in_check_p			:  STD_LOGIC;
	SIGNAL 		match_i				:  STD_LOGIC;
	SIGNAL 		unmatch_i				:  STD_LOGIC;
	---------------------------------------------------------------------------
	SIGNAL 		time_out 			:  STD_LOGIC;
	SIGNAL 		timer_aging_bit 	:  STD_LOGIC;	
	---------------------------------------------------------------------------
	--------- Signals to connect with Valid Address Module-------------
	SIGNAL  	vd_add				:  STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
	SIGNAL		vd_add_wr			:  STD_LOGIC;
	SIGNAL		vd_in_rd			:  STD_LOGIC;
	SIGNAL		vd_add_rm			:  STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
	SIGNAL		vd_rm				:  STD_LOGIC;
	SIGNAL		vd_out_add  		:  STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
	SIGNAL		vd_out_rdy			:  STD_LOGIC;
	SIGNAL		out_rd_rdy_i		:  STD_LOGIC;
	---------------------------------------------------------------------------
	--------- Signals to connect with Fifo Module---------------------
	SIGNAL		write_cmd_rd		:  STD_LOGIC;       
	SIGNAL	  	write_cmd_address	:  STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);   
	SIGNAL	 	write_cmd_empty		:  STD_LOGIC;	
	SIGNAL		time_out_cmd_rd		:  STD_LOGIC;       
	SIGNAL		time_out_cmd_empty	:  STD_LOGIC;
	SIGNAL		time_out_fifo_wr	:  STD_LOGIC;
	---------------------------------------------------------------------------
	--------- Signals to connect with VALID AGING Ram ----------------
	SIGNAL		raddr_av			:  STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0); 
	SIGNAL		waddr_av 			:  STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
	SIGNAL		data_av				:  STD_LOGIC_VECTOR(1 DOWNTO 0);
	SIGNAL		we_av				:  STD_LOGIC;
	SIGNAL		ag_vd_q				:  STD_LOGIC_VECTOR(1 DOWNTO 0);
	---------------------------------------------------------------------------
	--------- Signals to connect with MAC reading Ram ----------------
	SIGNAL 		ram_mac_out 		:  STD_LOGIC_VECTOR(47 DOWNTO 0);
	-------------------------------------------------
	--------- Signals to connect with MAC Searching Ram ----------------
	SIGNAL 		ram_q		 		:  STD_LOGIC_VECTOR(55 DOWNTO 0);
	---------------------------------------------------------------------------
	SIGNAL		cnt_1				:  STD_LOGIC_VECTOR(ADDR_WIDTH-1 DOWNTO 0);
	SIGNAL		cnt_1_restart		:  STD_LOGIC;
	SIGNAL		cnt_1_up			:  STD_LOGIC;
	---------------------------------------------------------------------------
begin
	---------------------------------------------------------------------------
 
	-------PORT MAP SMALL FIFO DATA
		------------------------
			Aging_Timer_Inst :  Aging_Timer 
			   GENERIC MAP ( 
								N => 32 , 	 
								M => 1025000 -- = 1 --miliscond  
							)
				   port MAP(
					  clk => clk, 
					  reset => reset,
					  timeout =>open ,
					  timer_aging_bit =>timer_aging_bit,
					  count_out => open
				   );
 
					time_out<='0';--testing without aging bit
--Search  new MAC inside the table the address  
		ram_256x48_search_Inst : ram_256x48 
 
			GENERIC MAP	(
					DATA_WIDTH => 56, ADDR_WIDTH => ADDR_WIDTH)
 
				port MAP (
					clk			=>	 clk		,
					raddr	    =>	  CONV_INTEGER(cnt)			,
					waddr	    =>	  CONV_INTEGER(in_address)			,
					data	    =>	  in_mac_no_prt(63 DOWNTO 8)		,
					we		    =>	 in_wr		,
					q		    =>	 ram_q		
				);
 
-----------------------------------------------------------------------	
 
		PROCESS(clk, reset)
				BEGIN
					IF reset= '1' THEN
								state_search	<=	IDLE	;
					ELSIF clk'EVENT AND clk = '1' THEN
								state_search		<=	state_next_search	;
						IF(in_check = '1') THEN
								in_mac_no_prt_i <= in_mac_no_prt(63 DOWNTO 8);
 
						END IF;
						IF(match_i = '1') THEN
								match_address 		<= std_logic_vector(to_unsigned(cnt - 1, ADDR_WIDTH)); 
 
						END IF;
					END IF;		
	END PROCESS;
 
	PROCESS(state_search, in_check, ram_q, in_mac_no_prt_i, cnt, last_address)
		BEGIN
								state_next_search	<=	state_search	;
								match_i 			<=  '0'	;
								unmatch_i 			<=  '0'	; 
 
		CASE state_search IS
		WHEN IDLE => 
					IF(in_check = '1' ) THEN																
								state_next_search	<= CHECK	;
					END IF;
		WHEN CHECK =>			
					IF (ram_q = in_mac_no_prt_i )THEN
								match_i 			<=  '1'	;
								state_next_search	<=	IDLE	;
					ELSIF (cnt = CONV_INTEGER(last_address)) 	THEN
								unmatch_i <=  '1'; 
								state_next_search	<=	IDLE	;								
					END IF;
 
		WHEN OTHERS=>			
								state_next_search	<=	IDLE	;
 
		END CASE;
	END PROCESS;	
 
---------Register Out put--------------
	process (clk)
	begin
		if (rising_edge(clk)) then
			match	<= match_i;
			unmatch	<= unmatch_i;			
		end if;
	end process;
 
-----------------------------------------
 
	process (clk)
		variable   cnt1		   : integer range 0 to 2**ADDR_WIDTH-1;
	begin
		if (rising_edge(clk)) then
 
			if reset = '1' then
				cnt1 := 0;
			elsIF(in_check = '1'  ) THEN
					cnt1 := 0;
			else  	   
				cnt1 := cnt1 + 1;
			end if;
		end if;
		cnt <= cnt1;
	end process;
 
 -------------------------------------------------------------------
 -------------------------------------------------------------------
 -------------------------------------------------------------------
--Write new MAC inside the table the address is provided by out side 
		ram_256x48_Inst : ram_256x48 
 
			GENERIC MAP	(
					DATA_WIDTH => 56, ADDR_WIDTH => ADDR_WIDTH)
 
				port MAP (
					clk				    =>	 clk		,
					raddr	   		    =>	CONV_INTEGER(vd_out_add)		,--this is coming from the valid address
					waddr	    	    =>	 CONV_INTEGER(in_address)		,
					data	    	    =>	 mac_prt		,--MAC=>PORT
					we		    	    =>	 in_wr	,	
					q		            =>	 q_mac_prt --Next MAC address		
				);	
				mac_prt(55 DOWNTO 8) <= in_mac_no_prt(63 DOWNTO 16);
				mac_prt(7 DOWNTO 0) <= in_mac_no_prt(7 DOWNTO 0);
				out_mac 			<=q_mac_prt(55 DOWNTO 8);
				out_port 			<=q_mac_prt(7 DOWNTO 0);
	WRITE_command_Inst :  small_fifo 
		GENERIC MAP(WIDTH  => ADDR_WIDTH,
				MAX_DEPTH_BITS  => 5)
		PORT MAP(				   
				   din 					=>	in_address,    
				   wr_en 				=>	in_wr, 		
				   rd_en 				=> 	write_cmd_rd,       
				   dout 				=>	write_cmd_address,   
				   full 				=>	open,
				   nearly_full 			=>	open,
				   empty 				=> 	write_cmd_empty,
				   reset 				=> 	reset ,
				   clk  				=> 	clk 
		);
	time_command_Inst :  small_fifo 
		GENERIC MAP(WIDTH  => 1,
				MAX_DEPTH_BITS  => 2)
		PORT MAP(				   
				   din 					=>	"1",    
				   wr_en 				=>	time_out_fifo_wr, 		
				   rd_en 				=> 	time_out_cmd_rd,       
				   dout 				=>	open,   
				   full 				=>	open,
				   nearly_full 			=>	open,
				   empty 				=>	time_out_cmd_empty,
				   reset 				=> 	reset ,
				   clk  				=> 	clk 
		);
		time_out_fifo_wr <= time_out AND  (time_out_cmd_empty);--onòy one element can be sotred in this 
-------------------------------------------------------------------						
------------------------------------------------------------
	--Write new MAC inside the table the address is provided by out side 
		Aging_Valid_256x48_Inst : ram_256x48 
 
			GENERIC MAP	(
					DATA_WIDTH => 2, ADDR_WIDTH => ADDR_WIDTH)
 
				port MAP (
					clk					=>	 clk		,
					raddr	   			=>	 CONV_INTEGER(raddr_av)		,
					waddr	    		=>	 CONV_INTEGER(waddr_av)		,
					data	    		=>	 data_av	,
					we		    		=>	 we_av		,
					q		    		=>	 ag_vd_q		
				);
-------------------------------------------------------------------------------------
	valid_address_Inst : valid_address 
		GENERIC MAP (ADDR_WIDTH =>ADDR_WIDTH)
		PORT MAP    (
					clk					=>	 clk		,
					reset 				=>	 reset		,
					in_wr_address 		=>	 vd_add		,
					in_wr				=>	 vd_add_wr	,
					in_rd 				=>	 in_rd	,
					in_key 				=>	 in_key	,
					in_rm_address_no 	=>	 vd_add_rm	,
					in_rm 				=>	 vd_rm		,
					out_address 		=>   vd_out_add ,
					out_rdy 			=>   vd_out_rdy
 
			);		
 
-------------------------------------------------------------------------------------
		PROCESS(clk, reset)
				BEGIN
				IF reset= '1' THEN
					state				<=	IDLE	;
				ELSIF clk'EVENT AND clk = '1' THEN
					state				<=	state_next	;
					out_rd_rdy_i		    <=  vd_out_rdy;
					out_rd_rdy		    <=  out_rd_rdy_i ;
				END IF;		
		END PROCESS;
 
		PROCESS(state, write_cmd_empty, time_out_cmd_empty,
				write_cmd_address, timer_aging_bit, write_cmd_address, ag_vd_q, cnt_1)
		BEGIN				
					vd_add_rm 		    <=  (OTHERS=>'0');
					vd_rm			    <=  '0';
					vd_add	 		    <=  (OTHERS=>'0');
					vd_add_wr		    <=  '0';
					raddr_av   		    <=	(OTHERS=>'0');
					waddr_av		    <=	(OTHERS=>'0');
					data_av	   		    <=	(OTHERS=>'0');
					we_av			    <=	'0';
					write_cmd_rd	    <=  '0';
					time_out_cmd_rd		<=  '0';
					cnt_1_restart		<=  '0';
					cnt_1_up 			<=  '0';	
					state_next		    <=	state	;
 
 
		CASE state IS
 
		WHEN IDLE => 
							cnt_1_restart	<= '1';
					IF write_cmd_empty = '0' THEN
							write_cmd_rd<=  '1';
							state_next	<=  ADD_1	;
					ELSIF(time_out_cmd_empty = '0' ) THEN	
 
							time_out_cmd_rd		<=  '1';
							state_next	<=  SCAN_1	;
					END IF;
		WHEN ADD_1 => 
							---Read the Valid and  Aging bit 
							raddr_av	<=	write_cmd_address	;
							state_next	<=	ADD_2	;
		WHEN ADD_2 => 
							---Write the Valid and  Aging bit 
							data_av		<=	 '1' & timer_aging_bit ;
							waddr_av	<=	write_cmd_address	;
							we_av		<=	'1'	;
							--Write the Valid Address
							vd_add 		<=  write_cmd_address	;
							vd_add_wr 	<=  NOT ag_vd_q(1)	;
							state_next	<=	IDLE	;
		WHEN SCAN_1 =>		
 
							raddr_av   	<=	cnt_1 ;
							state_next	<=	SCAN_2	;		
 
		WHEN SCAN_2 =>		cnt_1_up 	<= '1';
 
		--		ELSIF cnt_1 = CONV_INTEGER(last_address)THEN 		--LAST ELEMNET REACHED
		IF cnt_1 = CONV_INTEGER(last_address) THEN 		--LAST ELEMNET REACHED
							state_next	<=	IDLE	;	
 
		ELSIF ( ag_vd_q(1) = '1' AND ( ag_vd_q(0) /= timer_aging_bit )  )THEN 
--							data_av(1) 	<=	'1';
--							data_av(0) 	<=	ag_vd_q(0); --do not change it 
--							we_av		<=	'1'	;
							state_next	<=	SCAN_1	;
 
	    ELSIF ( ag_vd_q(1)  = '1' AND ( ag_vd_q(0) = timer_aging_bit ) )THEN 
							---delete this valid address 
							vd_add_rm 	<=  cnt_1 ;
							vd_rm		<=  '1';
							-----------------------------
							data_av(1) 	<=	'0';
							data_av(0) 	<=	timer_aging_bit; 
							waddr_av	<=	cnt_1 ;								
							we_av		<=	'1'	;
							state_next	<=	SCAN_1	;
		ELSE 
							state_next	<=	SCAN_1	;
							END IF;
 
		WHEN OTHERS=>			
							state_next	<=	IDLE	;		
		END CASE;
	END PROCESS;	
 
--	vd_add_rm_out <= vd_add_rm 	 ;
--	vd_rm_out <=time_out_cmd_rd;
--	vd_rm_out <=vd_rm;
	process (clk)
		variable   cnt1		   : integer range 0 to 2**ADDR_WIDTH-1;
	begin
		if (rising_edge(clk)) then
 
			if reset = '1' then
				cnt1 := 0;
			elsIF(cnt_1_restart = '1'  ) THEN
					cnt1 := 0;
			elsif cnt_1_up = '1' then  	   
				cnt1 := cnt1 + 1;
			end if;
		end if;
		cnt_1 <= std_logic_vector(to_unsigned(cnt1 , ADDR_WIDTH)); 
	end process;
 
 
 
 
end Behavioral;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.