~ruther/vhdl-i2c

ref: 74d8f5e0d61065c4b93b2d905314d7b0ad608004 vhdl-i2c/tb/i2c/tb_i2c_pkg.vhd -rw-r--r-- 4.3 KiB
74d8f5e0 — Rutherther tests: add pull up sda, scl behavior 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
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
  type std_logic_arr_t is array (natural range <>) of std_logic;
  function f_resolve_pull_up (
    constant signals : std_logic_arr_t)
    return std_logic;

  subtype pull_up_std_logic is f_resolve_pull_up std_logic;

  signal sda : pull_up_std_logic;
  signal scl : pull_up_std_logic;

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

  procedure scl_fall (
    signal scl_override : inout std_logic);

  procedure scl_rise (
    signal scl_override : inout std_logic);

  procedure scl_pulse (
    signal scl_override : inout std_logic);

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

  procedure sda_rise (
    signal sda_override : 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);

end package tb_i2c_pkg;

package body tb_i2c_pkg is
  function f_resolve_pull_up (
    constant signals : std_logic_arr_t)
    return std_logic is
    variable sig : std_logic := '1';
  begin
    for i in signals'range loop
      if signals(i) = '0' then
        sig := '0';
      end if;
    end loop;  -- i

    return sig;
  end function f_resolve_pull_up;

  procedure scl_fall (
    signal scl_override : inout std_logic) is
  begin  -- procedure scl_rise
    scl_override <= '1';
    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_override : inout std_logic) is
  begin  -- procedure scl_rise
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    scl_override <= '0';
    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_override : inout std_logic) is
  begin  -- procedure scl_rise
    scl_rise(scl_override);
    wait until falling_edge(clk);
    wait until falling_edge(clk);
    scl_fall(scl_override);
  end procedure scl_pulse;

  procedure sda_fall (
    signal sda_override : 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_override <= '1';
    wait until falling_edge(clk);
  end procedure sda_fall;

  procedure sda_rise (
    signal sda_override : 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_override <= '0';
    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;

end package body tb_i2c_pkg;
Do not follow this link