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

Subversion Repositories gecko4

[/] [gecko4/] [trunk/] [GECKO4com/] [spartan200_an/] [vhdl/] [i2c/] [spi-behavior-xilinx.vhdl] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 ktt1
--------------------------------------------------------------------------------
2
--            _   _            __   ____                                      --
3
--           / / | |          / _| |  __|                                     --
4
--           | |_| |  _   _  / /   | |_                                       --
5
--           |  _  | | | | | | |   |  _|                                      --
6
--           | | | | | |_| | \ \_  | |__                                      --
7
--           |_| |_| \_____|  \__| |____| microLab                            --
8
--                                                                            --
9
--           Bern University of Applied Sciences (BFH)                        --
10
--           Quellgasse 21                                                    --
11
--           Room HG 4.33                                                     --
12
--           2501 Biel/Bienne                                                 --
13
--           Switzerland                                                      --
14
--                                                                            --
15
--           http://www.microlab.ch                                           --
16
--------------------------------------------------------------------------------
17
--   GECKO4com
18
--  
19
--   2010/2011 Dr. Theo Kluter
20
--  
21
--   This VHDL code is free code: you can redistribute it and/or modify
22
--   it under the terms of the GNU General Public License as published by
23
--   the Free Software Foundation, either version 3 of the License, or
24
--   (at your option) any later version.
25
--  
26
--   This VHDL code is distributed in the hope that it will be useful,
27
--   but WITHOUT ANY WARRANTY; without even the implied warranty of
28
--   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
--   GNU General Public License for more details. 
30
--   You should have received a copy of the GNU General Public License
31
--   along with these sources.  If not, see <http://www.gnu.org/licenses/>.
32
--
33
 
34
library UNISIM;
35
use UNISIM.VComponents.all;
36
 
37
ARCHITECTURE xilinx OF spi_if IS
38
 
39
   TYPE STATE_TYPE IS (IDLE,INIT_READ,WAIT_READ,ALL_DONE,
40
                       INIT_PAGE_LOAD,WAIT_I2C_DONE,INIT_STATE_REG_1,
41
                       POLL_STATE_REG_1,INIT_WRITE,WAIT_WRITE, INIT_WRITE_BACK ,
42
                       WAIT_WRITE_BACK,INIT_STATE_REG_2,POLL_STATE_REG_2);
43
 
44
   COMPONENT SPI_ACCESS
45
      GENERIC ( SIM_DEVICE : string );
46
      PORT( MISO : OUT std_ulogic;
47
            CLK  : IN  std_ulogic;
48
            CSB  : IN  std_ulogic;
49
            MOSI : IN  std_ulogic );
50
   END COMPONENT;
51
 
52
   COMPONENT RAM32X1S
53
      PORT ( O    : OUT std_logic;
54
             A0   : IN  std_logic;
55
             A1   : IN  std_logic;
56
             A2   : IN  std_logic;
57
             A3   : IN  std_logic;
58
             A4   : IN  std_logic;
59
             D    : IN  std_logic;
60
             WCLK : IN  std_logic;
61
             WE   : IN  std_logic);
62
   END COMPONENT;
63
 
64
   SIGNAL s_state_reg             : STATE_TYPE;
65
   SIGNAL s_spi_shift_reg         : std_logic_vector(31 DOWNTO 0 );
66
   SIGNAL s_spi_shift_next        : std_logic_vector(31 DOWNTO 0 );
67
   SIGNAL s_spi_shift_load        : std_logic_vector(31 DOWNTO 0 );
68
   SIGNAL s_n_ena_spi             : std_logic;
69
   SIGNAL s_spi_miso              : std_logic;
70
   SIGNAL s_spi_count_reg         : std_logic_vector( 9 DOWNTO 0 );
71
   SIGNAL s_spi_count_load        : std_logic_vector( 9 DOWNTO 0 );
72
   SIGNAL s_start_spi_action      : std_logic;
73
   SIGNAL s_spi_clk_reg           : std_logic;
74
   SIGNAL s_spi_mosi              : std_logic;
75
   SIGNAL s_spi_ram_index_reg     : std_logic_vector( 4 DOWNTO 0 );
76
   SIGNAL s_spi_size_reg          : std_logic_vector( 5 DOWNTO 0 );
