OpenCores
URL https://opencores.org/ocsvn/iicmb/iicmb/trunk

Subversion Repositories iicmb

[/] [iicmb/] [trunk/] [src/] [sequencer.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sshuv2
 
2
--==============================================================================
3
--                                                                             |
4
--    Project: IIC Multiple Bus Controller (IICMB)                             |
5
--                                                                             |
6
--    Module:  Command sequencer for 'iicmb_m'.                                |
7
--    Version:                                                                 |
8
--             1.0,   April 29, 2016                                           |
9
--                                                                             |
10
--    Author:  Sergey Shuvalkin, (sshuv2@opencores.org)                        |
11
--                                                                             |
12
--==============================================================================
13
--==============================================================================
14
-- Copyright (c) 2016, Sergey Shuvalkin                                        |
15
-- All rights reserved.                                                        |
16
--                                                                             |
17
-- Redistribution and use in source and binary forms, with or without          |
18
-- modification, are permitted provided that the following conditions are met: |
19
--                                                                             |
20
-- 1. Redistributions of source code must retain the above copyright notice,   |
21
--    this list of conditions and the following disclaimer.                    |
22
-- 2. Redistributions in binary form must reproduce the above copyright        |
23
--    notice, this list of conditions and the following disclaimer in the      |
24
--    documentation and/or other materials provided with the distribution.     |
25
--                                                                             |
26
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
27
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE   |
28
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  |
29
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE    |
30
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR         |
31
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF        |
32
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    |
33
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN     |
34
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)     |
35
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  |
36
-- POSSIBILITY OF SUCH DAMAGE.                                                 |
37
--==============================================================================
38
 
39
 
40
library ieee;
41
use ieee.std_logic_1164.all;
42
 
43
use work.iicmb_pkg.all;
44
 
45
 
46
--==============================================================================
47
entity sequencer is
48
  generic
49
  (
50
    g_cmd       :       seq_cmd_type_array := c_empty_array   -- Sequence of commands (supported: WAIT, SET_BUS and WRITE_BYTE)
51
  );
52
  port
53
  (
54
    ------------------------------------
55
    clk         : in    std_logic;                            -- Clock input
56
    s_rst       : in    std_logic;                            -- Synchronous reset (active high)
57
    ------------------------------------
58
    ------------------------------------
59
    cs_start    : in    std_logic;                            -- Start executing command sequence
60
    cs_busy     :   out std_logic;                            -- Command sequence is being executed
61
    cs_status   :   out std_logic_vector(2 downto 0);         -- Execution status
62
    ------------------------------------
63
    ------------------------------------
64
    -- Status:
65
    busy        : in    std_logic;                            -- Bus busy status
66
    captured    : in    std_logic;                            -- Bus captured status
67
    bus_id      : in    std_logic_vector(3 downto 0);         -- ID of selected I2C bus
68
    bit_state   : in    std_logic_vector(3 downto 0);         -- State of bit level FSM
69
    byte_state  : in    std_logic_vector(3 downto 0);         -- State of byte level FSM
70
    ------------------------------------
71
    ------------------------------------
72
    -- 'Generic interface' signals:
73
    mcmd_wr     :   out std_logic;                            -- Byte command write (active high)
74
    mcmd_id     :   out std_logic_vector(2 downto 0);         -- Byte command ID
75
    mcmd_data   :   out std_logic_vector(7 downto 0);         -- Command data
76
    --
77
    mrsp_wr     : in    std_logic;                            -- Byte response write (active high)
78
    mrsp_id     : in    std_logic_vector(2 downto 0);         -- Byte response ID
79
    mrsp_data   : in    std_logic_vector(7 downto 0)          -- Response data
80
    ------------------------------------
81
  );
82
end entity sequencer;
83
--==============================================================================
84
 
85
--==============================================================================
86
architecture rtl of sequencer is
87
 
88
  type cmd_type_array is array (natural range <>) of std_logic_vector(10 downto 0);
89
 
90
  ------------------------------------------------------------------------------
91
  function get_cmd_seq_length(a : seq_cmd_type_array) return natural is
92
    variable v_ret : natural := 0;
93
  begin
94
    for i in a'range loop
95
      case a(i).id is
96
        when seq_wait       => v_ret := v_ret + 1;
97
        when seq_set_bus    => v_ret := v_ret + 1;
98
        when seq_write_byte => v_ret := v_ret + 5;
99
      end case;
100
    end loop;
