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

Subversion Repositories spi_boot

[/] [spi_boot/] [trunk/] [rtl/] [vhdl/] [sample/] [ram_loader.vhd] - Blame information for rev 77

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 arniml
-------------------------------------------------------------------------------
2
--
3
-- SD/MMC Bootloader
4
-- Sample client for loading an image to asynchronous SRAM
5
--
6 77 arniml
-- $Id: ram_loader.vhd 77 2009-04-01 19:53:14Z arniml $
7 19 arniml
--
8
-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
9
--
10
-- All rights reserved, see COPYING.
11
--
12
-- Redistribution and use in source and synthezised forms, with or without
13
-- modification, are permitted provided that the following conditions are met:
14
--
15
-- Redistributions of source code must retain the above copyright notice,
16
-- this list of conditions and the following disclaimer.
17
--
18
-- Redistributions in synthesized form must reproduce the above copyright
19
-- notice, this list of conditions and the following disclaimer in the
20
-- documentation and/or other materials provided with the distribution.
21
--
22
-- Neither the name of the author nor the names of other contributors may
23
-- be used to endorse or promote products derived from this software without
24
-- specific prior written permission.
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,
28
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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
-- Please report bugs to the author, but before you do so, please
39
-- make sure that this is not a derivative work and that
40
-- you have the latest version of this file.
41
--
42
-- The latest version of this file can be found at:
43
--      http://www.opencores.org/projects.cgi/web/spi_boot/overview
44
--
45
-------------------------------------------------------------------------------
46
 
47
library ieee;
48
use ieee.std_logic_1164.all;
49
 
50
 
51
entity ram_loader is
52
 
53
  port (
54
    -- Global Interface -------------------------------------------------------
55
    clk_i      : in    std_logic;
56
    reset_i    : in    std_logic;
57
    lamp_o     : out   std_logic;
58
    -- Config Interface -------------------------------------------------------
59
    cfg_clk_i  : in    std_logic;
60
    cfg_data_i : in    std_logic;
61
    start_o    : out   std_logic;
62
    mode_o     : out   std_logic;
63
    done_o     : out   std_logic;
64 41 arniml
    detached_i : in    std_logic;
65 19 arniml
    -- Asynchronous RAM Interface ---------------------------------------------
66
    ram_addr_o : out   std_logic_vector(15 downto 0);
67
    ram_data_b : out   std_logic_vector( 7 downto 0);
68
    ram_ce_no  : out   std_logic_vector( 3 downto 0);
69
    ram_oe_no  : out   std_logic;
70
    ram_we_no  : out   std_logic
71
  );
72
 
73
end ram_loader;
74
 
75
 
76
library ieee;
77
use ieee.numeric_std.all;
78
 
79
architecture rtl of ram_loader is
80
 
81
  signal addr_q     : unsigned(17 downto 0);
82
  signal inc_addr_s : boolean;
83
 
84
  signal shift_dat_q : std_logic_vector(7 downto 0);
85
  signal ser_dat_q   : std_logic_vector(7 downto 0);
86
  signal bit_q       : unsigned(2 downto 0);
87
  signal bit_ovfl_q  : boolean;
88
 
89
  type fsm_t is (IDLE,
90
                 WE_ON,
91
                 WE_OFF,
92
                 INC_ADDR1, INC_ADDR2,
93
                 FINISHED);
94
  signal fsm_s,
95
         fsm_q  : fsm_t;
96 41 arniml
  signal done_q          : std_logic;
97
  signal done_s          : boolean;
98
  signal mode_q,
99
         mode_s          : std_logic;
100 19 arniml
 
101
  signal ram_we_n_q,
102
         ram_we_n_s  : std_logic;
103
  signal ram_ce_n_q,
104
         ram_ce_n_s  : std_logic_vector(3 downto 0);
105
 
106 41 arniml
  type start_fsm_t is (WAIT_DETACH,
107
                       CHECK_NO_DONE,
108
                       WAIT_DONE);
109
  signal start_fsm_s,
110
         start_fsm_q  : start_fsm_t;
111 19 arniml
 
112 41 arniml
  signal start_s,
