~ruther/vhdl-i2c

ref: 57bc4031f549c4c98b9f726cf3ca7681299aa521 vhdl-i2c/tb/i2c/tb_i2c_pkg.vhd -rw-r--r-- 5.3 KiB
57bc4031 — Rutherther feat: store address, rw in address generator or detector 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
library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
-- use vunit_lib.check_pkg.all;
context vunit_lib.vunit_context;

use work.tb_pkg.all;

package tb_i2c_pkg is
  signal sda : std_logic := 'H';
  signal scl : std_logic := 'H';

  signal tx_ready : std_logic;
  signal rx_valid : std_logic;
  signal rx_data : std_logic_vector(7 downto 0);

  procedure scl_fall (
    signal scl : inout std_logic);

  procedure scl_rise (
    signal scl : inout std_logic);

  procedure scl_pulse (
    signal scl : inout std_logic);

  procedure sda_fall (
    signal sda : inout std_logic;
    constant assert_no_condition : in std_logic := '1');

  procedure sda_rise (
    signal sda : inout std_logic;
    constant assert_no_condition : in std_logic := '1');

  procedure tx_write_data (
    constant data   : in    std_logic_vector(7 downto 0);
    signal tx_data : inout std_logic_vector(7 downto 0);
    signal tx_valid : inout std_logic);

  procedure rx_read_data (
    constant exp_data : in std_logic_vector(7 downto 0);
    signal rx_confirm_read : inout std_logic);

  procedure wait_for_start_condition (
    constant timeout : in time;
    signal scl       : in std_logic;
    signal sda       : in std_logic);

  procedure wait_for_stop_condition (
    constant timeout : in time;
    signal scl       : in std_logic;
    signal sda       : in std_logic);

  procedure wait_for_scl_rise (
    constant timeout : in time;
    signal scl       : in std_logic);

  procedure wait_for_scl_fall (
    constant timeout : in time;
    signal scl       : in std_logic);

end package tb_i2c_pkg;

package body tb_i2c_pkg is
  procedure scl_fall (
    signal scl : inout std_logic) is
  begin  -- procedure scl_rise
    scl <= '0';
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
  end procedure scl_fall;

  procedure scl_rise (
    signal scl : inout std_logic) is
  begin  -- procedure scl_rise
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    scl <= 'Z';
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
  end procedure scl_rise;

  procedure scl_pulse (
    signal scl : inout std_logic) is
  begin  -- procedure scl_rise
    scl_rise(scl);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    scl_fall(scl);
  end procedure scl_pulse;

  procedure sda_fall (
    signal sda : inout std_logic;
    constant assert_no_condition : in std_logic := '1') is
  begin  -- procedure scl_rise
    if assert_no_condition = '1' and sda /= '0' then
      check_equal(scl, '0', "Cannot change sda as that would trigger start condition.", failure);
    end if;

    sda <= '0';
    wait until falling_edge(clk);
  end procedure sda_fall;

  procedure sda_rise (
    signal sda : inout std_logic;
    constant assert_no_condition : in std_logic := '1') is
  begin  -- procedure scl_rise
    if assert_no_condition = '1' and sda /= '0' then
      check_equal(scl, '0', "Cannot change sda as that would trigger stop condition.", failure);
    end if;

    sda <= 'Z';
    wait until falling_edge(clk);
  end procedure sda_rise;

  procedure tx_write_data (
    constant data   : in    std_logic_vector(7 downto 0);
    signal tx_data : inout std_logic_vector(7 downto 0);
    signal tx_valid : inout std_logic
    ) is
  begin
    check_equal(tx_ready, '1', "not ready when trying to write data!");
    tx_data <= data;
    tx_valid <= '1';
    wait until falling_edge(clk);
    tx_valid <= '0';
  end procedure tx_write_data;

  procedure rx_read_data (
    constant exp_data : in std_logic_vector(7 downto 0);
    signal rx_confirm_read : inout std_logic
    ) is
  begin
    check_equal(rx_valid, '1', "not valid when trying to read data!");
    check_equal(rx_data, exp_data, "Read rx data not equal to expected");
    rx_confirm_read <= '1';
    wait until falling_edge(clk);
    rx_confirm_read <= '0';
  end procedure rx_read_data;

  procedure wait_for_start_condition (
    constant timeout : in time;
    signal scl       : in std_logic;
    signal sda       : in std_logic) is
  begin
    wait until falling_edge(sda) and scl = 'H' for timeout;
    check(sda = '0' and scl = 'H', "Did not get start condition in time.");
  end procedure wait_for_start_condition;

  procedure wait_for_stop_condition (
    constant timeout : in time;
    signal scl       : in std_logic;
    signal sda       : in std_logic) is
  begin
    wait until rising_edge(sda) and scl = 'H' for timeout;
    check(sda = 'H' and scl = 'H', "Did not get stop condition in time.");
  end procedure wait_for_stop_condition;

  procedure wait_for_scl_rise (
    constant timeout : in time;
    signal scl       : in std_logic) is
  begin
    wait until rising_edge(scl) for timeout;
    check_equal(scl, 'H', "Did not get rising scl in time.");
    wait until falling_edge(clk);
  end procedure wait_for_scl_rise;


  procedure wait_for_scl_fall (
    constant timeout : in time;
    signal scl       : in std_logic) is
  begin
    wait until falling_edge(scl) for timeout;
    check_equal(scl, '0', "Did not get falling scl in time.");
    wait until falling_edge(clk);
  end procedure wait_for_scl_fall;


end package body tb_i2c_pkg;
Do not follow this link