~ruther/vhdl-i2c

ref: 6d023a1fedb92085f8d8d06c5be1825bad586d1d vhdl-i2c/tb/i2c/model/i2c_slave_pkg.vhd -rw-r--r-- 4.1 KiB
6d023a1f — Rutherther tests: add packages for communication with i2c bus model 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
--- read(address, exp_data, timeout)
---   wait start
---   wait address
---   ack (if matching)
---   read data, check it
---   check ack on every byte
---   wait stop?
--- write(address, data, timeout)
---   wait start
---   wait address
---   ack (if matching)
---   write data, check ack
---   wait stop?
--- read_write(address, exp_data, data, timeout)
---   wait start
---   wait address
---   ack (if matcihng)
---   start matching bytes
---     ack every byte
---   wait start
---   wait address
---   ack (if matching)
---   write data, check ack

library ieee;
use ieee.std_logic_1164.all;

library vunit_lib;
context vunit_lib.vunit_context;
context vunit_lib.com_context;

use work.i2c_bus_pkg;

package i2c_slave_pkg is

  procedure write (
    constant address  : in std_logic_vector(6 downto 0);
    constant exp_data : in std_logic_vector;
    constant timeout  : in time;
    constant actor    : in actor_t);

  procedure read (
    constant address  : in std_logic_vector(6 downto 0);
    constant data     : in std_logic_vector;
    constant timeout  : in time;
    constant actor : in actor_t);

  procedure write_read (
    constant address  : in std_logic_vector(6 downto 0);
    constant exp_data : in std_logic_vector;
    constant data     : in std_logic_vector;
    constant timeout  : in time;
    constant actor : in actor_t);

end package i2c_slave_pkg;

package body i2c_slave_pkg is

  procedure write (
    constant address  : in std_logic_vector(6 downto 0);
    constant exp_data : in std_logic_vector;
    constant timeout  : in time;
    constant actor    : in actor_t) is
  begin
    if exp_data'length mod 8 /= 0 then
      failure("The number of bits to be written to the slave have to be divisible by 8.");
    end if;

    i2c_bus_pkg.wait_for_start_cond(timeout, actor);
    i2c_bus_pkg.check_data(address & '0', timeout, actor);

    for i in 0 to exp_data'length/8 - 1 loop
      i2c_bus_pkg.check_data(exp_data(exp_data'left - i*8 downto exp_data'left - 7 - i*8), timeout, actor);
      i2c_bus_pkg.send_ack(timeout, actor);
    end loop;  -- i

    i2c_bus_pkg.wait_for_stop_cond(timeout, actor);
  end procedure write;

  procedure read (
    constant address  : in std_logic_vector(6 downto 0);
    constant data     : in std_logic_vector;
    constant timeout  : in time;
    constant actor    : in actor_t) is
  begin
    if data'length mod 8 /= 0 then
      failure("The number of bits to be read from the slave have to be divisible by 8.");
    end if;

    i2c_bus_pkg.wait_for_start_cond(timeout, actor);
    i2c_bus_pkg.check_data(address & '1', timeout, actor);

    for i in 0 to data'length/8 - 1 loop
      i2c_bus_pkg.send_data(data(data'left - i*8 downto data'left - 7 - i*8), timeout, actor);
      i2c_bus_pkg.check_ack(timeout, actor);
    end loop;  -- i

    i2c_bus_pkg.wait_for_stop_cond(timeout, actor);
  end procedure read;

  procedure write_read (
    constant address  : in std_logic_vector(6 downto 0);
    constant data     : in std_logic_vector;
    constant exp_data : in std_logic_vector;
    constant timeout  : in time;
    constant actor : in actor_t) is
  begin
    if exp_data'length mod 8 /= 0 then
      failure("The number of bits to be written to the slave have to be divisible by 8.");
    end if;
    if data'length mod 8 /= 0 then
      failure("The number of bits to be read from the slave have to be divisible by 8.");
    end if;

    i2c_bus_pkg.wait_for_start_cond(timeout, actor);
    i2c_bus_pkg.send_data_and_clock(address & '0', timeout, actor);

    for i in 0 to exp_data'length/8 - 1 loop
      i2c_bus_pkg.check_data(exp_data(exp_data'left - i*8 downto exp_data'left - 7 - i*8), timeout, actor);
      i2c_bus_pkg.send_ack(timeout, actor);
    end loop;  -- i

    i2c_bus_pkg.wait_for_start_cond(timeout, actor);
    i2c_bus_pkg.send_data_and_clock(address & '1', timeout, actor);

    for i in 0 to data'length/8 - 1 loop
      i2c_bus_pkg.send_data(data(data'left - i*8 downto data'left - 7 - i*8), timeout, actor);
      i2c_bus_pkg.check_ack(timeout, actor);
    end loop;  -- i

    i2c_bus_pkg.wait_for_stop_cond(timeout, actor);
  end procedure write_read;


end package body i2c_slave_pkg;
Do not follow this link