From: hadeshyp Date: Tue, 17 Feb 2009 17:59:27 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: oldGBE~484 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=ca760792e5b86ec876c2f1b5d416611fa4c79b83;p=trbnet.git *** empty log message *** --- diff --git a/trb_net16_med_16_CC.vhd b/trb_net16_med_16_CC.vhd new file mode 100644 index 0000000..e843839 --- /dev/null +++ b/trb_net16_med_16_CC.vhd @@ -0,0 +1,317 @@ +-- A 16bit data interface between two devices using a common clock, 32 data lines and 4 control lines + + +LIBRARY ieee; +use ieee.std_logic_1164.all; +USE IEEE.numeric_std.ALL; +USE IEEE.std_logic_UNSIGNED.ALL; + +library work; +use work.trb_net_std.all; + +entity trb_net16_med_16_CC is + port( + CLK : in std_logic; + CLK_EN : in std_logic; + RESET : in std_logic; + + --Internal Connection + MED_DATA_IN : in std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_IN : in std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_IN : in std_logic; + MED_READ_OUT : out std_logic; + MED_DATA_OUT : out std_logic_vector(c_DATA_WIDTH-1 downto 0); + MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0); + MED_DATAREADY_OUT : out std_logic; + MED_READ_IN : in std_logic; + + DATA_OUT : out std_logic_vector(15 downto 0); + DATA_VALID_OUT : out std_logic; + DATA_CTRL_OUT : out std_logic; + DATA_IN : in std_logic_vector(15 downto 0); + DATA_VALID_IN : in std_logic; + DATA_CTRL_IN : in std_logic; + + STAT_OP : out std_logic_vector(15 downto 0); + CTRL_OP : in std_logic_vector(15 downto 0); + STAT_DEBUG : out std_logic_vector(63 downto 0) + ); +end entity; + +architecture trb_net16_med_16_CC_arch of trb_net16_med_16_CC is + + component signal_sync is + generic( + WIDTH : integer := 18; + DEPTH : integer := 3 + ); + port( + RESET : in std_logic; + CLK0 : in std_logic; + CLK1 : in std_logic; + D_IN : in std_logic_vector(WIDTH-1 downto 0); + D_OUT : out std_logic_vector(WIDTH-1 downto 0) + ); + end component; + + + signal reg_DATA_IN : std_logic_vector(15 downto 0); + signal reg_DATA_VALID_IN : std_logic; + signal reg_DATA_CTRL_IN : std_logic; + + signal last_DATA_CTRL_IN : std_logic; + signal link_running_counter : unsigned(3 downto 0); + signal link_running : std_logic; + + signal buf_DATA_VALID_OUT : std_logic; + signal buf_DATA_CTRL_OUT : std_logic; + signal buf_DATA_OUT : std_logic_vector(15 downto 0); + signal PRESENT_SIG : std_logic; + signal led_counter : unsigned(18 downto 0); + + signal link_led : std_logic; + signal tx_led : std_logic; + signal rx_led : std_logic; + signal resync : std_logic; + signal resync_counter : unsigned(4 downto 0); + signal rx_mismatch : std_logic; + + signal rx_counter : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal buf_MED_READ_OUT : std_logic; + signal buf_MED_DATAREADY_OUT : std_logic; + signal buf_MED_PACKET_NUM_OUT : std_logic_vector(c_NUM_WIDTH-1 downto 0); + signal buf_MED_DATA_OUT : std_logic_vector(c_DATA_WIDTH-1 downto 0); + +begin + +----------------------- +--Receiver +----------------------- + THE_RX_SIGNAL_SYNC: signal_sync + generic map( + DEPTH => 2, + WIDTH => 18 + ) + port map( + RESET => RESET, + D_IN(15 downto 0) => DATA_IN, + D_IN(16) => DATA_VALID_IN, + D_IN(17) => DATA_CTRL_IN, + CLK0 => CLK, + CLK1 => CLK, + D_OUT(15 downto 0) => reg_DATA_IN, + D_OUT(16) => reg_DATA_VALID_IN, + D_OUT(17) => reg_DATA_CTRL_IN + ); + + + PROC_RX_COUNTER : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + rx_counter <= c_H0; + elsif buf_MED_DATAREADY_OUT = '1' and CLK_EN = '1' then + if rx_counter = c_max_word_number then + rx_counter <= (others => '0'); + else + rx_counter <= rx_counter + 1; + end if; + end if; + end if; + end process; + + + buf_MED_PACKET_NUM_OUT <= rx_counter; + buf_MED_DATAREADY_OUT <= reg_DATA_VALID_IN and link_running; + buf_MED_DATA_OUT <= reg_DATA_IN; + buf_MED_READ_OUT <= link_running; + MED_READ_OUT <= buf_MED_READ_OUT; + + PROC_REG_MED_OUT : process(CLK) + begin + if rising_edge(CLK) then + MED_DATA_OUT <= buf_MED_DATA_OUT; + MED_DATAREADY_OUT <= buf_MED_DATAREADY_OUT; + MED_PACKET_NUM_OUT<= buf_MED_PACKET_NUM_OUT; + end if; + end process; + + +----------------------- +--Link detection & Status & Control signals +----------------------- + +--during idle phases, the ctrl signal changes every clock cycle +--if no change is seen within 2 cycles, the link is broken +--if it changes for 16 cycles, the link is running + PROC_DETECT_SIGNAL : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + link_running_counter <= to_unsigned(0,4); + link_running <= '0'; + else + if link_running_counter = x"F" and rx_mismatch = '0' then + link_running <= '1'; + else + link_running <= '0'; + end if; + if reg_DATA_VALID_IN = '0' then + last_DATA_CTRL_IN <= reg_DATA_CTRL_IN; + if last_DATA_CTRL_IN /= reg_DATA_CTRL_IN and link_running_counter /= x"F" then + link_running_counter <= link_running_counter + to_unsigned(1,1); + elsif last_DATA_CTRL_IN = reg_DATA_CTRL_IN and link_running_counter /= 0 then + link_running_counter <= link_running_counter - to_unsigned(1,1); + end if; + end if; + end if; + end if; + end process; + + PROC_CHECK_RX_COUNTER : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' or CTRL_OP(15) = '1' then + rx_mismatch <= '0'; + elsif link_running = '1' then + if (reg_DATA_CTRL_IN = '1' and reg_DATA_VALID_IN = '1' and rx_counter /= c_H0) + or (reg_DATA_CTRL_IN = '0' and reg_DATA_VALID_IN = '1' and rx_counter = c_H0) + or (buf_MED_DATAREADY_OUT = '1' and MED_READ_IN = '0') then + rx_mismatch <= '1'; + end if; + end if; + end if; + end process; + + STAT_OP(8 downto 3) <= (others => '0'); + STAT_OP(9) <= link_led; + STAT_OP(10) <= rx_led; + STAT_OP(11) <= tx_led; + STAT_OP(12) <= '0'; + STAT_OP(13) <= '0'; + STAT_OP(14) <= '1' when link_running_counter > x"1" and link_running_counter < x"A" else '0'; + STAT_OP(15) <= rx_mismatch; + + + PROC_ERROR : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + STAT_OP(2 downto 0) <= ERROR_NC; + else + if link_running = '1' then + STAT_OP(2 downto 0) <= ERROR_OK; + else + STAT_OP(2 downto 0) <= ERROR_NC; + end if; + end if; + end if; + end process; + + PROC_LED : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + led_counter <= (others => '0'); + rx_led <= '0'; + tx_led <= '0'; + link_led <= '0'; + else + led_counter <= led_counter + 1; + link_led <= link_running; + if led_counter(18) = '1' then + led_counter <= (others => '0'); + rx_led <= '0'; + tx_led <= '0'; + end if; + if buf_MED_DATAREADY_OUT = '1' then + rx_led <= '1'; + end if; + if MED_DATAREADY_IN = '1' and buf_MED_READ_OUT = '1' then + tx_led <= '1'; + end if; + end if; + end if; + end process; + + PROC_GEN_RESYNC : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + resync_counter <= (others => '0'); + resync <= '0'; + else + if CTRL_OP(15) = '1' or resync_counter /= 0 then + resync_counter <= resync_counter + 1; + resync <= '1'; + else + resync_counter <= (others => '0'); + resync <= '0'; + end if; + end if; + end if; + end process; + +----------------------- +--Sender +----------------------- + + +--Generate tx signals + PROC_SEND_DATA : process(CLK) + begin + if rising_edge(CLK) then + if RESET = '1' then + buf_DATA_VALID_OUT <= '0'; + buf_DATA_CTRL_OUT <= '0'; + buf_DATA_OUT <= (others => '0'); + PRESENT_SIG <= '0'; + elsif resync = '1' then + buf_DATA_VALID_OUT <= '0'; + buf_DATA_CTRL_OUT <= '1'; + buf_DATA_OUT <= x"EEEE"; + elsif MED_DATAREADY_IN = '1' and buf_MED_READ_OUT = '1' then + buf_DATA_VALID_OUT <= '1'; + buf_DATA_OUT <= MED_DATA_IN; + if MED_PACKET_NUM_IN = c_H0 then + buf_DATA_CTRL_OUT <= '1'; + else + buf_DATA_CTRL_OUT <= '0'; + end if; + else + buf_DATA_OUT <= x"AAAA"; + buf_DATA_CTRL_OUT <= PRESENT_SIG; + buf_DATA_VALID_OUT <= '0'; + PRESENT_SIG <= not PRESENT_SIG; + end if; + end if; + end process; + +--Generate O-FF + PROC_OUTPUT : process(CLK) + begin + if rising_edge(CLK) then + DATA_VALID_OUT <= buf_DATA_VALID_OUT; + DATA_CTRL_OUT <= buf_DATA_CTRL_OUT; + DATA_OUT <= buf_DATA_OUT; + end if; + end process; + + + + +----------------------- +--Debug +----------------------- + +STAT_DEBUG(15 downto 0) <= reg_DATA_IN; +STAT_DEBUG(16) <= reg_DATA_VALID_IN; +STAT_DEBUG(17) <= reg_DATA_CTRL_IN; +STAT_DEBUG(18) <= rx_mismatch; +STAT_DEBUG(22 downto 19)<= link_running_counter(3 downto 0); +STAT_DEBUG(23) <= resync; + + +STAT_DEBUG(63 downto 24) <= (others => '0'); + +end architecture; \ No newline at end of file