77
   SIGNAL s_spi_address_reg       : std_logic_vector(11 DOWNTO 0 );
78
   SIGNAL s_load_data_byte        : std_logic;
79
   SIGNAL s_buffer_data           : std_logic_vector( 7 DOWNTO 0 );
80
 
81
BEGIN
82
   -- Assign outputs
83
   data_out          <= s_spi_shift_reg( 7 DOWNTO 0 );
84
   done              <= '1' WHEN s_state_reg = ALL_DONE ELSE '0';
85
   busy              <= '0' WHEN s_state_reg = IDLE OR
86
                                 s_state_reg = INIT_READ OR
87
                                 s_state_reg = WAIT_READ OR
88
                                 s_state_reg = ALL_DONE ELSE '1';
89
 
90
   -- Assign control signals
91
   s_start_spi_action <= '1' WHEN s_state_reg = INIT_READ OR
92
                                  s_state_reg = INIT_PAGE_LOAD OR
93
                                  s_state_reg = INIT_STATE_REG_1 OR
94
                                  s_state_reg = INIT_WRITE OR
95
                                  s_state_reg = INIT_WRITE_BACK OR
96
                                  s_state_reg = INIT_STATE_REG_2 ELSE '0';
97
 
98
   s_n_ena_spi       <= s_spi_count_reg(9) AND NOT(s_spi_count_reg(0));
99
   s_load_data_byte  <= '1' WHEN s_state_reg = WAIT_WRITE AND
100
                                 s_spi_count_reg( 2 DOWNTO 0 ) = "000" AND
101
                                 s_spi_clk_reg = '1' ELSE '0';
102
   s_spi_shift_next  <= s_spi_shift_load
103
                           WHEN s_start_spi_action = '1' ELSE
104
                        s_spi_shift_reg WHEN s_n_ena_spi = '1' OR
105
                                             s_spi_clk_reg = '0' ELSE
106
                        s_spi_shift_reg(30 DOWNTO 7)&s_buffer_data
107
                                        WHEN s_load_data_byte = '1' ELSE
108
                        s_spi_shift_reg(30 DOWNTO 0)&s_spi_miso;
109
 
110
   -- map processes
111
   make_spi_load_values : PROCESS( s_state_reg , address ,
112
                                   s_spi_address_reg )
113
      VARIABLE v_select : std_logic_vector( 1 DOWNTO 0 );
114
      VARIABLE v_add    : std_logic_vector( 5 DOWNTO 0 );
115
   BEGIN
116
      CASE (s_state_reg) IS
117
         WHEN INIT_READ       => s_spi_shift_load <= X"030F"&"111"&
118
                                                     s_spi_address_reg(11 DOWNTO 8)&"0"&
119
                                                     s_spi_address_reg(7 DOWNTO 0);
120
                                 s_spi_count_load <= "0000100111";
121
         WHEN INIT_PAGE_LOAD  => s_spi_shift_load <= X"530F"&"111"&
122
                                                     s_spi_address_reg(11 DOWNTO 8)&"0"&
123
                                                     X"00";
124
                                 s_spi_count_load <= "0000011111";
125
         WHEN INIT_STATE_REG_1 |
126
              INIT_STATE_REG_2=> s_spi_shift_load <= X"D7000000";
127
                                 s_spi_count_load <= "0000001111";
128
         WHEN INIT_WRITE      => s_spi_shift_load <= X"840000"&s_spi_address_reg(7 DOWNTO 0);
129
                                 v_add := unsigned(s_spi_size_reg) + 3;
130
                                 s_spi_count_load <= "0"&v_add&"111";
131
         WHEN INIT_WRITE_BACK => s_spi_shift_load <= X"830F"&"111"&
132
                                                     s_spi_address_reg(11 DOWNTO 8)&"0"&
133
                                                     X"00";
134
                                 s_spi_count_load <= "0000011111";
135
         WHEN OTHERS          => s_spi_shift_load <= X"00000000";
136
                                 s_spi_count_load <= "1111111110";
137
      END CASE;
138
   END PROCESS make_spi_load_values;
139
 
140
   make_state_machine : PROCESS( clock , reset , s_state_reg ,
141
                                 read_request , s_spi_count_reg ,
142
                                 write_request , i2c_write_done ,
143
                                 s_spi_shift_reg )
