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; -- I2C slave interface i2c_scl_io : inout std_logic; i2c_sda_io : inout std_logic; -- SIM board CONF bits sim_board_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 signals vsim_data_io : inout std_logic_vector(3 downto 0); -- Modem signals mod_detect_o : out std_logic_vector(3 downto 0); mod_wake_host_i : in std_logic_vector(3 downto 0); mod_pwron_i : in std_logic_vector(7 downto 0); mod_rst_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) ); 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 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'); -- 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 type arr_modnum_t is array (natural range <>) of natural range 0 to 15; signal reg_sim_modemnum: arr_modnum_t(0 to 7); begin s_sim_data_i(15 downto 8) <= (others => '1'); sdb_sim_data_i(15 downto 8) <= (others => '1'); reg_sim_det(7 downto 0) <= sim_detect_i; reg_sim_det(15 downto 8) <= (others => '0'); -- reg_sim_modemnum <= ( -- 0 => 7, -- 1 => 6, -- 2 => 5, -- 3 => 4, -- 4 => 3, -- 5 => 2, -- 6 => 1, -- 7 => 0 -- ); -- reg_sim_change_irq <= (others => '0'); ---------------------------------- -- 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 -- --------------------------- simb_conf_upd_proc: process(clk25_i) is begin if (rising_edge(clk25_i)) then reg_sim_board_conf <= sim_board_conf_i; 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'); reg_sim_pwr(15 downto 8) <= (others => '0'); 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, v1.1=0x19, v2.0=0x28) i2c_data_to_master <= x"20"; 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"0A" => -- Read SIMs detect register (LSB) i2c_data_to_master <= reg_sim_det(7 downto 0); i2c_slv_state <= wait_while_sent; -- when x"0B" => -- Read SIMs detect register (MSB) -- i2c_data_to_master <= reg_sim_det(15 downto 8); -- i2c_slv_state <= wait_while_sent; when x"0C" => -- Read SIMs power register (LSB) i2c_data_to_master <= reg_sim_pwr(7 downto 0); i2c_slv_state <= wait_while_sent; -- when x"0D" => -- Read SIMs 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"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"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"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"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 emulation test --- ------------------------------- -- Switch RST line of SIM according to connected MODEM sim_rst_o(0) <= mod_rst_i(0) when reg_sim_modemnum(0) = 0 else mod_rst_i(1) when reg_sim_modemnum(0) = 1 else mod_rst_i(2) when reg_sim_modemnum(0) = 2 else mod_rst_i(3) when reg_sim_modemnum(0) = 3 else mod_rst_i(4) when reg_sim_modemnum(0) = 4 else mod_rst_i(5) when reg_sim_modemnum(0) = 5 else mod_rst_i(6) when reg_sim_modemnum(0) = 6 else mod_rst_i(7) when reg_sim_modemnum(0) = 7 else 'Z'; sim_rst_o(1) <= mod_rst_i(0) when reg_sim_modemnum(1) = 0 else mod_rst_i(1) when reg_sim_modemnum(1) = 1 else mod_rst_i(2) when reg_sim_modemnum(1) = 2 else mod_rst_i(3) when reg_sim_modemnum(1) = 3 else mod_rst_i(4) when reg_sim_modemnum(1) = 4 else mod_rst_i(5) when reg_sim_modemnum(1) = 5 else mod_rst_i(6) when reg_sim_modemnum(1) = 6 else mod_rst_i(7) when reg_sim_modemnum(1) = 7 else 'Z'; sim_rst_o(2) <= mod_rst_i(0) when reg_sim_modemnum(2) = 0 else mod_rst_i(1) when reg_sim_modemnum(2) = 1 else mod_rst_i(2) when reg_sim_modemnum(2) = 2 else mod_rst_i(3) when reg_sim_modemnum(2) = 3 else mod_rst_i(4) when reg_sim_modemnum(2) = 4 else mod_rst_i(5) when reg_sim_modemnum(2) = 5 else mod_rst_i(6) when reg_sim_modemnum(2) = 6 else mod_rst_i(7) when reg_sim_modemnum(2) = 7 else 'Z'; sim_rst_o(3) <= mod_rst_i(0) when reg_sim_modemnum(3) = 0 else mod_rst_i(1) when reg_sim_modemnum(3) = 1 else mod_rst_i(2) when reg_sim_modemnum(3) = 2 else mod_rst_i(3) when reg_sim_modemnum(3) = 3 else mod_rst_i(4) when reg_sim_modemnum(3) = 4 else mod_rst_i(5) when reg_sim_modemnum(3) = 5 else mod_rst_i(6) when reg_sim_modemnum(3) = 6 else mod_rst_i(7) when reg_sim_modemnum(3) = 7 else 'Z'; sim_rst_o(4) <= mod_rst_i(0) when reg_sim_modemnum(4) = 0 else mod_rst_i(1) when reg_sim_modemnum(4) = 1 else mod_rst_i(2) when reg_sim_modemnum(4) = 2 else mod_rst_i(3) when reg_sim_modemnum(4) = 3 else mod_rst_i(4) when reg_sim_modemnum(4) = 4 else mod_rst_i(5) when reg_sim_modemnum(4) = 5 else mod_rst_i(6) when reg_sim_modemnum(4) = 6 else mod_rst_i(7) when reg_sim_modemnum(4) = 7 else 'Z'; sim_rst_o(5) <= mod_rst_i(0) when reg_sim_modemnum(5) = 0 else mod_rst_i(1) when reg_sim_modemnum(5) = 1 else mod_rst_i(2) when reg_sim_modemnum(5) = 2 else mod_rst_i(3) when reg_sim_modemnum(5) = 3 else mod_rst_i(4) when reg_sim_modemnum(5) = 4 else mod_rst_i(5) when reg_sim_modemnum(5) = 5 else mod_rst_i(6) when reg_sim_modemnum(5) = 6 else mod_rst_i(7) when reg_sim_modemnum(5) = 7 else 'Z'; sim_rst_o(6) <= mod_rst_i(0) when reg_sim_modemnum(6) = 0 else mod_rst_i(1) when reg_sim_modemnum(6) = 1 else mod_rst_i(2) when reg_sim_modemnum(6) = 2 else mod_rst_i(3) when reg_sim_modemnum(6) = 3 else mod_rst_i(4) when reg_sim_modemnum(6) = 4 else mod_rst_i(5) when reg_sim_modemnum(6) = 5 else mod_rst_i(6) when reg_sim_modemnum(6) = 6 else mod_rst_i(7) when reg_sim_modemnum(6) = 7 else 'Z'; sim_rst_o(7) <= mod_rst_i(0) when reg_sim_modemnum(7) = 0 else mod_rst_i(1) when reg_sim_modemnum(7) = 1 else mod_rst_i(2) when reg_sim_modemnum(7) = 2 else mod_rst_i(3) when reg_sim_modemnum(7) = 3 else mod_rst_i(4) when reg_sim_modemnum(7) = 4 else mod_rst_i(5) when reg_sim_modemnum(7) = 5 else mod_rst_i(6) when reg_sim_modemnum(7) = 6 else mod_rst_i(7) when reg_sim_modemnum(7) = 7 else 'Z'; -- Switch CLK line of SIM according to connected MODEM sim_clk_o(0) <= mod_clk_i(0) when reg_sim_modemnum(0) = 0 else mod_clk_i(1) when reg_sim_modemnum(0) = 1 else mod_clk_i(2) when reg_sim_modemnum(0) = 2 else mod_clk_i(3) when reg_sim_modemnum(0) = 3 else mod_clk_i(4) when reg_sim_modemnum(0) = 4 else mod_clk_i(5) when reg_sim_modemnum(0) = 5 else mod_clk_i(6) when reg_sim_modemnum(0) = 6 else mod_clk_i(7) when reg_sim_modemnum(0) = 7 else 'Z'; sim_clk_o(1) <= mod_clk_i(0) when reg_sim_modemnum(1) = 0 else mod_clk_i(1) when reg_sim_modemnum(1) = 1 else mod_clk_i(2) when reg_sim_modemnum(1) = 2 else mod_clk_i(3) when reg_sim_modemnum(1) = 3 else mod_clk_i(4) when reg_sim_modemnum(1) = 4 else mod_clk_i(5) when reg_sim_modemnum(1) = 5 else mod_clk_i(6) when reg_sim_modemnum(1) = 6 else mod_clk_i(7) when reg_sim_modemnum(1) = 7 else 'Z'; sim_clk_o(2) <= mod_clk_i(0) when reg_sim_modemnum(2) = 0 else mod_clk_i(1) when reg_sim_modemnum(2) = 1 else mod_clk_i(2) when reg_sim_modemnum(2) = 2 else mod_clk_i(3) when reg_sim_modemnum(2) = 3 else mod_clk_i(4) when reg_sim_modemnum(2) = 4 else mod_clk_i(5) when reg_sim_modemnum(2) = 5 else mod_clk_i(6) when reg_sim_modemnum(2) = 6 else mod_clk_i(7) when reg_sim_modemnum(2) = 7 else 'Z'; sim_clk_o(3) <= mod_clk_i(0) when reg_sim_modemnum(3) = 0 else mod_clk_i(1) when reg_sim_modemnum(3) = 1 else mod_clk_i(2) when reg_sim_modemnum(3) = 2 else mod_clk_i(3) when reg_sim_modemnum(3) = 3 else mod_clk_i(4) when reg_sim_modemnum(3) = 4 else mod_clk_i(5) when reg_sim_modemnum(3) = 5 else mod_clk_i(6) when reg_sim_modemnum(3) = 6 else mod_clk_i(7) when reg_sim_modemnum(3) = 7 else 'Z'; sim_clk_o(4) <= mod_clk_i(0) when reg_sim_modemnum(4) = 0 else mod_clk_i(1) when reg_sim_modemnum(4) = 1 else mod_clk_i(2) when reg_sim_modemnum(4) = 2 else mod_clk_i(3) when reg_sim_modemnum(4) = 3 else mod_clk_i(4) when reg_sim_modemnum(4) = 4 else mod_clk_i(5) when reg_sim_modemnum(4) = 5 else mod_clk_i(6) when reg_sim_modemnum(4) = 6 else mod_clk_i(7) when reg_sim_modemnum(4) = 7 else 'Z'; sim_clk_o(5) <= mod_clk_i(0) when reg_sim_modemnum(5) = 0 else mod_clk_i(1) when reg_sim_modemnum(5) = 1 else mod_clk_i(2) when reg_sim_modemnum(5) = 2 else mod_clk_i(3) when reg_sim_modemnum(5) = 3 else mod_clk_i(4) when reg_sim_modemnum(5) = 4 else mod_clk_i(5) when reg_sim_modemnum(5) = 5 else mod_clk_i(6) when reg_sim_modemnum(5) = 6 else mod_clk_i(7) when reg_sim_modemnum(5) = 7 else 'Z'; sim_clk_o(6) <= mod_clk_i(0) when reg_sim_modemnum(6) = 0 else mod_clk_i(1) when reg_sim_modemnum(6) = 1 else mod_clk_i(2) when reg_sim_modemnum(6) = 2 else mod_clk_i(3) when reg_sim_modemnum(6) = 3 else mod_clk_i(4) when reg_sim_modemnum(6) = 4 else mod_clk_i(5) when reg_sim_modemnum(6) = 5 else mod_clk_i(6) when reg_sim_modemnum(6) = 6 else mod_clk_i(7) when reg_sim_modemnum(6) = 7 else 'Z'; sim_clk_o(7) <= mod_clk_i(0) when reg_sim_modemnum(7) = 0 else mod_clk_i(1) when reg_sim_modemnum(7) = 1 else mod_clk_i(2) when reg_sim_modemnum(7) = 2 else mod_clk_i(3) when reg_sim_modemnum(7) = 3 else mod_clk_i(4) when reg_sim_modemnum(7) = 4 else mod_clk_i(5) when reg_sim_modemnum(7) = 5 else mod_clk_i(6) when reg_sim_modemnum(7) = 6 else mod_clk_i(7) when reg_sim_modemnum(7) = 7 else 'Z'; -- Switch SIM DETECT line of SIM according to connected MODEM, mod_detect_o(0) <= sim_detect_i(0) when reg_sim_modemnum(0) = 0 else sim_detect_i(1) when reg_sim_modemnum(1) = 0 else sim_detect_i(2) when reg_sim_modemnum(2) = 0 else sim_detect_i(3) when reg_sim_modemnum(3) = 0 else sim_detect_i(4) when reg_sim_modemnum(4) = 0 else sim_detect_i(5) when reg_sim_modemnum(5) = 0 else sim_detect_i(6) when reg_sim_modemnum(6) = 0 else sim_detect_i(7) when reg_sim_modemnum(7) = 0 else 'Z'; mod_detect_o(1) <= sim_detect_i(0) when reg_sim_modemnum(0) = 1 else sim_detect_i(1) when reg_sim_modemnum(1) = 1 else sim_detect_i(2) when reg_sim_modemnum(2) = 1 else sim_detect_i(3) when reg_sim_modemnum(3) = 1 else sim_detect_i(4) when reg_sim_modemnum(4) = 1 else sim_detect_i(5) when reg_sim_modemnum(5) = 1 else sim_detect_i(6) when reg_sim_modemnum(6) = 1 else sim_detect_i(7) when reg_sim_modemnum(7) = 1 else 'Z'; mod_detect_o(2) <= sim_detect_i(0) when reg_sim_modemnum(0) = 2 else sim_detect_i(1) when reg_sim_modemnum(1) = 2 else sim_detect_i(2) when reg_sim_modemnum(2) = 2 else sim_detect_i(3) when reg_sim_modemnum(3) = 2 else sim_detect_i(4) when reg_sim_modemnum(4) = 2 else sim_detect_i(5) when reg_sim_modemnum(5) = 2 else sim_detect_i(6) when reg_sim_modemnum(6) = 2 else sim_detect_i(7) when reg_sim_modemnum(7) = 2 else 'Z'; mod_detect_o(3) <= sim_detect_i(0) when reg_sim_modemnum(0) = 3 else sim_detect_i(1) when reg_sim_modemnum(1) = 3 else sim_detect_i(2) when reg_sim_modemnum(2) = 3 else sim_detect_i(3) when reg_sim_modemnum(3) = 3 else sim_detect_i(4) when reg_sim_modemnum(4) = 3 else sim_detect_i(5) when reg_sim_modemnum(5) = 3 else sim_detect_i(6) when reg_sim_modemnum(6) = 3 else sim_detect_i(7) when reg_sim_modemnum(7) = 3 else 'Z'; -- Route one-way signals from mod to SIM sim_pwron_o <= reg_sim_pwr(7 downto 0);--(others => '1');--mod_pwron_i; --mod_detect_o(3 downto 0) <= sim_detect_i(3 downto 0); --!! Switching -- 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'; --sim_rst_o(i) <= mod_rst_i(i); --!! Switching --sim_clk_o(i) <= mod_clk_i(i); --!! Switching -- 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; sw_mod_data_i(0) <= sdb_mod_data_i(0) when reg_sim_modemnum(0) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(0) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(0) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(0) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(0) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(0) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(0) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(0) = 7 else 'Z'; sw_mod_data_i(1) <= sdb_mod_data_i(0) when reg_sim_modemnum(1) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(1) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(1) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(1) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(1) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(1) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(1) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(1) = 7 else 'Z'; sw_mod_data_i(2) <= sdb_mod_data_i(0) when reg_sim_modemnum(2) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(2) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(2) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(2) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(2) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(2) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(2) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(2) = 7 else 'Z'; sw_mod_data_i(3) <= sdb_mod_data_i(0) when reg_sim_modemnum(3) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(3) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(3) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(3) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(3) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(3) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(3) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(3) = 7 else 'Z'; sw_mod_data_i(4) <= sdb_mod_data_i(0) when reg_sim_modemnum(4) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(4) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(4) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(4) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(4) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(4) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(4) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(4) = 7 else 'Z'; sw_mod_data_i(5) <= sdb_mod_data_i(0) when reg_sim_modemnum(5) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(5) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(5) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(5) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(5) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(5) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(5) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(5) = 7 else 'Z'; sw_mod_data_i(6) <= sdb_mod_data_i(0) when reg_sim_modemnum(6) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(6) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(6) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(6) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(6) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(6) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(6) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(6) = 7 else 'Z'; sw_mod_data_i(7) <= sdb_mod_data_i(0) when reg_sim_modemnum(7) = 0 else sdb_mod_data_i(1) when reg_sim_modemnum(7) = 1 else sdb_mod_data_i(2) when reg_sim_modemnum(7) = 2 else sdb_mod_data_i(3) when reg_sim_modemnum(7) = 3 else sdb_mod_data_i(4) when reg_sim_modemnum(7) = 4 else sdb_mod_data_i(5) when reg_sim_modemnum(7) = 5 else sdb_mod_data_i(6) when reg_sim_modemnum(7) = 6 else sdb_mod_data_i(7) when reg_sim_modemnum(7) = 7 else 'Z'; s_mod_data_o(0) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 0 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 0 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 0 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 0 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 0 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 0 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 0 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 0 else 'Z'; s_mod_data_o(1) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 1 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 1 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 1 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 1 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 1 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 1 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 1 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 1 else 'Z'; s_mod_data_o(2) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 2 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 2 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 2 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 2 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 2 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 2 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 2 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 2 else 'Z'; s_mod_data_o(3) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 3 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 3 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 3 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 3 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 3 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 3 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 3 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 3 else 'Z'; s_mod_data_o(4) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 4 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 4 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 4 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 4 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 4 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 4 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 4 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 4 else 'Z'; s_mod_data_o(5) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 5 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 5 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 5 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 5 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 5 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 5 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 5 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 5 else 'Z'; s_mod_data_o(6) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 6 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 6 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 6 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 6 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 6 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 6 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 6 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 6 else 'Z'; s_mod_data_o(7) <= sw_mod_data_o(0) when reg_sim_modemnum(0) = 7 else sw_mod_data_o(1) when reg_sim_modemnum(1) = 7 else sw_mod_data_o(2) when reg_sim_modemnum(2) = 7 else sw_mod_data_o(3) when reg_sim_modemnum(3) = 7 else sw_mod_data_o(4) when reg_sim_modemnum(4) = 7 else sw_mod_data_o(5) when reg_sim_modemnum(5) = 7 else sw_mod_data_o(6) when reg_sim_modemnum(6) = 7 else sw_mod_data_o(7) when reg_sim_modemnum(7) = 7 else 'Z'; ------------------ -- 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;