First commit

This commit is contained in:
matt 2020-02-07 17:18:28 +07:00
commit b06870f628
2 changed files with 430 additions and 0 deletions

63
debounce.vhd Normal file
View File

@ -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;

367
sim_switcher_top.vhd Normal file
View File

@ -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;