Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top...
[debian/gnuradio] / usrp2 / fpga / opencores / i2c / rtl / vhdl / i2c_master_byte_ctrl.vhd
1 ---------------------------------------------------------------------
2 ----                                                             ----
3 ----  WISHBONE revB2 compl. I2C Master Core; byte-controller     ----
4 ----                                                             ----
5 ----                                                             ----
6 ----  Author: Richard Herveille                                  ----
7 ----          richard@asics.ws                                   ----
8 ----          www.asics.ws                                       ----
9 ----                                                             ----
10 ----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
11 ----                                                             ----
12 ---------------------------------------------------------------------
13 ----                                                             ----
14 ---- Copyright (C) 2000 Richard Herveille                        ----
15 ----                    richard@asics.ws                         ----
16 ----                                                             ----
17 ---- This source file may be used and distributed without        ----
18 ---- restriction provided that this copyright statement is not   ----
19 ---- removed from the file and that any derivative work contains ----
20 ---- the original copyright notice and the associated disclaimer.----
21 ----                                                             ----
22 ----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
23 ---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
24 ---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
25 ---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
26 ---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
27 ---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
28 ---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
29 ---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
30 ---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
31 ---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
32 ---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
33 ---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
34 ---- POSSIBILITY OF SUCH DAMAGE.                                 ----
35 ----                                                             ----
36 ---------------------------------------------------------------------
37
38 --  CVS Log
39 --
40 --  $Id: i2c_master_byte_ctrl.vhd,v 1.5 2004/02/18 11:41:48 rherveille Exp $
41 --
42 --  $Date: 2004/02/18 11:41:48 $
43 --  $Revision: 1.5 $
44 --  $Author: rherveille $
45 --  $Locker:  $
46 --  $State: Exp $
47 --
48 -- Change History:
49 --               $Log: i2c_master_byte_ctrl.vhd,v $
50 --               Revision 1.5  2004/02/18 11:41:48  rherveille
51 --               Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
52 --
53 --               Revision 1.4  2003/08/09 07:01:13  rherveille
54 --               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
55 --               Fixed a potential bug in the byte controller's host-acknowledge generation.
56 --
57 --               Revision 1.3  2002/12/26 16:05:47  rherveille
58 --               Core is now a Multimaster I2C controller.
59 --
60 --               Revision 1.2  2002/11/30 22:24:37  rherveille
61 --               Cleaned up code
62 --
63 --               Revision 1.1  2001/11/05 12:02:33  rherveille
64 --               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
65 --               Code updated, is now up-to-date to doc. rev.0.4.
66 --               Added headers.
67 --
68
69
70
71
72 --
73 ------------------------------------------
74 -- Byte controller section
75 ------------------------------------------
76 --
77 library ieee;
78 use ieee.std_logic_1164.all;
79 use ieee.std_logic_arith.all;
80
81 entity i2c_master_byte_ctrl is
82         port (
83                 clk    : in std_logic;
84                 rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
85                 nReset : in std_logic;  -- asynchornous active low reset (FPGA compatible)
86                 ena    : in std_logic; -- core enable signal
87
88                 clk_cnt : in unsigned(15 downto 0);     -- 4x SCL
89
90                 -- input signals
91                 start,
92                 stop,
93                 read,
94                 write,
95                 ack_in : std_logic;
96                 din    : in std_logic_vector(7 downto 0);
97
98                 -- output signals
99                 cmd_ack  : out std_logic; -- command done
100                 ack_out  : out std_logic;
101                 i2c_busy : out std_logic; -- arbitration lost
102                 i2c_al   : out std_logic; -- i2c bus busy
103                 dout     : out std_logic_vector(7 downto 0);
104
105                 -- i2c lines
106                 scl_i   : in std_logic;  -- i2c clock line input
107                 scl_o   : out std_logic; -- i2c clock line output
108                 scl_oen : out std_logic; -- i2c clock line output enable, active low
109                 sda_i   : in std_logic;  -- i2c data line input
110                 sda_o   : out std_logic; -- i2c data line output
111                 sda_oen : out std_logic  -- i2c data line output enable, active low
112         );
113 end entity i2c_master_byte_ctrl;
114
115 architecture structural of i2c_master_byte_ctrl is
116         component i2c_master_bit_ctrl is
117         port (
118                 clk    : in std_logic;
119                 rst    : in std_logic;
120                 nReset : in std_logic;
121                 ena    : in std_logic;                          -- core enable signal
122
123                 clk_cnt : in unsigned(15 downto 0);             -- clock prescale value
124
125                 cmd     : in std_logic_vector(3 downto 0);
126                 cmd_ack : out std_logic; -- command done
127                 busy    : out std_logic; -- i2c bus busy
128                 al      : out std_logic; -- arbitration lost
129
130                 din  : in std_logic;
131                 dout : out std_logic;
132
133                 -- i2c lines
134                 scl_i   : in std_logic;  -- i2c clock line input
135                 scl_o   : out std_logic; -- i2c clock line output
136                 scl_oen : out std_logic; -- i2c clock line output enable, active low
137                 sda_i   : in std_logic;  -- i2c data line input
138                 sda_o   : out std_logic; -- i2c data line output
139                 sda_oen : out std_logic  -- i2c data line output enable, active low
140         );
141         end component i2c_master_bit_ctrl;
142
143         -- commands for bit_controller block
144         constant I2C_CMD_NOP    : std_logic_vector(3 downto 0) := "0000";
145         constant I2C_CMD_START  : std_logic_vector(3 downto 0) := "0001";
146         constant I2C_CMD_STOP    : std_logic_vector(3 downto 0) := "0010";
147         constant I2C_CMD_READ    : std_logic_vector(3 downto 0) := "0100";
148         constant I2C_CMD_WRITE  : std_logic_vector(3 downto 0) := "1000";
149
150         -- signals for bit_controller
151         signal core_cmd : std_logic_vector(3 downto 0);
152         signal core_ack, core_txd, core_rxd : std_logic;
153         signal al : std_logic;
154
155         -- signals for shift register
156         signal sr : std_logic_vector(7 downto 0); -- 8bit shift register
157         signal shift, ld : std_logic;
158
159         -- signals for state machine
160         signal go, host_ack : std_logic;
161         signal dcnt : unsigned(2 downto 0); -- data counter
162         signal cnt_done : std_logic;
163
164 begin
165         -- hookup bit_controller
166         bit_ctrl: i2c_master_bit_ctrl port map(
167                 clk     => clk,
168                 rst     => rst,
169                 nReset  => nReset,
170                 ena     => ena,
171                 clk_cnt => clk_cnt,
172                 cmd     => core_cmd,
173                 cmd_ack => core_ack,
174                 busy    => i2c_busy,
175                 al      => al,
176                 din     => core_txd,
177                 dout    => core_rxd,
178                 scl_i   => scl_i,
179                 scl_o   => scl_o,
180                 scl_oen => scl_oen,
181                 sda_i   => sda_i,
182                 sda_o   => sda_o,
183                 sda_oen => sda_oen
184         );
185         i2c_al <= al;
186
187         -- generate host-command-acknowledge
188         cmd_ack <= host_ack;
189
190         -- generate go-signal
191         go <= (read or write or stop) and not host_ack;
192
193         -- assign Dout output to shift-register
194         dout <= sr;
195
196         -- generate shift register
197         shift_register: process(clk, nReset)
198         begin
199             if (nReset = '0') then
200               sr <= (others => '0');
201             elsif (clk'event and clk = '1') then
202               if (rst = '1') then
203                 sr <= (others => '0');
204               elsif (ld = '1') then
205                 sr <= din;
206               elsif (shift = '1') then
207                 sr <= (sr(6 downto 0) & core_rxd);
208               end if;
209             end if;
210         end process shift_register;
211
212         -- generate data-counter
213         data_cnt: process(clk, nReset)
214         begin
215             if (nReset = '0') then
216               dcnt <= (others => '0');
217             elsif (clk'event and clk = '1') then
218               if (rst = '1') then
219                 dcnt <= (others => '0');
220               elsif (ld = '1') then
221                 dcnt <= (others => '1');  -- load counter with 7
222               elsif (shift = '1') then
223                 dcnt <= dcnt -1;
224               end if;
225             end if;
226         end process data_cnt;
227
228         cnt_done <= '1' when (dcnt = 0) else '0';
229
230         --
231         -- state machine
232         --
233         statemachine : block
234             type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);
235             signal c_state : states;
236         begin
237             --
238             -- command interpreter, translate complex commands into simpler I2C commands
239             --
240             nxt_state_decoder: process(clk, nReset)
241             begin
242                 if (nReset = '0') then
243                   core_cmd <= I2C_CMD_NOP;
244                   core_txd <= '0';
245                   shift    <= '0';
246                   ld       <= '0';
247                   host_ack <= '0';
248                   c_state  <= st_idle;
249                   ack_out  <= '0';
250                 elsif (clk'event and clk = '1') then
251                   if (rst = '1' or al = '1') then
252                     core_cmd <= I2C_CMD_NOP;
253                     core_txd <= '0';
254                     shift    <= '0';
255                     ld       <= '0';
256                     host_ack <= '0';
257                     c_state  <= st_idle;
258                     ack_out  <= '0';
259                   else
260                     -- initialy reset all signal
261                     core_txd <= sr(7);
262                     shift    <= '0';
263                     ld       <= '0';
264                     host_ack <= '0';
265
266                     case c_state is
267                       when st_idle =>
268                          if (go = '1') then
269                            if (start = '1') then
270                              c_state  <= st_start;
271                              core_cmd <= I2C_CMD_START;
272                            elsif (read = '1') then
273                              c_state  <= st_read;
274                              core_cmd <= I2C_CMD_READ;
275                            elsif (write = '1') then
276                              c_state  <= st_write;
277                              core_cmd <= I2C_CMD_WRITE;
278                            else -- stop
279                              c_state  <= st_stop;
280                              core_cmd <= I2C_CMD_STOP;
281                            end if;
282
283                            ld <= '1';
284                          end if;
285
286                       when st_start =>
287                          if (core_ack = '1') then
288                            if (read = '1') then
289                              c_state  <= st_read;
290                              core_cmd <= I2C_CMD_READ;
291                            else
292                              c_state  <= st_write;
293                              core_cmd <= I2C_CMD_WRITE;
294                            end if;
295
296                            ld <= '1';
297                          end if;
298
299                       when st_write =>
300                          if (core_ack = '1') then
301                            if (cnt_done = '1') then
302                              c_state  <= st_ack;
303                              core_cmd <= I2C_CMD_READ;
304                            else
305                              c_state  <= st_write;       -- stay in same state
306                              core_cmd <= I2C_CMD_WRITE;  -- write next bit
307                              shift    <= '1';
308                            end if;
309                          end if;
310
311                       when st_read =>
312                          if (core_ack = '1') then
313                            if (cnt_done = '1') then
314                              c_state  <= st_ack;
315                              core_cmd <= I2C_CMD_WRITE;
316                            else
317                              c_state  <= st_read;      -- stay in same state
318                              core_cmd <= I2C_CMD_READ; -- read next bit
319                            end if;
320
321                            shift    <= '1';
322                            core_txd <= ack_in;
323                          end if;
324
325                       when st_ack =>
326                          if (core_ack = '1') then
327                            -- check for stop; Should a STOP command be generated ?
328                            if (stop = '1') then
329                              c_state  <= st_stop;
330                              core_cmd <= I2C_CMD_STOP;
331                            else
332                              c_state  <= st_idle;
333                              core_cmd <= I2C_CMD_NOP;
334
335                              -- generate command acknowledge signal
336                              host_ack <= '1';
337                            end if;
338
339                            -- assign ack_out output to core_rxd (contains last received bit)
340                            ack_out  <= core_rxd;
341
342                            core_txd <= '1';
343                          else
344                            core_txd <= ack_in;
345                          end if;
346
347                       when st_stop =>
348                          if (core_ack = '1') then
349                            c_state  <= st_idle;
350                            core_cmd <= I2C_CMD_NOP;
351
352                            -- generate command acknowledge signal
353                            host_ack <= '1';
354                          end if;
355
356                       when others => -- illegal states
357                          c_state  <= st_idle;
358                          core_cmd <= I2C_CMD_NOP;
359                          report ("Byte controller entered illegal state.");
360
361                     end case;
362
363                   end if;
364                 end if;
365             end process nxt_state_decoder;
366
367         end block statemachine;
368
369 end architecture structural;
370