library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.sim_switcher_pkg.all; entity sim_switcher_top is generic ( -- General parameters SYSFREQ : integer := 25_000_000; -- System clock frequency INSIM : std_logic := '0'; -- In Simulation flag: 0 - real work (default), 1 - simulation -- I2C parameters I2C_SLAVE_ADDR : std_logic_vector(6 downto 0) := "1010111" -- Address of I2C slave, dafault 0x57 ); port ( -- Clock and reset clk25_i : in std_logic; clk125_i : in std_logic; rstn_i : in std_logic; -- User LED led_o : out std_logic; -- Power Good signals pg_10v_i : in std_logic; pg_25v_i : in std_logic; pg_33v_i : in std_logic; -- CPU reset signals cpu_rst_reqn_i : in std_logic; cpu_trstn_o : out std_logic; cpu_jtag_rstn_o : out std_logic; -- FPGA interrupt to CPU fpga_int_o : out std_logic; -- FPGA_INTn_V18, PIN_F12, active high -- I2C slave interface i2c_scl_io : inout std_logic; i2c_sda_io : inout std_logic; -- SIM board CONF bits sb_conf_i : in std_logic_vector(2 downto 0); -- SIM signals sim_detect_i : in std_logic_vector(7 downto 0); sim_pwron_o : out std_logic_vector(7 downto 0); sim_rst_o : out std_logic_vector(7 downto 0); sim_clk_o : out std_logic_vector(7 downto 0); sim_data_io : inout std_logic_vector(7 downto 0); -- Virtual SIM data IO signals vsim_data_io : inout std_logic_vector(3 downto 0); -- Modem signals for SIM cards mod_detect_o : out std_logic_vector(3 downto 0); mod_wake_host_i : in std_logic_vector(3 downto 0); mod_simpwr_i : in std_logic_vector(7 downto 0); mod_simrst_i : in std_logic_vector(7 downto 0); mod_clk_i : in std_logic_vector(7 downto 0); mod_data_io : inout std_logic_vector(7 downto 0); -- Modem LEDs mod_led_o : out std_logic_vector(7 downto 0); -- Modem manage signals mod_pwr_o : out std_logic_vector(7 downto 0); -- Modem power on signals mod_rstn_o : out std_logic_vector(7 downto 5); -- PCIe reset signal mod_pciehstwake_i : in std_logic_vector(7 downto 5); -- PCIe wake host signal -- Expansion card GPIO signals exp_card_io : inout std_logic_vector(5 downto 0); -- FAN power on signals fan_o : out std_logic_vector(1 downto 0); -- I2C slave interface FPGA-MCU (BitBang by MCU) i2c_mcuscl_io : inout std_logic; i2c_mcusda_io : inout std_logic; -- POE IN add-in card poe_in_vpres : in std_logic; -- Voltage present at card power output poe_in_enn : out std_logic; -- PD enable signal (active low) poe_in_t2p : in std_logic_vector(1 downto 0); -- PSE connected signal -- POE OUT add-in card signals pse_rst : out std_logic; -- PSE reset pse_vpwr_enn : out std_logic; -- PSE enable (active low) pse_i2c_scl_io : inout std_logic; -- PSE I2C SCL signal pse_i2c_sda_io : inout std_logic; -- PSE I2C SDA signal pse_intn : in std_logic; -- PSE interrupt (active low) pse_vpwr_pg : in std_logic -- PSE power good signal ); end entity sim_switcher_top; architecture rtl of sim_switcher_top is component debounce is generic ( WAIT_CYCLES : integer := 5 ); port ( signal_in : in std_logic; signal_out : out std_logic; clk : in std_logic ); end component; constant FLASHES : natural := 5; -- Number of LED flashes on boot constant CPU_RST_DURATION : natural := 100_000_000; -- 25_000_000 = 1sec constant PON_RST_DURATION : natural := 10; -- 25_000_000 = 1sec constant PON_CPU_DELAY_DURATION : natural := 75_000_000; -- 25_000_000 = 1sec constant SB_CONF_UPDATE_INTERVAL : natural := 25_000_000; -- 25_000_000 = 1sec constant DEBOUNCING_WAIT_CYCLES : natural := 3; -- Number of debouncing wait cycles constant I2C_MAX_WAIT : natural := 2_500_000; -- 25_000_000 = 1sec signal s_clk_i : std_logic; -- clock buffer signal s_rstn_i : std_logic; -- reset signal signal s_rst_i : std_logic; -- reset signal -- Signals to detect CPU reset request falling edge signal s_cpu_rst_reqn : std_logic; signal s_cpu_rst_reqn_prev : std_logic; signal s_cpu_trst_dir_o : std_logic := '1'; signal s_rst_cntr_start : std_logic; -- CPU delay signal signal s_cpu_delay : std_logic := '1'; signal s_led_o : std_logic := '1'; -- I2C slave parallel interface signal i2c_read_req : std_logic := '0'; signal i2c_data_to_master : std_logic_vector(7 downto 0) := (others => '0'); signal i2c_data_valid : std_logic := '0'; signal i2c_data_from_master : std_logic_vector(7 downto 0) := (others => '0'); -- I2C slave state machine type i2c_fsm_t is (ready, receive_byte, wait_while_sent); signal i2c_slv_state : i2c_fsm_t := ready; signal reg_sim_pwr : std_logic_vector(15 downto 0); signal reg_sim_det : std_logic_vector(15 downto 0); signal s_reg_to_write : std_logic_vector(7 downto 0); -- SIM data signals signal s_sim_data_i, sdb_sim_data_i, sdb_sim_data_prev, s_sim_data_o: std_logic_vector(15 downto 0); -- Modem data signals signal s_mod_data_i, sdb_mod_data_i, sw_mod_data_i, sw_mod_data_prev, s_mod_data_o, sw_mod_data_o: std_logic_vector(7 downto 0); -- SIM board CONF bits register signal reg_sim_board_conf : std_logic_vector(2 downto 0); -- SIM switch IRQs for repeater state machine reset upon SIM change signal reg_sim_change_irq : std_logic_vector(15 downto 0) := (others => '0'); -- Modem LED register signal reg_mod_led : std_logic_vector(7 downto 0); -- Modem power register signal reg_mod_pwr : std_logic_vector(7 downto 0); -- PCI-e signals signal reg_pcie_rstn : std_logic_vector(7 downto 5); signal reg_pcie_waken : std_logic_vector(7 downto 5); -- M.2 modem wake host register signal reg_mod_hstwake : std_logic_vector(3 downto 0); -- FAN control register signal reg_fan_ctl : std_logic_vector(1 downto 0); -- PSE registers signal reg_pse_status : std_logic_vector(1 downto 0); signal reg_pse_ctl : std_logic_vector(1 downto 0); -- POE PD registers signal reg_poepd_status : std_logic_vector(2 downto 0); signal reg_poepd_ctl : std_logic; -- Expansion card IO tri-state control signal reg_expio_line : std_logic_vector(5 downto 0); signal reg_expio_output : std_logic_vector(5 downto 0); signal s_exp_card_i : std_logic_vector(5 downto 0); signal s_dbexp_card_i : std_logic_vector(5 downto 0); -- State machine signals and types type state_t is (idle, mod_to_sim, sim_to_mod); type arr_state_t is array (natural range <>) of state_t; signal state: arr_state_t(0 to 7); -- SIM-MODEM switching register signal reg_sim_modemnum: arr_modnum_t(0 to 7); begin -- Interrupt generation fpga_int_o <= not pse_intn; -- Currently unused SIM data lines for VirtualSIM s_sim_data_i(15 downto 8) <= (others => '1'); sdb_sim_data_i(15 downto 8) <= (others => '1'); -- Fill SIM detect register reg_sim_det(7 downto 0) <= sim_detect_i; reg_sim_det(15 downto 8) <= (others => '0'); -- Drive modem LEDs and Power mod_led_o <= reg_mod_led; mod_pwr_o <= reg_mod_pwr; -- Drive PCI-e RSTn and WAKEn signals mod_rstn_o <= reg_pcie_rstn; reg_pcie_waken <= mod_pciehstwake_i; -- Drive M.2 wake host signals reg_mod_hstwake <= mod_wake_host_i; -- Drive FAN control signals fan_o <= reg_fan_ctl; -- PSE init pse_rst <= reg_pse_ctl(0); pse_vpwr_enn <= reg_pse_ctl(1); reg_pse_status <= pse_intn&pse_vpwr_pg; -- Connect PSE I2C bus to main I2C bus pse_scl_rptr: odio_repeater generic map ( WAIT_CYCLES => DEBOUNCING_WAIT_CYCLES ) port map ( clk => clk25_i, rstn => s_rstn_i, signal_n1 => i2c_scl_io, signal_n2 => pse_i2c_scl_io ); pse_sda_rptr: odio_repeater generic map ( WAIT_CYCLES => DEBOUNCING_WAIT_CYCLES ) port map ( clk => clk25_i, rstn => s_rstn_i, signal_n1 => i2c_sda_io, signal_n2 => pse_i2c_sda_io ); -- POE PD init reg_poepd_status <= poe_in_vpres&poe_in_t2p; poe_in_enn <= reg_poepd_ctl; -- Expansion card IO control gen_expio_dbnc: for i in 0 to 5 generate s_exp_card_i(i) <= exp_card_io(i); exp_card_io(i) <= '0' when reg_expio_output(i) = '0' else 'Z'; reg_expio_line(i) <= s_dbexp_card_i(i); expio_debounce : debounce generic map ( WAIT_CYCLES => DEBOUNCING_WAIT_CYCLES ) port map ( clk => clk25_i, signal_in => s_exp_card_i(i), signal_out => s_dbexp_card_i(i) ); end generate gen_expio_dbnc; --------------------------------------------------------- ---------------------------------- -- Power-On FPGA IP-cores reset -- ---------------------------------- pon_rst_proc: process(clk25_i) is variable wait_cnt : natural := 0; begin if (rising_edge(clk25_i)) then if (wait_cnt > PON_RST_DURATION) then s_rstn_i <= '1'; else wait_cnt := wait_cnt + 1; s_rstn_i <= '0'; end if; end if; end process; s_rst_i <= not s_rstn_i; ----------------------- -- Startup LED blink -- ----------------------- led_o <= s_led_o; led_blink_proc: process(clk25_i) is variable wait_cnt : natural := 0; variable flash_cnt : natural := 0; begin if (rising_edge(clk25_i)) then if (wait_cnt > SYSFREQ/4) then if (flash_cnt <= (FLASHES-1)*2) then wait_cnt := 0; s_led_o <= not s_led_o; flash_cnt := flash_cnt + 1; end if; end if; if (flash_cnt <= FLASHES*2) then wait_cnt := wait_cnt + 1; end if; end if; end process; ------------------------------ -- Power-On CPU start delay -- ------------------------------ pon_cpu_start_proc: process(clk25_i) is variable wait_cnt : natural := 0; begin if (rising_edge(clk25_i)) then if (wait_cnt > PON_CPU_DELAY_DURATION) then s_cpu_delay <= '1'; else wait_cnt := wait_cnt + 1; s_cpu_delay <= '0'; end if; end if; end process; ------------------------------------- -- Reset generator per CPU request -- ------------------------------------- s_cpu_rst_reqn <= cpu_rst_reqn_i; cpu_trstn_o <= '0' when s_cpu_trst_dir_o = '0' or s_cpu_delay = '0' else 'Z'; --pg_10v_i and pg_25v_i and pg_33v_i; --cpu_trstn_o <= pg_10v_i and pg_25v_i and pg_33v_i; cpu_jtag_rstn_o <= '0' when s_cpu_trst_dir_o = '0' or s_cpu_delay = '0' else 'Z'; cpu_rst_gen_proc: process(clk25_i, s_rstn_i, cpu_rst_reqn_i) is variable wait_cnt : natural := CPU_RST_DURATION; begin if s_rstn_i = '0' then wait_cnt := 0; s_rst_cntr_start <= '0'; s_cpu_rst_reqn_prev <= cpu_rst_reqn_i; elsif rising_edge(clk25_i) then s_cpu_rst_reqn_prev <= s_cpu_rst_reqn; -- Capture value of RESET_REQn for further edge detection -- Check for start if s_rst_cntr_start = '1' then if (wait_cnt >= CPU_RST_DURATION) then s_cpu_trst_dir_o <= '1'; s_rst_cntr_start <= '0'; else wait_cnt := wait_cnt + 1; s_cpu_trst_dir_o <= '0'; end if; else if (s_cpu_rst_reqn_prev = '1' and s_cpu_rst_reqn = '0') then wait_cnt := 0; s_rst_cntr_start <= '1'; end if; end if; end if; end process; --------------------------- -- SIM board CONF update -- --------------------------- sb_conf_upd_proc: process(clk25_i, s_rstn_i, sb_conf_i) is variable wait_cnt : natural := 0; begin if s_rstn_i = '0' then wait_cnt := 0; reg_sim_board_conf <= sb_conf_i; elsif (rising_edge(clk25_i)) then if (wait_cnt > SB_CONF_UPDATE_INTERVAL) then wait_cnt := 0; reg_sim_board_conf <= sb_conf_i; else wait_cnt := wait_cnt + 1; end if; end if; end process; -------------------------------- -- I2C slave interface to CPU -- -------------------------------- inst_i2c_slave: i2c_slave generic map ( SLAVE_ADDR => I2C_SLAVE_ADDR ) port map( scl => i2c_scl_io, sda => i2c_sda_io, clk => clk25_i, rst => s_rst_i, read_req => i2c_read_req, data_to_master => i2c_data_to_master, data_valid => i2c_data_valid, data_from_master => i2c_data_from_master ); i2c_slv_process : process (clk25_i, s_rstn_i) variable wait_cnt : natural := 0; begin if (s_rstn_i = '0') then i2c_data_to_master <= (others => '0'); wait_cnt := 0; -- SIM attach reset assigment: default is 1-to-1 SIM to MODEM connection reg_sim_modemnum <= ( 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7 ); -- SIM change IRQ register reset reg_sim_change_irq <= (others => '0'); -- Turn on all SIM cards reg_sim_pwr(7 downto 0) <= (others => '1'); -- Real SIMs power is on reg_sim_pwr(15 downto 8) <= (others => '0'); -- Virtual SIMs power is "off" reg_mod_led <= (others => '0'); -- Modem LEDs are not lit reg_mod_pwr <= (others => '0'); -- Modem power is off reg_pcie_rstn <= (others => '1'); -- PCIe RSTn is not active reg_fan_ctl <= (others => '0'); -- FANs are off reg_pse_ctl <= (others => '0'); -- POE out is on reg_poepd_ctl <= '0'; -- POE PD enabled reg_expio_output <= (others => '1'); -- All Expansion card IOs in HighZ at start elsif (rising_edge(clk25_i)) then case i2c_slv_state is when ready => wait_cnt := 0; i2c_data_to_master <= (others => '0'); if (i2c_data_valid = '1') then -- master sent a register addr byte -- Save register address for later use in write procedure s_reg_to_write <= i2c_data_from_master; case i2c_data_from_master is when x"10" => -- Read ID byte i2c_data_to_master <= x"18"; i2c_slv_state <= wait_while_sent; when x"11" => -- Read SW Version byte (v1.0=0x18 MBCr1, v1.1=0x19 MBSr1, v2.0=0x28 MBSr2) i2c_data_to_master <= x"28"; i2c_slv_state <= wait_while_sent; when x"12" => -- Read SIM board model regiser i2c_data_to_master <= "00000" & reg_sim_board_conf; i2c_slv_state <= wait_while_sent; when x"13" => -- Read FAN control regiser i2c_data_to_master <= "000000" & reg_fan_ctl; i2c_slv_state <= wait_while_sent; when x"14" => -- Read POE OUT status register i2c_data_to_master <= "000000" & reg_pse_status; i2c_slv_state <= wait_while_sent; when x"15" => -- Read POE OUT control register i2c_data_to_master <= "000000" & reg_pse_ctl; i2c_slv_state <= wait_while_sent; when x"16" => -- Read POE IN status register i2c_data_to_master <= "00000" & reg_poepd_status; i2c_slv_state <= wait_while_sent; when x"17" => -- Read POE IN control register i2c_data_to_master <= "0000000" & reg_poepd_ctl; i2c_slv_state <= wait_while_sent; when x"18" => -- Read Expansion card IO lines i2c_data_to_master <= "00" & reg_expio_line; i2c_slv_state <= wait_while_sent; when x"19" => -- Read Expansion card output register i2c_data_to_master <= "00" & reg_expio_output; i2c_slv_state <= wait_while_sent; when x"05" => -- Read M.2 modem wake host register i2c_data_to_master <= "0000"®_mod_hstwake(3 downto 0); i2c_slv_state <= wait_while_sent; when x"06" => -- Read modem LED register i2c_data_to_master <= reg_mod_led(7 downto 0); i2c_slv_state <= wait_while_sent; when x"07" => -- Read modem power register i2c_data_to_master <= reg_mod_pwr(7 downto 0); i2c_slv_state <= wait_while_sent; when x"08" => -- Read PCIe RSTn register i2c_data_to_master <= reg_pcie_rstn(7 downto 5)&"00000"; i2c_slv_state <= wait_while_sent; when x"09" => -- Read PCIe WAKEn register i2c_data_to_master <= reg_pcie_waken(7 downto 5)&"00000"; i2c_slv_state <= wait_while_sent; when x"0A" => -- Read SIM detect register (LSB) i2c_data_to_master <= reg_sim_det(7 downto 0); i2c_slv_state <= wait_while_sent; -- when x"0B" => -- Read SIM detect register (MSB) -- i2c_data_to_master <= reg_sim_det(15 downto 8); -- i2c_slv_state <= wait_while_sent; when x"0C" => -- Read SIM power register (LSB) i2c_data_to_master <= reg_sim_pwr(7 downto 0); i2c_slv_state <= wait_while_sent; -- when x"0D" => -- Read SIM power register (MSB) -- i2c_data_to_master <= reg_sim_pwr(15 downto 8); -- i2c_slv_state <= wait_while_sent; when x"20" => -- Read SIM1 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(0),4)); i2c_slv_state <= wait_while_sent; when x"21" => -- Read SIM2 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(1),4)); i2c_slv_state <= wait_while_sent; when x"22" => -- Read SIM3 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(2),4)); i2c_slv_state <= wait_while_sent; when x"23" => -- Read SIM4 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(3),4)); i2c_slv_state <= wait_while_sent; when x"24" => -- Read SIM5 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(4),4)); i2c_slv_state <= wait_while_sent; when x"25" => -- Read SIM6 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(5),4)); i2c_slv_state <= wait_while_sent; when x"26" => -- Read SIM7 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(6),4)); i2c_slv_state <= wait_while_sent; when x"27" => -- Read SIM8 modem register i2c_data_to_master <= "0000" & std_logic_vector(to_unsigned(reg_sim_modemnum(7),4)); i2c_slv_state <= wait_while_sent; when x"86" => -- Write modem LED register i2c_slv_state <= receive_byte; when x"87" => -- Write modem power register i2c_slv_state <= receive_byte; when x"88" => -- Write PCIe RSTn register i2c_slv_state <= receive_byte; when x"8C" => -- Write SIMs power register (LSB) i2c_slv_state <= receive_byte; -- when x"8D" => -- Write SIMs power register (MSB) -- i2c_slv_state <= receive_byte; when x"93" => -- Write FAN control regiser i2c_slv_state <= receive_byte; when x"95" => -- Write POE OUT control register i2c_slv_state <= receive_byte; when x"97" => -- Write POE IN control register i2c_slv_state <= receive_byte; when x"99" => -- Write Expansion card output register i2c_slv_state <= receive_byte; when x"A0" => -- Write SIM1 modem register i2c_slv_state <= receive_byte; when x"A1" => -- Write SIM2 modem register i2c_slv_state <= receive_byte; when x"A2" => -- Write SIM3 modem register i2c_slv_state <= receive_byte; when x"A3" => -- Write SIM4 modem register i2c_slv_state <= receive_byte; when x"A4" => -- Write SIM5 modem register i2c_slv_state <= receive_byte; when x"A5" => -- Write SIM6 modem register i2c_slv_state <= receive_byte; when x"A6" => -- Write SIM7 modem register i2c_slv_state <= receive_byte; when x"A7" => -- Write SIM8 modem register i2c_slv_state <= receive_byte; when others => i2c_slv_state <= ready; end case; end if; when receive_byte => if (i2c_data_valid = '1') then case s_reg_to_write is when x"86" => -- Write modem LED register reg_mod_led(7 downto 0) <= i2c_data_from_master(7 downto 0); when x"87" => -- Write modem power register reg_mod_pwr(7 downto 0) <= i2c_data_from_master(7 downto 0); when x"88" => -- Write PCIe RSTn register reg_pcie_rstn(7 downto 5) <= i2c_data_from_master(7 downto 5); when x"8C" => -- Write SIMs power register (LSB) reg_sim_pwr(7 downto 0) <= i2c_data_from_master(7 downto 0); -- when x"8D" => -- Write SIMs power register (MSB) -- reg_sim_pwr(15 downto 8) <= i2c_data_from_master(7 downto 0); when x"93" => -- Write FAN control regiser reg_fan_ctl(1 downto 0) <= i2c_data_from_master(1 downto 0); when x"95" => -- Write POE OUT control register reg_pse_ctl(1 downto 0) <= i2c_data_from_master(1 downto 0); when x"97" => -- Write POE IN control register reg_poepd_ctl <= i2c_data_from_master(0); when x"99" => -- Write Expansion card output register reg_expio_output <= i2c_data_from_master(5 downto 0); when x"A0" => -- Write SIM1 modem register reg_sim_modemnum(0) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when x"A1" => -- Write SIM2 modem register reg_sim_modemnum(1) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when x"A2" => -- Write SIM3 modem register reg_sim_modemnum(2) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when x"A3" => -- Write SIM4 modem register reg_sim_modemnum(3) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when x"A4" => -- Write SIM5 modem register reg_sim_modemnum(4) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when x"A5" => -- Write SIM6 modem register reg_sim_modemnum(5) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when x"A6" => -- Write SIM7 modem register reg_sim_modemnum(6) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when x"A7" => -- Write SIM8 modem register reg_sim_modemnum(7) <= to_integer(unsigned(i2c_data_from_master(3 downto 0))); when others => null; end case; i2c_slv_state <= ready; else -- Wait timer to prevent freeze in waiting state if (wait_cnt > I2C_MAX_WAIT) then i2c_slv_state <= ready; else wait_cnt := wait_cnt + 1; end if; end if; when wait_while_sent => if (i2c_read_req = '1') then i2c_slv_state <= ready; else -- Wait timer to prevent freeze in waiting state if (wait_cnt > I2C_MAX_WAIT) then i2c_slv_state <= ready; else wait_cnt := wait_cnt + 1; end if; end if; when others => i2c_slv_state <= ready; end case; end if; end process i2c_slv_process; -------------------------- --- SIM card switching --- -------------------------- -- Power on SIM card according to the reg_sim_pwr register sim_pwron_o <= reg_sim_pwr(7 downto 0); -- Bidir sinals routing gen_datalines: for i in 0 to 7 generate s_sim_data_i(i) <= sim_data_io(i); sim_data_io(i) <= '0' when s_sim_data_o(i) = '0' else 'Z'; s_mod_data_i(i) <= mod_data_io(i); mod_data_io(i) <= '0' when s_mod_data_o(i) = '0' else 'Z'; -- Debounce data lines mod_dat_i_debounce : debounce generic map ( WAIT_CYCLES => DEBOUNCING_WAIT_CYCLES ) port map ( clk => clk25_i, signal_in => s_mod_data_i(i), signal_out => sdb_mod_data_i(i) ); sim_dat_i_debounce : debounce generic map ( WAIT_CYCLES => DEBOUNCING_WAIT_CYCLES ) port map ( clk => clk25_i, signal_in => s_sim_data_i(i), signal_out => sdb_sim_data_i(i) ); end generate gen_datalines; -- Actual SIM/MODEM signal muxing sim_muxing : sim_mux port map ( reg_sim_modemnum => reg_sim_modemnum, sim_rst_o => sim_rst_o, mod_simrst_i => mod_simrst_i, sim_clk_o => sim_clk_o, mod_clk_i => mod_clk_i, mod_detect_o => mod_detect_o, sim_detect_i => sim_detect_i, sw_mod_data_i => sw_mod_data_i, -- For switched tri-state buffer there are input and output part of mod_data_i => sdb_mod_data_i, -- the lines which are switched transparently, thus ports mod_data_o => s_mod_data_o, -- sw_mod_data_i is actual output and sw_mod_data_o is sw_mod_data_o => sw_mod_data_o -- actual input. Please, don't be confused by conflicting name. ); ------------------ -- SIM repeater -- ------------------ sim_rptr_proc: process(clk25_i, s_rstn_i, sdb_sim_data_i, sdb_sim_data_prev, sw_mod_data_i, sw_mod_data_prev, reg_sim_change_irq) is begin if s_rstn_i = '0' then s_sim_data_o <= (others => '1'); sw_mod_data_o <= (others => '1'); sdb_sim_data_prev <= sdb_sim_data_i; sw_mod_data_prev <= sw_mod_data_i; state <= (others => idle); elsif (rising_edge(clk25_i)) then sdb_sim_data_prev <= sdb_sim_data_i; sw_mod_data_prev <= sw_mod_data_i; for i in 0 to 7 loop case state(i) is when idle => if (sw_mod_data_prev(i) = '1' and sw_mod_data_i(i) = '0') then s_sim_data_o(i) <= '0'; state(i) <= mod_to_sim; elsif (sdb_sim_data_prev(i) = '1' and sdb_sim_data_i(i) = '0') then sw_mod_data_o(i) <= '0'; state(i) <= sim_to_mod; end if; when mod_to_sim => if ((sw_mod_data_prev(i) = '0' and sw_mod_data_i(i) = '1') or reg_sim_change_irq(i) = '1') then s_sim_data_o(i) <= '1'; state(i) <= idle; end if; when sim_to_mod => if ((sdb_sim_data_prev(i) = '0' and sdb_sim_data_i(i) = '1') or reg_sim_change_irq(i) = '1') then sw_mod_data_o(i) <= '1'; state(i) <= idle; end if; end case; end loop; end if; end process; end architecture rtl;