113
         start_q         : std_logic;
114
  signal enable_s,
115
         enable_q        : boolean;
116
 
117 19 arniml
begin
118
 
119 41 arniml
  -----------------------------------------------------------------------------
120
  -- Process seq
121
  --
122
  -- Purpose:
123
  --   Implements the sequential elements clocked with cfg_clk_i.
124
  --
125 19 arniml
  seq: process (cfg_clk_i, reset_i)
126
  begin
127
    if reset_i = '0' then
128
      addr_q      <= (others => '0');
129
      shift_dat_q <= (others => '0');
130
      ser_dat_q   <= (others => '0');
131
      bit_q       <= (others => '0');
132
      bit_ovfl_q  <= false;
133
      fsm_q       <= IDLE;
134
      ram_we_n_q  <= '1';
135
      ram_ce_n_q  <= (others => '1');
136
      done_q      <= '0';
137 41 arniml
      mode_q      <= '0';
138 19 arniml
 
139
    elsif cfg_clk_i'event and cfg_clk_i = '1' then
140
      if inc_addr_s then
141
        addr_q <= addr_q + 1;
142
      end if;
143
 
144
      if enable_q then
145
        bit_q      <= bit_q + 1;
146
        bit_ovfl_q <= bit_q = 7;
147
 
148
        shift_dat_q(0) <= cfg_data_i;
149
        shift_dat_q(7 downto 1) <= shift_dat_q(6 downto 0);
150
      end if;
151
 
152
      -- update register when 8 serial bits have been shifted in
153
      if bit_ovfl_q then
154
        ser_dat_q <= shift_dat_q;
155
      end if;
156
 
157
      fsm_q <= fsm_s;
158
 
159
      ram_we_n_q <= ram_we_n_s;
160
      ram_ce_n_q <= ram_ce_n_s;
161
 
162 41 arniml
      -- done only settable once
163 19 arniml
      if done_s then
164
        done_q <= '1';
165
      end if;
166
 
167 41 arniml
      mode_q <= mode_s;
168 19 arniml
 
169
    end if;
170
  end process seq;
171 41 arniml
  --
172
  -----------------------------------------------------------------------------
173 19 arniml
 
174
 
175 41 arniml
  -----------------------------------------------------------------------------
176
  -- Process fsm
177
  --
178
  -- Purpose:
179
  --   Implements the combinational logic of the RAM loader FSM.
180
  --
181 19 arniml
  fsm: process (fsm_q,
182
                bit_ovfl_q,
183
                start_q,
184
                addr_q)
185
  begin
186
    -- default assignments
187
    inc_addr_s      <= false;
188
    ram_we_n_s      <= '1';
189
    done_s          <= false;
190
    fsm_s           <= IDLE;
191
    lamp_o          <= '1';
192
    mode_s          <= '0';
193
 
194
    case fsm_q is
195
      when IDLE =>
196
        lamp_o <= '0';
197
        if start_q = '1' then
198
          if bit_ovfl_q then
199
            fsm_s <= WE_ON;
200
          end if;
201
        end if;
202
 
203
      when WE_ON =>
204
        ram_we_n_s <= '0';
205
        fsm_s      <= WE_OFF;
206
 
207
      when WE_OFF =>
208
        fsm_s <= INC_ADDR1;
209
 
210
      when INC_ADDR1 =>
211
        fsm_s      <= INC_ADDR2;
212
 
213
      when INC_ADDR2 =>
214
        if addr_q = "001111111111111111" then  -- load only 64k
215
          fsm_s <= FINISHED;
216
          done_s <= true;
217 41 arniml
          mode_s <= '1';
218 19 arniml
        else
219
          inc_addr_s <= true;
220
          fsm_s      <= IDLE;
221
        end if;
222
 
223
      when FINISHED =>
224
        fsm_s  <= FINISHED;
225
        lamp_o <= '1';
226
        mode_s <= '1';
227
 
228
      when others =>
229
    end case;
230
 
231
  end process fsm;
232 41 arniml
  --
233
  -----------------------------------------------------------------------------
234 19 arniml
 
