source: Hardware/WARP_v3/Rev1.1/Config_CPLD/src/spi_boot_OpenCores_src/rtl/vhdl/sample/ram_loader.vhd

Last change on this file was 1799, checked in by murphpo, 12 years ago

Adding WARP v3 hardware files (schematics, FPGA pinout, configuration CPLD source)

File size: 10.0 KB
Line 
1-------------------------------------------------------------------------------
2--
3-- SD/MMC Bootloader
4-- Sample client for loading an image to asynchronous SRAM
5--
6-- $Id: ram_loader.vhd 77 2009-04-01 19:53:14Z arniml $
7--
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
47library ieee;
48use ieee.std_logic_1164.all;
49
50
51entity 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    detached_i : in    std_logic;
65    -- 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
73end ram_loader;
74
75
76library ieee;
77use ieee.numeric_std.all;
78
79architecture 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  signal done_q          : std_logic;
97  signal done_s          : boolean;
98  signal mode_q,
99         mode_s          : std_logic;
100
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  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
112  signal start_s,
113         start_q         : std_logic;
114  signal enable_s,
115         enable_q        : boolean;
116
117begin
118
119  -----------------------------------------------------------------------------
120  -- Process seq
121  --
122  -- Purpose:
123  --   Implements the sequential elements clocked with cfg_clk_i.
124  --
125  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      mode_q      <= '0';
138
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      -- done only settable once
163      if done_s then
164        done_q <= '1';
165      end if;
166
167      mode_q <= mode_s;
168
169    end if;
170  end process seq;
171  --
172  -----------------------------------------------------------------------------
173
174
175  -----------------------------------------------------------------------------
176  -- Process fsm
177  --
178  -- Purpose:
179  --   Implements the combinational logic of the RAM loader FSM.
180  --
181  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          mode_s <= '1';
218        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  --
233  -----------------------------------------------------------------------------
234
235
236  -----------------------------------------------------------------------------
237  -- Process ce_gen
238  --
239  -- Purpose:
240  --   Generates the four CE signals for the external RAM chips.
241  --
242  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  --
248  -----------------------------------------------------------------------------
249
250
251  -----------------------------------------------------------------------------
252  -- 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  -- 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
355end rtl;
Note: See TracBrowser for help on using the repository browser.