~ruther/vhdl-i2c

ref: da60d1f13356b798f9fc9a7b734c9f81ec1187b7 vhdl-i2c/tb/i2c/scl_generator_tb.vhd -rw-r--r-- 5.1 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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
library ieee;
use ieee.std_logic_1164.all;

library i2c;

library vunit_lib;
context vunit_lib.vunit_context;

entity scl_generator_tb is

  generic (
    runner_cfg : string);

end entity scl_generator_tb;

architecture tb of scl_generator_tb is
  signal clk : std_logic := '0';
  constant CLK_PERIOD : time := 10 ns;

  signal rst_n : std_logic := '0';

  signal scl : std_logic := 'H';
  signal slave_scl : std_logic;
  signal scl_rising : std_logic := '0';
  signal scl_falling : std_logic := '0';

  signal scl_enable : std_logic := '0';
  signal gen_continuous, gen_rising, gen_falling : std_logic := '0';
  signal cannot_comply : std_logic;

  signal stable_cannot_comply : std_logic := '1';

  constant DELAY : natural := 5;
  signal one : std_logic := '1';
  signal zero : std_logic := '0';
begin  -- architecture tb

  clk <= not clk after CLK_PERIOD/2;
  rst_n <= '1' after 2*CLK_PERIOD;

  scl <= 'H';
  scl <= '0' when scl_enable = '1' else 'Z';

  slave_scl <= '1' when scl = 'H' else 'Z';
  slave_scl <= scl;

  cannot_comply_stable: check_stable(clk, stable_cannot_comply, one, zero, cannot_comply);

  uut: entity i2c.scl_generator
    generic map (
      MIN_STABLE_CYCLES => DELAY)
    port map (
      clk_i            => clk,
      rst_in           => rst_n,
      scl_i            => slave_scl,
      scl_rising_i     => scl_rising,
      scl_falling_i    => scl_falling,
      gen_continuous_i => gen_continuous,
      gen_rising_i     => gen_rising,
      gen_falling_i    => gen_falling,
      scl_enable_o     => scl_enable,
      cannot_comply_o  => cannot_comply);

  main: process is
    procedure wait_delay(constant delay : in integer) is
    begin  -- procedure wait_delay
      for i in 0 to delay loop
        wait until falling_edge(clk);
      end loop;  -- i
      wait until falling_edge(clk);
    end procedure wait_delay;

    procedure req_clear is
    begin  -- procedure req_rising
      gen_falling <= '0';
      gen_continuous <= '0';
      gen_rising <= '0';
    end procedure req_clear;

    procedure req_rising is
    begin  -- procedure req_rising
      req_clear;
      gen_rising <= '1';
    end procedure req_rising;

    procedure req_falling is
    begin  -- procedure req_falling
      req_clear;
      gen_falling <= '1';
    end procedure req_falling;

    procedure req_continuous is
    begin  -- procedure req_
      req_clear;
      gen_continuous <= '1';
    end procedure req_continuous;
  begin  -- process main
    wait until rst_n = '1';
    wait until falling_edge(clk);

    check_equal(scl, 'H', "begin SCL not high");

    test_runner_setup(runner, runner_cfg);

    while test_suite loop
        if run("continuous") then
        req_continuous;

        for i in 0 to 10 loop
            wait_delay(DELAY);
            check_equal(scl, '0');
            wait_delay(DELAY);
            check_equal(scl, 'H');
        end loop;  -- i
        elsif run("falling") then
          req_falling;
          wait_delay(DELAY);

          check_equal(scl, '0');
          req_clear;

          for i in 0 to 10 loop
            check_equal(scl, '0');
          end loop;  -- i
        elsif run("falling_rising") then
          req_falling;
          wait_delay(DELAY);

          check_equal(scl, '0');
          req_rising;
          wait_delay(DELAY);
          req_clear;

          for i in 0 to 10 loop
            check_equal(scl, 'H');
          end loop;  -- i
        elsif run("continuous_rising") then
          req_continuous;
          for i in 0 to 5 loop
            wait_delay(DELAY - 1);
            report "Hi" & std_logic'image(scl);
          end loop;  -- i

          check_equal(scl, '0');
          req_rising;
          wait_delay(DELAY);
          check_equal(scl, 'H');
        elsif run("continuous_falling") then
          req_continuous;
          for i in 0 to 6 loop
            wait_delay(DELAY - 1);
          end loop;  -- i

          check_equal(scl, 'H');
          req_falling;
          wait_delay(DELAY);
          check_equal(scl, '0');
        elsif run("rising_scl_low") then
          scl <= '0'; -- pull down
          req_rising;

          stable_cannot_comply <= '0';
          wait_delay(1);
          check_equal(cannot_comply, '1');
        elsif run("falling_rising_scl_low") then
          req_falling;
          wait_delay(DELAY);
          scl <= '0'; -- pull down
          req_rising;

          stable_cannot_comply <= '0';
          wait_delay(DELAY);
          check_equal(cannot_comply, '1');
          check_equal(scl_enable, '0');
          wait_delay(DELAY);
          check_equal(scl_enable, '0');
        end if;
    end loop;

    test_runner_cleanup(runner);
  end process main;

  set_scl_rising: process is
  begin  -- process scl_rising
    wait until rising_edge(scl);
    scl_rising <= '1';
    wait until rising_edge(clk);
    wait until falling_edge(clk);
    scl_rising <= '0';
  end process set_scl_rising;

  set_scl_falling: process is
  begin  -- process scl_rising
    wait until falling_edge(scl);
    scl_falling <= '1';
    wait until rising_edge(clk);
    wait until falling_edge(clk);
    scl_falling <= '0';
  end process set_scl_falling;

end architecture tb;
Do not follow this link