235 41 arniml
 
236
  -----------------------------------------------------------------------------
237
  -- Process ce_gen
238
  --
239
  -- Purpose:
240
  --   Generates the four CE signals for the external RAM chips.
241
  --
242 19 arniml
  ce_gen: process (addr_q)
243
  begin
244
    ram_ce_n_s <= (others => '1');
245
    ram_ce_n_s(to_integer(addr_q(17 downto 16))) <= '0';
246
  end process ce_gen;
247 41 arniml
  --
248
  -----------------------------------------------------------------------------
249 19 arniml
 
250 41 arniml
 
251 19 arniml
  -----------------------------------------------------------------------------
252 41 arniml
  -- Process start_seq
253
  --
254
  -- Purpose:
255
  --   Implements the sequential elements clocked with clk_i.
256
  --
257
  start_seq: process (clk_i, reset_i)
258
  begin
259
    if reset_i = '0' then
260
      start_fsm_q <= WAIT_DETACH;
261
      start_q     <= '0';
262
      enable_q    <= false;
263
 
264
    elsif clk_i'event and clk_i = '1' then
265
      start_fsm_q <= start_fsm_s;
266
 
267
      enable_q    <= enable_s;
268
 
269
      start_q     <= start_s;
270
 
271
    end if;
272
  end process start_seq;
273
  --
274
  -----------------------------------------------------------------------------
275
 
276
 
277
  -----------------------------------------------------------------------------
278
  -- Process start_comb
279
  --
280
  -- Purpose:
281
  --   Implements the combinational logic of the start FSM.
282
  --
283
  start_comb: process (start_fsm_q,
284
                       detached_i,
285
                       done_q,
286
                       enable_q,
287
                       start_q)
288
  begin
289
    -- default assignments
290
    start_fsm_s <= WAIT_DETACH;
291
    enable_s    <= enable_q;
292
    start_s     <= start_q;
293
 
294
    case start_fsm_q is
295
      -- Wait for detached_i to become '1'
296
      -- This state is entered/left twice:
297
      -- 1. after reset to start the data download
298
      -- 2. after data download to start the next configuration cycle
299
      when WAIT_DETACH =>
300
        if detached_i = '1' then
301
          start_fsm_s <= CHECK_NO_DONE;
302
          enable_s    <= true;
303
          start_s     <= '1';
304
 
305
        else
306
          start_fsm_s <= WAIT_DETACH;
307
        end if;
308
 
309
      -- Wait until done_q is '0'
310
      -- This ensures that the FSM stalls when it has started the configuration
311
      -- download. There must be no further action in this case.
312
      when CHECK_NO_DONE =>
313
        if done_q = '0' then
314
          start_fsm_s <= WAIT_DONE;
315
        else
316
          start_fsm_s <= CHECK_NO_DONE;
317
        end if;
318
 
319
      -- Wait until done_q is '1'
320
      -- done_q is the signal that the main FSM has finished its work. We
321
      -- need to start the configuration download.
322
      when WAIT_DONE =>
323
        if done_q = '1' then
324
          start_fsm_s <= WAIT_DETACH;
325
          enable_s    <= false;
326
          start_s     <= '0';
327
        else
328
          start_fsm_s <= WAIT_DONE;
329
        end if;
330
 
331
      when others =>
332
        null;
333
 
334
    end case;
335
 
336
  end process start_comb;
337
  --
338
  -----------------------------------------------------------------------------
339
 
340
 
341
  -----------------------------------------------------------------------------
342 19 arniml
  -- Output Mapping
343
  -----------------------------------------------------------------------------
344
  start_o    <= start_q;
345
  mode_o     <= mode_q;
346
  done_o     <=   done_q
347
                when start_q = '1' else
348
                  '1';
349
  ram_addr_o <= std_logic_vector(addr_q(15 downto 0));
350
  ram_data_b <= ser_dat_q;
351
  ram_oe_no  <= '1';
352
  ram_ce_no  <= ram_ce_n_q;
353
  ram_we_no  <= ram_we_n_q;
354
 
355
end rtl;

powered by: WebSVN 2.1.0

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