1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
library ieee;
use ieee.std_logic_1164.all;
entity scl_generator is
generic (
MIN_STABLE_CYCLES : natural := 5);
port (
clk_i : in std_logic;
rst_in : in std_logic;
scl_i : in std_logic;
scl_rising_i : in std_logic;
scl_falling_i : in std_logic;
gen_continuous_i : in std_logic;
gen_rising_i : in std_logic;
gen_falling_i : in std_logic;
scl_enable_o : out std_logic;
cannot_comply_o : out std_logic);
end entity scl_generator;
architecture a1 of scl_generator is
signal should_fall : std_logic;
signal should_rise : std_logic;
signal should_change : std_logic;
signal can_change : std_logic;
signal req_change : std_logic;
signal scl_changing : std_logic;
signal exp_scl : std_logic;
signal curr_stable_count : integer range 0 to MIN_STABLE_CYCLES;
signal next_stable_count : integer range 0 to MIN_STABLE_CYCLES;
signal curr_scl_enable : std_logic;
signal next_scl_enable : std_logic;
begin -- architecture a1
scl_enable_o <= curr_scl_enable;
cannot_comply_o <= (scl_i xor (not curr_scl_enable)) and should_change;
should_rise <= (gen_rising_i or gen_continuous_i) and not scl_i;
should_fall <= (gen_falling_i or gen_continuous_i) and scl_i;
should_change <= should_rise or should_fall;
can_change <= '1' when curr_stable_count = MIN_STABLE_CYCLES else '0';
-- requests a change of the SCL, not of SCL enable
req_change <= '1' when (can_change and should_change) = '1' and next_stable_count /= 0 else '0';
exp_scl <= '1' when should_rise = '1' and req_change = '1' else
'0' when should_fall = '1' and req_change = '1' else
not curr_scl_enable;
next_scl_enable <= not exp_scl;
scl_changing <= scl_rising_i or scl_falling_i;
next_stable_count <= 0 when scl_changing = '1' else
curr_stable_count + 1 when can_change = '0' and curr_stable_count < MIN_STABLE_CYCLES else
curr_stable_count;
set_regs: process (clk_i) is
begin -- process set_regs
if rising_edge(clk_i) then -- rising clock edge
if rst_in = '0' then -- synchronous reset (active low)
curr_stable_count <= 0;
curr_scl_enable <= '0';
else
curr_stable_count <= next_stable_count;
curr_scl_enable <= next_scl_enable;
end if;
end if;
end process set_regs;
end architecture a1;