First commit
This commit is contained in:
commit
b06870f628
|
|
@ -0,0 +1,63 @@
|
||||||
|
------------------------------------------------------------
|
||||||
|
-- File : debounce.vhd
|
||||||
|
------------------------------------------------------------
|
||||||
|
-- Author : Peter Samarin <peter.samarin@gmail.com>
|
||||||
|
------------------------------------------------------------
|
||||||
|
-- Copyright (c) 2016 Peter Samarin
|
||||||
|
------------------------------------------------------------
|
||||||
|
-- Description: debouncing circuit that forwards only
|
||||||
|
-- signals that have been stable for the whole duration of
|
||||||
|
-- the counter
|
||||||
|
------------------------------------------------------------
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
------------------------------------------------------------
|
||||||
|
entity debounce is
|
||||||
|
generic (
|
||||||
|
WAIT_CYCLES : integer := 5);
|
||||||
|
port (
|
||||||
|
signal_in : in std_logic;
|
||||||
|
signal_out : out std_logic;
|
||||||
|
clk : in std_logic);
|
||||||
|
end entity debounce;
|
||||||
|
------------------------------------------------------------
|
||||||
|
architecture arch of debounce is
|
||||||
|
type state_t is (idle, check_input_stable);
|
||||||
|
signal state_reg : state_t := idle;
|
||||||
|
signal out_reg : std_logic := signal_in;
|
||||||
|
signal signal_in_reg : std_logic;
|
||||||
|
signal counter : integer range 0 to WAIT_CYCLES-1 := 0;
|
||||||
|
begin
|
||||||
|
|
||||||
|
process (clk) is
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
case state_reg is
|
||||||
|
when idle =>
|
||||||
|
if out_reg /= signal_in then
|
||||||
|
signal_in_reg <= signal_in;
|
||||||
|
state_reg <= check_input_stable;
|
||||||
|
counter <= WAIT_CYCLES-1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when check_input_stable =>
|
||||||
|
if counter = 0 then
|
||||||
|
if signal_in = signal_in_reg then
|
||||||
|
out_reg <= signal_in;
|
||||||
|
end if;
|
||||||
|
state_reg <= idle;
|
||||||
|
else
|
||||||
|
if signal_in /= signal_in_reg then
|
||||||
|
state_reg <= idle;
|
||||||
|
end if;
|
||||||
|
counter <= counter - 1;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
-- output
|
||||||
|
signal_out <= to_UX01(out_reg);
|
||||||
|
|
||||||
|
end architecture arch;
|
||||||
|
|
@ -0,0 +1,367 @@
|
||||||
|
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 := 4; -- 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';
|
||||||
|
|
||||||
|
-- SIM data signals
|
||||||
|
signal s_sim_data_i, sdb_sim_data_i, sdb_sim_data_prev, s_sim_data_o: std_logic_vector(7 downto 0);
|
||||||
|
|
||||||
|
-- Modem data signals
|
||||||
|
signal s_mod_data_i, sdb_mod_data_i, sdb_mod_data_prev, s_mod_data_o: std_logic_vector(7 downto 0);
|
||||||
|
|
||||||
|
type state_t is (idle, mod_to_sim, sim_to_mod);
|
||||||
|
type arr_state_t is array (integer range <>) of state_t;
|
||||||
|
signal state: arr_state_t(0 to 7);
|
||||||
|
begin
|
||||||
|
|
||||||
|
----------------------------------
|
||||||
|
-- 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 card emulation test ---
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
-- 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;
|
||||||
|
|
||||||
|
-- Route one-way signals from mod to SIM
|
||||||
|
sim_pwron_o <= (others => '1');--mod_pwron_i;
|
||||||
|
sim_rst_o <= mod_rst_i;
|
||||||
|
sim_clk_o <= mod_clk_i;
|
||||||
|
mod_detect_o(3 downto 0) <= sim_detect_i(3 downto 0);
|
||||||
|
|
||||||
|
------------------
|
||||||
|
-- SIM repeater --
|
||||||
|
------------------
|
||||||
|
sim_rptr_proc: process(clk25_i, s_rstn_i, sdb_sim_data_i, sdb_sim_data_prev, sdb_mod_data_i, sdb_mod_data_prev) is
|
||||||
|
begin
|
||||||
|
if s_rstn_i = '0' then
|
||||||
|
s_sim_data_o <= (others => '1');
|
||||||
|
s_mod_data_o <= (others => '1');
|
||||||
|
sdb_sim_data_prev <= sdb_sim_data_i;
|
||||||
|
sdb_mod_data_prev <= sdb_mod_data_i;
|
||||||
|
state <= (others => idle);
|
||||||
|
|
||||||
|
elsif (rising_edge(clk25_i)) then
|
||||||
|
sdb_sim_data_prev <= sdb_sim_data_i;
|
||||||
|
sdb_mod_data_prev <= sdb_mod_data_i;
|
||||||
|
|
||||||
|
for i in 0 to 7 loop
|
||||||
|
case state(i) is
|
||||||
|
when idle =>
|
||||||
|
if (sdb_mod_data_prev(i) = '1' and sdb_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
|
||||||
|
s_mod_data_o(i) <= '0';
|
||||||
|
state(i) <= sim_to_mod;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when mod_to_sim =>
|
||||||
|
if (sdb_mod_data_prev(i) = '0' and sdb_mod_data_i(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') then
|
||||||
|
s_mod_data_o(i) <= '1';
|
||||||
|
state(i) <= idle;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------
|
||||||
|
----- SIM card emulation test ---
|
||||||
|
---------------------------------
|
||||||
|
--
|
||||||
|
-- -- 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;
|
||||||
|
--
|
||||||
|
-- -- Route one-way signals from mod to SIM
|
||||||
|
-- sim_pwron_o <= (others => '1');--mod_pwron_i;
|
||||||
|
-- sim_rst_o <= mod_rst_i;
|
||||||
|
-- sim_clk_o <= mod_clk_i;
|
||||||
|
-- mod_detect_o(3 downto 0) <= sim_detect_i(3 downto 0);
|
||||||
|
--
|
||||||
|
-- ------------------
|
||||||
|
-- -- SIM repeater --
|
||||||
|
-- ------------------
|
||||||
|
-- sims: for num in 0 to 7 generate
|
||||||
|
-- sim_rptr_proc: process(clk25_i) is
|
||||||
|
-- begin
|
||||||
|
-- if s_rstn_i = '0' then
|
||||||
|
-- s_sim_data_o(num) <= '1';
|
||||||
|
-- s_mod_data_o(num) <= '1';
|
||||||
|
-- sdb_sim_data_prev(num) <= sdb_sim_data_i(num);
|
||||||
|
-- sdb_mod_data_prev(num) <= sdb_mod_data_i(num);
|
||||||
|
-- state(num) <= idle;
|
||||||
|
--
|
||||||
|
-- elsif (rising_edge(clk25_i)) then
|
||||||
|
-- sdb_sim_data_prev(num) <= sdb_sim_data_i(num);
|
||||||
|
-- sdb_mod_data_prev(num) <= sdb_mod_data_i(num);
|
||||||
|
--
|
||||||
|
-- case state(num) is
|
||||||
|
-- when idle =>
|
||||||
|
-- if (sdb_mod_data_prev(num) = '1' and sdb_mod_data_i(num) = '0') then
|
||||||
|
-- s_sim_data_o(num) <= '0';
|
||||||
|
-- state(num) <= mod_to_sim;
|
||||||
|
-- elsif (sdb_sim_data_prev(num) = '1' and sdb_sim_data_i(num) = '0') then
|
||||||
|
-- s_mod_data_o(num) <= '0';
|
||||||
|
-- state(num) <= sim_to_mod;
|
||||||
|
-- end if;
|
||||||
|
--
|
||||||
|
-- when mod_to_sim =>
|
||||||
|
-- if (sdb_mod_data_prev(num) = '0' and sdb_mod_data_i(num) = '1') then
|
||||||
|
-- s_sim_data_o(num) <= '1';
|
||||||
|
-- state(num) <= idle;
|
||||||
|
-- end if;
|
||||||
|
--
|
||||||
|
-- when sim_to_mod =>
|
||||||
|
-- if (sdb_sim_data_prev(num) = '0' and sdb_sim_data_i(num) = '1') then
|
||||||
|
-- s_mod_data_o(num) <= '1';
|
||||||
|
-- state(num) <= idle;
|
||||||
|
-- end if;
|
||||||
|
--
|
||||||
|
-- end case;
|
||||||
|
--
|
||||||
|
-- end if;
|
||||||
|
-- end process;
|
||||||
|
-- end generate sims;
|
||||||
|
|
||||||
|
|
||||||
|
end architecture rtl;
|
||||||
Loading…
Reference in New Issue