101
    return v_ret;
102
  end function get_cmd_seq_length;
103
  ------------------------------------------------------------------------------
104
 
105
  ------------------------------------------------------------------------------
106
  function get_cmd_seq(a : seq_cmd_type_array) return cmd_type_array is
107
    variable v_ret : cmd_type_array(0 to (get_cmd_seq_length(a) - 1));
108
    variable j : integer;
109
  begin
110
    j := 0;
111
    for i in a'range loop
112
      case a(i).id is
113
        when seq_wait       =>
114
          v_ret(j) := mcmd_wait & a(i).data;
115
          j := j + 1;
116
        when seq_set_bus    =>
117
          v_ret(j) := mcmd_set_bus & a(i).data;
118
          j := j + 1;
119
        when seq_write_byte =>
120
          v_ret(j + 0) := mcmd_start & x"00";
121
          v_ret(j + 1) := mcmd_write & a(i).saddr & "0";
122
          v_ret(j + 2) := mcmd_write & a(i).daddr;
123
          v_ret(j + 3) := mcmd_write & a(i).data;
124
          v_ret(j + 4) := mcmd_stop  & x"00";
125
          j := j + 5;
126
      end case;
127
    end loop;
128
    return v_ret;
129
  end function get_cmd_seq;
130
  ------------------------------------------------------------------------------
131
 
132
  ------------------------------------------------------------------------------
133
  -- Sequence of commands to execute:
134
  constant cmd_seq   : cmd_type_array := get_cmd_seq(g_cmd);
135
  ------------------------------------------------------------------------------
136
 
137
  type state_type is (s_idle, s_active);
138
  signal   state     : state_type                        := s_idle;
139
  signal   cmd_cnt   : integer range 0 to cmd_seq'length := 0;
140
 
141
begin
142
 
143
  ------------------------------------------------------------------------------
144
  state_proc:
145
  process(clk)
146
  begin
147
    if rising_edge(clk) then
148
      if (s_rst = '1') then
149
        state     <= s_idle;
150
        cmd_cnt   <= 0;
151
        cs_busy   <= '0';
152
        cs_status <= mrsp_done;
153
        mcmd_wr   <= '0';
154
        mcmd_id   <= "000";
155
        mcmd_data <= "00000000";
156
      else
157
        -- Defaults:
158
        mcmd_wr   <= '0';
159
 
160
        -- FSM:
161
        case state is
162
          -------------- 's_idle' state ------------------------
163
          when s_idle   =>
164
            cs_busy   <= '0';
165
            if (cs_start = '1') then
166
              if (cmd_cnt = cmd_seq'length) then
167
                cs_status <= mrsp_done;
168
                cmd_cnt   <= 0;
169
              else
170
                state     <= s_active;
171
                cmd_cnt   <= cmd_cnt + 1;
172
                cs_busy   <= '1';
173
                mcmd_wr   <= '1';
174
                mcmd_id   <= cmd_seq(cmd_cnt)(10 downto 8);
175
                mcmd_data <= cmd_seq(cmd_cnt)( 7 downto 0);
176
              end if;
177
            end if;
178
          -------------- 's_idle' state ------------------------
179
 
180
          -------------- 's_active' state ----------------------
181
          when s_active =>
182
            cs_busy   <= '1';
183
            if (mrsp_wr = '1') then
184
              case mrsp_id is
185
                when mrsp_nak | mrsp_arb_lost | mrsp_error =>
186
                  state     <= s_idle;
187
                  cmd_cnt   <= 0;
188
                  cs_busy   <= '0';
189
                  cs_status <= mrsp_id;
190
                when others        =>
191
                  if (cmd_cnt = cmd_seq'length) then
192
                    state     <= s_idle;
193
                    cmd_cnt   <= 0;
194
                    cs_busy   <= '0';
195
                    cs_status <= mrsp_done;
196
                  else
197
                    cmd_cnt   <= cmd_cnt + 1;
198
                    mcmd_wr   <= '1';
199
                    mcmd_id   <= cmd_seq(cmd_cnt)(10 downto 8);
200
                    mcmd_data <= cmd_seq(cmd_cnt)( 7 downto 0);
201
                  end if;
202
              end case;
203
            end if;
204
          -------------- 's_active' state ----------------------
205
        end case;
206
      end if;
207
    end if;
208
  end process state_proc;
209
  ------------------------------------------------------------------------------
210
 
211
end architecture rtl;
212
--==============================================================================
213
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.