144
      VARIABLE v_next_state : STATE_TYPE;
145
   BEGIN
146
      CASE (s_state_reg) IS
147
         WHEN IDLE               => IF (read_request = '1') THEN
148
                                       v_next_state := INIT_READ;
149
                                    ELSIF (write_request = '1') THEN
150
                                       v_next_state := INIT_PAGE_LOAD;
151
                                                            ELSE
152
                                       v_next_state := IDLE;
153
                                    END IF;
154
         WHEN INIT_READ          => v_next_state := WAIT_READ;
155
         WHEN WAIT_READ          => IF (s_spi_count_reg(9) = '1') THEN
156
                                       v_next_state := ALL_DONE;
157
                                                                  ELSE
158
                                       v_next_state := WAIT_READ;
159
                                    END IF;
160
         WHEN INIT_PAGE_LOAD     => v_next_state := WAIT_I2C_DONE;
161
         WHEN WAIT_I2C_DONE      => IF (i2c_write_done = '1') THEN
162
                                       v_next_state := INIT_STATE_REG_1;
163
                                                              ELSE
164
                                       v_next_state := WAIT_I2C_DONE;
165
                                    END IF;
166
         WHEN INIT_STATE_REG_1   => v_next_state := POLL_STATE_REG_1;
167
         WHEN POLL_STATE_REG_1   => IF (s_spi_count_reg(9) = '1' AND
168
                                        s_spi_count_reg(0) = '0') THEN
169
                                       IF (s_spi_shift_reg(7) = '0') THEN
170
                                          v_next_state := INIT_STATE_REG_1;
171
                                                                     ELSE
172
                                          v_next_state := INIT_WRITE;
173
                                       END IF;
174
                                                                  ELSE
175
                                       v_next_state := POLL_STATE_REG_1;
176
                                    END IF;
177
         WHEN INIT_WRITE         => v_next_state := WAIT_WRITE;
178
         WHEN WAIT_WRITE         => IF (s_spi_count_reg(9) = '1' AND
179
                                        s_spi_count_reg(0) = '0') THEN
180
                                       v_next_state := INIT_WRITE_BACK;
181
                                                                  ELSE
182
                                       v_next_state := WAIT_WRITE;
183
                                    END IF;
184
         WHEN INIT_WRITE_BACK    => v_next_state := WAIT_WRITE_BACK;
185
         WHEN WAIT_WRITE_BACK    => IF (s_spi_count_reg(9) = '1' AND
186
                                        s_spi_count_reg(0) = '0') THEN
187
                                       v_next_state := INIT_STATE_REG_2;
188
                                                                  ELSE
189
                                       v_next_state := WAIT_WRITE_BACK;
190
                                    END IF;
191
         WHEN INIT_STATE_REG_2   => v_next_state := POLL_STATE_REG_2;
192
         WHEN POLL_STATE_REG_2   => IF (s_spi_count_reg(9) = '1' AND
193
                                        s_spi_count_reg(0) = '0') THEN
194
                                       IF (s_spi_shift_reg(7) = '0') THEN
195
                                          v_next_state := INIT_STATE_REG_2;
196
                                                                     ELSE
197
                                          v_next_state := ALL_DONE;
198
                                       END IF;
199
                                                                  ELSE
200
                                       v_next_state := POLL_STATE_REG_2;
201
                                    END IF;
202
         WHEN OTHERS             => v_next_state := IDLE;
203
      END CASE;
