mmv5_FirmwareMS/sim_switcher_top.vhd

807 lines
33 KiB
VHDL

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) := "1010110" -- Address of I2C slave, dafault 0x56
);
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;
-- 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
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_sel : sim_mux_addr_t(3 downto 0);
-- 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 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_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;
--------------------------------
-- 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 select reset: default is SIM#1
-- reg_sim_sel <= (others => (others => '0'));
-- -- Turn on all SIM cards
-- reg_sim_pwr <= (others => '1');
-- -- Only first SIMs are powered on upon reset
-- -- reg_sim_pwr(0) <= '1';
-- -- reg_sim_pwr(3 downto 1) <= (others => '0');
-- --
-- -- reg_sim_pwr(4) <= '1';
-- -- reg_sim_pwr(7 downto 5) <= (others => '0');
-- --
-- -- reg_sim_pwr(8) <= '1';
-- -- reg_sim_pwr(11 downto 9) <= (others => '0');
-- --
-- -- reg_sim_pwr(12) <= '1';
-- -- reg_sim_pwr(15 downto 13) <= (others => '0');
--
-- reg_sim_change_irq <= (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)
-- i2c_data_to_master <= x"19";
-- 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"1A" => -- Read M1 SIM select register
-- i2c_data_to_master <= "000000" & reg_sim_sel(0);
-- i2c_slv_state <= wait_while_sent;
-- when x"1B" => -- Read M2 SIM select register
-- i2c_data_to_master <= "000000" & reg_sim_sel(1);
-- i2c_slv_state <= wait_while_sent;
-- when x"1C" => -- Read M3 SIM select register
-- i2c_data_to_master <= "000000" & reg_sim_sel(2);
-- i2c_slv_state <= wait_while_sent;
-- when x"1D" => -- Read M4 SIM select register
-- i2c_data_to_master <= "000000" & reg_sim_sel(3);
-- 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"9A" => -- Write M1 select register
-- i2c_slv_state <= receive_byte;
-- when x"9B" => -- Write M2 select register
-- i2c_slv_state <= receive_byte;
-- when x"9C" => -- Write M3 select register
-- i2c_slv_state <= receive_byte;
-- when x"9D" => -- Write M4 select 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"9A" => -- Write M1 select register
-- reg_sim_sel(0) <= i2c_data_from_master(1 downto 0);
-- when x"9B" => -- Write M2 select register
-- reg_sim_sel(1) <= i2c_data_from_master(1 downto 0);
-- when x"9C" => -- Write M3 select register
-- reg_sim_sel(2) <= i2c_data_from_master(1 downto 0);
-- when x"9D" => -- Write M4 select register
-- reg_sim_sel(3) <= i2c_data_from_master(1 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 <= (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;