~ruther/vhdl-i2c

ref: da60d1f13356b798f9fc9a7b734c9f81ec1187b7 vhdl-i2c/src/i2c/scl_generator.vhd -rw-r--r-- 2.4 KiB
da60d1f1 — Rutherther tests: add startstop condition generator testbench 1 year, 3 months ago
                                                                                
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;
Do not follow this link