204
      IF (clock'event AND (clock = '1')) THEN
205
         IF (reset = '1') THEN s_state_reg <= IDLE;
206
                          ELSE s_state_reg <= v_next_state;
207
         END IF;
208
      END IF;
209
   END PROCESS make_state_machine;
210
 
211
 
212
   make_spi_count_reg : PROCESS( clock , reset , s_spi_count_reg ,
213
                                 s_start_spi_action )
214
   BEGIN
215
      IF (clock'event AND (clock = '1')) THEN
216
         IF (reset = '1') THEN s_spi_count_reg <= (0 => '0' , OTHERS => '1');
217
         ELSIF (s_start_spi_action = '1') THEN s_spi_count_reg <= s_spi_count_load;
218
         ELSIF ((s_spi_count_reg(9) = '0' OR
219
                 s_spi_count_reg(0) = '1') AND
220
                (s_spi_clk_reg = '0' OR
221
                 (s_spi_count_reg(9) = '1' AND
222
                  s_spi_count_reg(0) = '1'))) THEN
223
            s_spi_count_reg <= unsigned(s_spi_count_reg) - 1;
224
         END IF;
225
      END IF;
226
   END PROCESS make_spi_count_reg;
227
 
228
   make_spi_shift_reg : PROCESS( clock , s_spi_shift_next )
229
   BEGIN
230
      IF (clock'event AND (clock = '1')) THEN
231
         s_spi_shift_reg <= s_spi_shift_next;
232
      END IF;
233
   END PROCESS make_spi_shift_reg;
234
 
235
   make_spi_clock_reg : PROCESS( clock , s_spi_count_reg , reset )
236
   BEGIN
237
      IF (clock'event AND (clock = '1')) THEN
238
         IF (s_spi_count_reg(9) = '1') THEN s_spi_clk_reg <= '1';
239
                                       ELSE s_spi_clk_reg <= NOT(s_spi_clk_reg);
240
         END IF;
241
      END IF;
242
   END PROCESS make_spi_clock_reg;
243
 
244
   make_spi_mosi : PROCESS( clock , s_spi_clk_reg , s_spi_shift_reg ,
245
                            reset )
246
   BEGIN
247
      IF (clock'event AND (clock = '1')) THEN
248
         IF (s_spi_clk_reg = '1') THEN s_spi_mosi <= s_spi_shift_reg(31);
249
         END IF;
250
      END IF;
251
   END PROCESS make_spi_mosi;
252
 
253
   make_spi_ram_index_reg : PROCESS( clock , reset , s_state_reg ,
254
                                     write_request , s_load_data_byte )
255
   BEGIN
256
      IF (clock'event AND (clock = '1')) THEN
257
         IF (reset = '1' OR
258
             s_state_reg = ALL_DONE OR
259
             s_state_reg = INIT_WRITE) THEN s_spi_ram_index_reg <= (OTHERS => '0');
260
               IF (s_state_reg /= INIT_WRITE) THEN
261
                  s_spi_size_reg      <= (OTHERS => '0');
262
               END IF;
263
         ELSIF (write_request = '1' OR
264
                s_load_data_byte = '1') THEN
265
            s_spi_ram_index_reg <= unsigned(s_spi_ram_index_reg) + 1;
266
            IF (s_spi_size_reg(5) = '0') THEN
267
               s_spi_size_reg <= unsigned(s_spi_size_reg) + 1;
268
            END IF;
269
         END IF;
270
      END IF;
271
   END PROCESS make_spi_ram_index_reg;
272
 
273
   make_spi_address_reg : PROCESS( clock , s_state_reg , write_request ,
274
                                   address , read_request )
275
   BEGIN
276
      IF (clock'event AND (clock = '1')) THEN
277
         IF ((write_request = '1' AND
278
              s_state_reg = IDLE) OR
279
             read_request = '1') THEN
280
            s_spi_address_reg <= address;
281
         END IF;
282
      END IF;
283
   END PROCESS make_spi_address_reg;
284
 
285
   -- map components
286
   spiif: SPI_ACCESS
287
          GENERIC MAP ( SIM_DEVICE => "3S200AN" )
288
          PORT MAP ( MISO => s_spi_miso,
289
                     CLK  => s_spi_clk_reg,
290
                     CSB  => s_n_ena_spi,
291
                     MOSI => s_spi_mosi );
292
   write_buffer : FOR n IN 7 DOWNTO 0 GENERATE
293
      bufbit : RAM32X1S
294
               PORT MAP ( O    => s_buffer_data(n),
295
                          A0   => s_spi_ram_index_reg(0),
296
                          A1   => s_spi_ram_index_reg(1),
297
                          A2   => s_spi_ram_index_reg(2),
298
                          A3   => s_spi_ram_index_reg(3),
299
                          A4   => s_spi_ram_index_reg(4),
300
                          D    => data_in(n),
301
                          WCLK => clock,
302
                          WE   => write_request);
303
   END GENERATE write_buffer;
304
 
305
END xilinx;

powered by: WebSVN 2.1.0

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