-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiic_slave_example.vhd
155 lines (140 loc) · 3.27 KB
/
iic_slave_example.vhd
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
-- iic_slave_example - example design for iic_slave
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.iic_slave_phy_pkg.all;
use work.iic_slave_mm_8x8_pkg.all;
entity iic_slave_example is
port(
clk : in std_logic;
rst : in std_logic;
-- IO pins
scl : inout std_logic;
sda : inout std_logic;
led : out std_logic
);
end entity iic_slave_example;
architecture test of iic_slave_example is
signal bus_addr : std_logic_vector(7 downto 0);
signal bus_write : std_logic;
signal bus_read : std_logic;
signal bus_waitreq : std_logic;
signal bus_wdata : std_logic_vector(7 downto 0);
signal bus_rdata : std_logic_vector(7 downto 0);
signal bus_rvalid : std_logic;
signal reg0 : std_logic_vector(7 downto 0);
signal reg1 : std_logic_vector(7 downto 0);
signal reg2 : std_logic_vector(7 downto 0);
signal reg3 : std_logic_vector(7 downto 0);
signal acc_ctr : integer range 0 to 63;
signal rst_ctr : unsigned(3 downto 0) := x"0";
signal rst_i : std_logic;
signal pwm_ctr : unsigned(7 downto 0);
signal pwm_out : std_logic;
signal blink_ctr : unsigned(19 downto 0);
signal blink_on : std_logic;
begin
reg: iic_slave_mm_8x8 generic map (
ADDRESS => x"c2",
FILTER_LEN => 3
) port map (
clk => clk,
rst => rst_i,
scl => scl,
sda => sda,
bus_addr => bus_addr,
bus_write => bus_write,
bus_read => bus_read,
bus_waitreq => bus_waitreq,
bus_wdata => bus_wdata,
bus_rdata => bus_rdata,
bus_rvalid => bus_rvalid );
process(clk)
begin
if rising_edge(clk) then
if rst_ctr < 10 then
rst_i <= '1';
rst_ctr <= rst_ctr + 1;
else
rst_i <= '0';
end if;
-- example register bank with artificially long response times
bus_waitreq <= '1';
if bus_write = '1' then
case bus_addr is
when x"00" =>
reg0 <= bus_wdata;
when x"01" =>
reg1 <= bus_wdata;
when x"02" =>
reg2 <= bus_wdata;
when x"03" =>
reg3 <= bus_wdata;
when others =>
null;
end case;
if acc_ctr = 25 then
bus_waitreq <= '0';
acc_ctr <= 0;
else
acc_ctr <= acc_ctr + 1;
end if;
end if;
bus_rvalid <= '0';
if bus_read = '1' then
case bus_addr is
when x"00" =>
bus_rdata <= reg0;
when x"01" =>
bus_rdata <= reg1;
when x"02" =>
bus_rdata <= reg2;
when x"03" =>
bus_rdata <= reg3;
when others =>
bus_rdata <= x"00";
null;
end case;
if acc_ctr = 30 then
bus_waitreq <= '0';
bus_rvalid <= '1';
acc_ctr <= 0;
else
acc_ctr <= acc_ctr + 1;
end if;
end if;
-- super fancy led binking control
pwm_ctr <= pwm_ctr + 1;
if pwm_ctr < unsigned(reg1) then
pwm_out <= '1';
else
pwm_out <= '0';
end if;
if pwm_ctr = x"00" then
blink_ctr <= blink_ctr + 1;
end if;
blink_on <= blink_ctr(14) and blink_ctr(13) and blink_ctr(12);
if reg0(0) = '1' then
led <= not '0'; -- disabled
else
if reg0(1) = '1' then --blink on
led <= not (blink_on and pwm_out);
else
led <= not pwm_out;
end if;
end if;
if rst_i = '1' then
acc_ctr <= 0;
bus_waitreq <= '1';
bus_rvalid <= '0';
reg0 <= x"02";
reg1 <= x"ff";
reg2 <= x"00";
reg3 <= x"00";
pwm_ctr <= x"00";
blink_ctr <= x"00000";
end if;
end if;
end process;
end;