source: Hardware/WARP_v3/Rev1.1/Config_CPLD/src/spi_boot.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: 28.7 KB
Line 
1-------------------------------------------------------------------------------
2--
3-- SD/MMC Bootloader
4--
5-- $Id: spi_boot.vhd 77 2009-04-01 19:53:14Z arniml $
6--
7-- Copyright (c) 2005, Arnim Laeuger (arniml@opencores.org)
8--
9-- All rights reserved, see COPYING.
10--
11-- Redistribution and use in source and synthezised forms, with or without
12-- modification, are permitted provided that the following conditions are met:
13--
14-- Redistributions of source code must retain the above copyright notice,
15-- this list of conditions and the following disclaimer.
16--
17-- Redistributions in synthesized form must reproduce the above copyright
18-- notice, this list of conditions and the following disclaimer in the
19-- documentation and/or other materials provided with the distribution.
20--
21-- Neither the name of the author nor the names of other contributors may
22-- be used to endorse or promote products derived from this software without
23-- specific prior written permission.
24--
25-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
29-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35-- POSSIBILITY OF SUCH DAMAGE.
36--
37-- Please report bugs to the author, but before you do so, please
38-- make sure that this is not a derivative work and that
39-- you have the latest version of this file.
40--
41-- The latest version of this file can be found at:
42--      http://www.opencores.org/projects.cgi/web/spi_boot/overview
43--
44-------------------------------------------------------------------------------
45
46library ieee;
47use ieee.std_logic_1164.all;
48
49
50entity spi_boot is
51
52  generic (
53    -- width of bit counter: minimum 6, maximum 12
54    width_bit_cnt_g      : integer := 6;
55    -- width of image counter: minimum 0, maximum n
56    width_img_cnt_g      : integer := 2;
57    -- number of bits required to address one image
58    num_bits_per_img_g   : integer := 18;
59    -- SD specific initialization
60    sd_init_g            : integer := 0;
61    -- clock divider to reach 400 kHz for MMC compatibility
62    mmc_compat_clk_div_g : integer := 0;
63    width_mmc_clk_div_g  : integer := 0;
64    -- active level of reset_i
65    reset_level_g        : integer := 0
66  );
67
68  port (
69    -- System Interface -------------------------------------------------------
70    clk_i          : in  std_logic;
71    reset_i        : in  std_logic;
72    set_sel_i      : in  std_logic_vector(31-width_img_cnt_g-num_bits_per_img_g
73                                          downto 0);
74    -- Card Interface ---------------------------------------------------------
75    spi_clk_o      : out std_logic;
76    spi_cs_n_o     : out std_logic;
77    spi_data_in_i  : in  std_logic;
78    spi_data_out_o : out std_logic;
79    spi_en_outs_o  : out std_logic;
80    -- FPGA Configuration Interface -------------------------------------------
81    start_i        : in  std_logic;
82    mode_i         : in  std_logic;
83    config_n_o     : out std_logic;
84    detached_o     : out std_logic;
85    cfg_init_n_i   : in  std_logic;
86    cfg_done_i     : in  std_logic;
87    dat_done_i     : in  std_logic;
88    cfg_clk_o      : out std_logic;
89    cfg_dat_o      : out std_logic
90  );
91
92end spi_boot;
93
94
95library ieee;
96use ieee.numeric_std.all;
97use work.spi_boot_pack.all;
98
99architecture rtl of spi_boot is
100
101  component spi_counter
102    generic (
103      cnt_width_g   : integer := 4;
104      cnt_max_g     : integer := 15
105    );
106    port (
107      clk_i      : in  std_logic;
108      reset_i    : in  boolean;
109      cnt_en_i   : in  boolean;
110      cnt_o      : out std_logic_vector(cnt_width_g-1 downto 0);
111      cnt_ovfl_o : out boolean
112    );
113  end component;
114
115
116  -----------------------------------------------------------------------------
117  -- States of the controller FSM
118  --
119  type ctrl_states_t is (POWER_UP1, POWER_UP2,
120                         CMD0,
121                         CMD1,
122                         CMD55, ACMD41,
123                         CMD16,
124                         WAIT_START,
125                         WAIT_INIT_LOW, WAIT_INIT_HIGH,
126                         CMD18, CMD18_DATA,
127                         CMD12,
128                         INC_IMG_CNT);
129  --
130  signal ctrl_fsm_q,
131         ctrl_fsm_s  : ctrl_states_t;
132  --
133  -----------------------------------------------------------------------------
134
135  -----------------------------------------------------------------------------
136  -- States of the command FSM
137  --
138  type cmd_states_t is (CMD, START, R1, PAUSE);
139  --
140  signal cmd_fsm_q,
141         cmd_fsm_s  : cmd_states_t;
142  --
143  -----------------------------------------------------------------------------
144
145  subtype op_r     is integer range 5 downto 0;
146  type    res_bc_t is (NONE, RES_MAX, RES_47, RES_15, RES_7);
147  signal  bit_cnt_q  : unsigned(width_bit_cnt_g-1 downto 0);
148  signal  res_bc_s   : res_bc_t;
149  signal  upper_bitcnt_zero_s : boolean;
150
151  signal cfg_dat_q : std_logic;
152
153  signal spi_clk_q         : std_logic;
154  signal spi_clk_rising_q  : boolean;
155  signal spi_clk_falling_q : boolean;
156  signal spi_dat_q,
157         spi_dat_s         : std_logic;
158  signal spi_cs_n_q,
159         spi_cs_n_s        : std_logic;
160
161  signal cfg_clk_q      : std_logic;
162
163  signal start_q        : std_logic;
164
165  signal img_cnt_s      : std_logic_vector(width_img_cnt_g downto 0);
166  signal cnt_en_img_s   : boolean;
167  signal mmc_cnt_ovfl_s : boolean;
168  signal mmc_compat_s   : boolean;
169
170  signal cmd_finished_s : boolean;
171
172  signal r1_illcmd_q,
173         r1_idle_q      : std_logic;
174  signal done_q,
175         send_cmd12_q   : boolean;
176
177  signal en_outs_s,
178         en_outs_q      : boolean;
179
180  signal reset_s        : boolean;
181
182  signal true_s         : boolean;
183
184begin
185
186  true_s <= true;
187
188  reset_s <=   true
189             when (reset_level_g = 1 and reset_i = '1') or
190                  (reset_level_g = 0 and reset_i = '0') else
191               false;
192
193  -----------------------------------------------------------------------------
194  -- Process seq
195  --
196  -- Purpose:
197  --   Implements several sequential elements.
198  --
199  seq: process (clk_i, reset_s)
200
201    variable bit_cnt_v : unsigned(1 downto 0);
202
203  begin
204    if reset_s then
205      -- reset bit counter to 63 for power up
206      bit_cnt_q       <= (others => '0');
207      bit_cnt_q(op_r) <= "111111";
208      spi_dat_q    <= '1';
209      spi_cs_n_q   <= '1';
210      cfg_dat_q    <= '1';
211      start_q      <= '0';
212      done_q       <= false;
213      send_cmd12_q <= false;
214      ctrl_fsm_q   <= POWER_UP1;
215      cmd_fsm_q    <= CMD;
216      r1_illcmd_q  <= '0';
217      r1_idle_q    <= '0';
218      en_outs_q    <= false;
219
220    elsif clk_i'event and clk_i = '1' then
221      -- bit counter control
222      if spi_clk_rising_q then
223        case res_bc_s is
224          when NONE =>
225            bit_cnt_q       <= bit_cnt_q - 1;
226          when RES_MAX =>
227            bit_cnt_q       <= (others => '1');
228          when RES_47 =>
229            bit_cnt_q       <= (others => '0');
230            bit_cnt_q(op_r) <= "101111";
231          when RES_15 =>
232            bit_cnt_q       <= (others => '0');
233            bit_cnt_q(op_r) <= "001111";
234          when RES_7 =>
235            bit_cnt_q       <= (others => '0');
236            bit_cnt_q(op_r) <= "000111";
237          when others =>
238            bit_cnt_q       <= (others => '0');
239        end case;
240      end if;
241
242      -- Card data output register
243      -- spi_clk_falling_q acts as enable during MMC clock compatibility mode.
244      -- As soon as this mode is left, the register must start latching.
245      -- There is no explicit relation to spi_clk_q anymore in normal mode.
246      -- Instead, spi_dat_s is operated by bit_cnt_q above which changes its
247      -- value after the rising edge of spi_clk_q.
248      --   -> spi_dat_q changes upon falling edge of spi_clk_q
249      if spi_clk_falling_q or not mmc_compat_s then
250        spi_dat_q <= spi_dat_s;
251      end if;
252
253      -- config data output register
254      -- a new value is loaded when config clock is high,
255      -- i.e. input data is sampled with rising spi_clk
256      -- while output value changes on falling edge of cfg_clk
257      if cfg_clk_q = '1' and spi_clk_rising_q then
258        cfg_dat_q <= spi_data_in_i;
259      end if;
260
261      -- Controller FSM state
262      ctrl_fsm_q <= ctrl_fsm_s;
263
264      -- Command FSM state
265      cmd_fsm_q <= cmd_fsm_s;
266
267      -- CS signal for SPI card
268      if spi_clk_q = '1' then
269        spi_cs_n_q <= spi_cs_n_s;
270      end if;
271
272      -- Extract flags from R1 response
273      if cmd_fsm_q = R1 then
274        bit_cnt_v := bit_cnt_q(1 downto 0);
275        case bit_cnt_v(1 downto 0) is
276          when "10" =>
277            -- save "Illegal Command" flag
278            r1_illcmd_q <= to_X01(spi_data_in_i);
279          when "00" =>
280            -- save "Idle State" flag
281            r1_idle_q   <= to_X01(spi_data_in_i);
282          when others =>
283            null;
284        end case;
285      end if;
286
287      -- Start trigger register for rising edge detection
288      -- the reset value is '0' thus a rising edge will always be detected
289      -- after reset even though start_i is tied to '1'
290      if start_i = '0' then
291        start_q <= '0';
292      elsif ctrl_fsm_q = WAIT_START and cmd_finished_s then
293        start_q <= start_i;
294      end if;
295
296      -- Marker for cfg_done and dat_done
297      if ctrl_fsm_q = CMD18_DATA then
298        if cfg_done_i = '1' and dat_done_i = '1' then
299          done_q       <= true;
300        end if;
301
302        if done_q and
303           (not upper_bitcnt_zero_s or cmd_fsm_q = START) then
304          -- activate sending of CMD12 when it is safe:
305          -- * upper bits of bit counter are not zero
306          --   -> transmission of CMD12 is not running
307          -- * cmd FSM is in START state
308          --   -> also no transmission running
309          send_cmd12_q <= true;
310        end if;
311      elsif ctrl_fsm_q = WAIT_START then
312        -- reset done_q when WAIT_START has been reached
313        -- this is necessary to let the stop transmission process come to
314        -- an end without interruption or generation of unwanted cfg_clk_q
315        done_q         <= false;
316        send_cmd12_q   <= false;
317      end if;
318
319      -- output enable
320      if spi_clk_rising_q then
321        en_outs_q <= en_outs_s;
322      end if;
323
324    end if;
325
326  end process seq;
327  --
328  -----------------------------------------------------------------------------
329
330
331  -----------------------------------------------------------------------------
332  -- Process upper_bits
333  --
334  -- Purpose:
335  --   Detects that the upper bits of the bit counter are zero.
336  --   Upper bits = n downto 6, i.e. the optional part that is not required for
337  --   commands but for extension of data blocks.
338  --
339  upper_bits: process (bit_cnt_q)
340    variable zero_v : boolean;
341  begin
342
343    zero_v     := true;
344    for i in bit_cnt_q'high downto 6 loop
345      if bit_cnt_q(i) = '1' then
346        zero_v := false;
347      end if;
348    end loop;
349
350    upper_bitcnt_zero_s <= zero_v;
351
352  end process upper_bits;
353  --
354  -----------------------------------------------------------------------------
355
356
357  -----------------------------------------------------------------------------
358  -- Process clk_gen
359  --
360  -- Purpose:
361  --   Generates clocks for card and FPGA configuration.
362  --   The card clock is free running with a divide by two of clk_i.
363  --   The clock for FPGA config has an enable and is stopped on high level.
364  --   There is a phase shift of half a period between spi_clk and cfg_clk.
365  --
366  clk_gen: process (clk_i, reset_s)
367  begin
368    if reset_s then
369      spi_clk_q        <= '0';
370      cfg_clk_q        <= '1';
371
372    elsif clk_i'event and clk_i = '1' then
373
374      -- spi_clk_q rises according to the flag
375      -- it falls with overflow indication
376      -- the resulting duty cycle is not exactly 50:50,
377      -- high time is a bit longer
378      if mmc_compat_s then
379        -- MMC clock compatibility mode:
380        -- spi_clk_q rises when flagged by spi_clk_rising_q
381        if spi_clk_rising_q then
382          spi_clk_q <= '1';
383        elsif mmc_cnt_ovfl_s then
384          -- upon counter overflow spi_clk_q falls in case it does not rise
385          spi_clk_q <= '0';
386        end if;
387      else
388        -- normal mode
389        -- spi_clk_q follows spi_clk_rising_q
390        if spi_clk_rising_q then
391          spi_clk_q <= '1';
392        else
393          spi_clk_q <= '0';
394        end if;
395      end if;
396
397      -- clock for FPGA config must be enabled and follows spi_clk
398      if ctrl_fsm_q = CMD18_DATA and cmd_fsm_q = CMD and
399         not done_q then
400        cfg_clk_q <= spi_clk_q;
401      else
402        cfg_clk_q <= '1';
403      end if;
404
405    end if;
406
407  end process clk_gen;
408  --
409  -----------------------------------------------------------------------------
410
411
412  -----------------------------------------------------------------------------
413  -- Indication flags for rising and falling spi_clk_q.
414  -- Essential for MMC clock compatibility mode.
415  -----------------------------------------------------------------------------
416  mmc_comap: if mmc_compat_clk_div_g > 0 generate
417    mmc_compat_sig: process (clk_i, reset_s)
418    begin
419      if reset_s then
420        spi_clk_rising_q  <= false;
421        spi_clk_falling_q <= false;
422
423      elsif clk_i'event and clk_i = '1' then
424        if mmc_compat_s then
425          -- MMC clock compatibility mode:
426          -- spi_clk_rising_q is an impulse right before rising edge of spi_clk_q
427          -- spi_clk_falling_q is an impulse right before falling edge of spi_clk_q
428          if mmc_cnt_ovfl_s then
429            spi_clk_rising_q  <= spi_clk_q = '0';
430            spi_clk_falling_q <= spi_clk_q = '1';
431          else
432            spi_clk_rising_q  <= false;
433            spi_clk_falling_q <= false;
434          end if;
435        else
436          -- normal mode
437          spi_clk_rising_q  <= not spi_clk_rising_q;
438          spi_clk_falling_q <= true;
439        end if;
440
441      end if;
442    end process mmc_compat_sig;
443  end generate;
444
445  no_mmc_compat: if mmc_compat_clk_div_g = 0 generate
446    -- SPI clock rising whenever spi_clk_q is '0'
447    spi_clk_rising_q  <= spi_clk_q = '0';
448    -- SPI clock falling whenever spi_clk_q is '1'
449    spi_clk_falling_q <= spi_clk_q = '1';
450  end generate;
451
452
453  -----------------------------------------------------------------------------
454  -- Process ctrl_fsm
455  --
456  -- Purpose:
457  --   Implements the controller FSM.
458  --
459  ctrl_fsm: process (ctrl_fsm_q,
460                     cmd_finished_s, r1_illcmd_q, r1_idle_q,
461                     start_i, start_q, mode_i,
462                     cfg_init_n_i)
463
464    variable mmc_compat_v : boolean;
465
466  begin
467    -- default assignments
468    ctrl_fsm_s   <= POWER_UP1;
469    config_n_o   <= '1';
470    cnt_en_img_s <= false;
471    spi_cs_n_s   <= '0';
472    mmc_compat_v := false;
473    en_outs_s    <= true;
474
475    case ctrl_fsm_q is
476      -- Let card finish power up, step 1 -------------------------------------
477      when POWER_UP1 =>
478        mmc_compat_v := true;
479        spi_cs_n_s   <= '1';
480        if cmd_finished_s then
481          ctrl_fsm_s <= POWER_UP2;
482        else
483          ctrl_fsm_s <= POWER_UP1;
484        end if;
485
486
487      -- Let card finish power up, step 2 -------------------------------------
488      when POWER_UP2 =>
489        mmc_compat_v := true;
490        if cmd_finished_s then
491          ctrl_fsm_s <= CMD0;
492        else
493          spi_cs_n_s <= '1';
494          ctrl_fsm_s <= POWER_UP2;
495        end if;
496
497
498      -- Issue CMD0: GO_IDLE_STATE --------------------------------------------
499      when CMD0 =>
500        mmc_compat_v   := true;
501        if cmd_finished_s then
502          if sd_init_g = 1 then
503            ctrl_fsm_s <= CMD55;
504          else
505            ctrl_fsm_s <= CMD1;
506          end if;
507        else
508          ctrl_fsm_s   <= CMD0;
509        end if;
510
511
512      -- Issue CMD55: APP_CMD -------------------------------------------------
513      when CMD55 =>
514        if sd_init_g = 1 then
515
516          mmc_compat_v   := true;
517          if cmd_finished_s then
518            if r1_illcmd_q = '0' then
519              -- command accepted, continue with ACMD41
520              ctrl_fsm_s <= ACMD41;
521            else
522              -- command rejected, it's an MMC card
523              ctrl_fsm_s <= CMD1;
524            end if;
525          else
526            ctrl_fsm_s   <= CMD55;
527          end if;
528
529        end if;
530
531
532      -- Issue ACMD41: SEND_OP_COND -------------------------------------------
533      when ACMD41 =>
534        if sd_init_g = 1 then
535
536          mmc_compat_v     := true;
537          if cmd_finished_s then
538            if r1_illcmd_q = '0' then
539              -- ok, that's an SD card
540              if r1_idle_q = '0' then
541                ctrl_fsm_s <= CMD16;
542              else
543                ctrl_fsm_s <= CMD55;
544              end if;
545
546            else
547              -- command rejected, though it accepted CMD55 -> it's an MMC
548              ctrl_fsm_s   <= CMD1;
549            end if;
550
551          else
552            ctrl_fsm_s     <= ACMD41;
553          end if;
554
555        end if;
556
557
558      -- Issue CMD1: SEND_OP_COND ---------------------------------------------
559      when CMD1 =>
560        mmc_compat_v   := true;
561        if cmd_finished_s then
562          if r1_idle_q = '0' then
563            ctrl_fsm_s <= CMD16;
564          else
565            ctrl_fsm_s <= CMD1;
566          end if;
567        else
568          ctrl_fsm_s   <= CMD1;
569        end if;
570
571
572      -- Issue CMD16: SET_BLOCKLEN --------------------------------------------
573      when CMD16 =>
574        if cmd_finished_s then
575          ctrl_fsm_s <= WAIT_START;
576        else
577          ctrl_fsm_s <= CMD16;
578        end if;
579
580
581      -- Wait for configuration start request ---------------------------------
582      when WAIT_START =>
583        spi_cs_n_s     <= '1';
584
585        --POM 2012-06-23: Adding de-assertion of PROG
586        config_n_o   <= '1';
587
588        -- detect rising edge of start_i
589        if start_i = '1' and start_q = '0' then
590          -- decide which mode is requested
591          if cmd_finished_s then
592            if mode_i = '0' then
593              ctrl_fsm_s <= CMD18;
594            else
595              ctrl_fsm_s <= WAIT_INIT_LOW;
596            end if;
597          else
598            en_outs_s    <= false;
599            ctrl_fsm_s   <= WAIT_START;
600          end if;
601        else
602          en_outs_s      <= false;
603          ctrl_fsm_s     <= WAIT_START;
604        end if;
605
606
607      -- Wait for INIT to become low ------------------------------------------
608      when WAIT_INIT_LOW =>
609        spi_cs_n_s   <= '1';
610        -- activate FPGA configuration
611        config_n_o   <= '0';
612
613        if cfg_init_n_i = '0' then
614          ctrl_fsm_s <= WAIT_INIT_HIGH;
615        else
616          ctrl_fsm_s <= WAIT_INIT_LOW;
617        end if;
618
619
620      -- Wait for INIT to become high -----------------------------------------
621      when WAIT_INIT_HIGH =>
622        spi_cs_n_s   <= '1';
623
624        --POM 2012-06-23: Adding de-assertion of PROG
625        config_n_o   <= '1';
626
627        if cfg_init_n_i = '1' and cmd_finished_s then
628          ctrl_fsm_s <= CMD18;
629        else
630          ctrl_fsm_s <= WAIT_INIT_HIGH;
631        end if;
632
633
634      -- Issue CMD18: READ_MULTIPLE_BLOCKS ------------------------------------
635      when CMD18 =>
636        if cmd_finished_s then
637          ctrl_fsm_s <= CMD18_DATA;
638        else
639          ctrl_fsm_s <= CMD18;
640        end if;
641      --
642      -- receive a data block
643      when CMD18_DATA =>
644        if cmd_finished_s then
645          ctrl_fsm_s   <= CMD12;
646        else
647          ctrl_fsm_s   <= CMD18_DATA;
648        end if;
649
650
651       -- Issued CMD12: STOP_TRANSMISSION -------------------------------------
652       when CMD12 =>
653         if cmd_finished_s then
654           ctrl_fsm_s <= INC_IMG_CNT;
655         else
656           ctrl_fsm_s <= CMD12;
657         end if;
658
659
660      -- Increment Image Counter ----------------------------------------------
661      when INC_IMG_CNT =>
662        spi_cs_n_s   <= '1';
663        ctrl_fsm_s   <= WAIT_START;
664        cnt_en_img_s <= true;
665
666
667
668      when others =>
669        null;
670
671    end case;
672
673    -- mmc_compat_s is suppressed if MMC clock compatibility is not required
674    if mmc_compat_clk_div_g > 0 then
675      mmc_compat_s <= mmc_compat_v;
676    else
677      mmc_compat_s <= false;
678    end if;
679
680  end process ctrl_fsm;
681  --
682  -----------------------------------------------------------------------------
683
684
685  -----------------------------------------------------------------------------
686  -- Process cmd_fsm
687  --
688  -- Purpose:
689  --   Implements the command FSM.
690  --
691  cmd_fsm: process (spi_clk_rising_q,
692                    spi_data_in_i,
693                    bit_cnt_q,
694                    ctrl_fsm_q,
695                    cmd_fsm_q,
696                    send_cmd12_q)
697
698    variable cnt_zero_v     : boolean;
699    variable spi_data_low_v : boolean;
700    variable no_startbit_v  : boolean;
701
702  begin
703    -- default assignments
704    cmd_finished_s <= false;
705    cmd_fsm_s      <= CMD;
706    res_bc_s       <= NONE;
707
708    cnt_zero_v     := spi_clk_rising_q and bit_cnt_q = 0;
709    spi_data_low_v := spi_clk_rising_q and spi_data_in_i = '0';
710
711    -- these are no real commands thus there will be no startbit
712    case ctrl_fsm_q is
713      when POWER_UP1  | POWER_UP2 |
714           WAIT_START | WAIT_INIT_HIGH | WAIT_INIT_LOW =>
715        no_startbit_v := true;
716      when others =>
717        no_startbit_v := false;
718    end case;
719
720
721    case cmd_fsm_q is
722      -- Send the command -----------------------------------------------------
723      when CMD =>
724        if cnt_zero_v then
725          if ctrl_fsm_q /= CMD18_DATA then
726            -- normal commands including CMD12 require startbit of R1 response
727            cmd_fsm_s <= START;
728          else
729            if not send_cmd12_q then
730              -- CMD18_DATA needs to read CRC
731              cmd_fsm_s <= R1;
732              res_bc_s <= RES_15;
733            else
734              -- CMD18_DATA finished, scan for startbit of response
735              cmd_finished_s <= true;
736              cmd_fsm_s      <= START;
737            end if;
738          end if;
739        else
740          cmd_fsm_s <= CMD;
741        end if;
742
743      -- Wait for startbit of response ----------------------------------------
744      when START =>
745        -- startbit detection or skip of this check
746        if no_startbit_v and spi_clk_rising_q then
747          cmd_fsm_s   <= R1;
748          res_bc_s    <= RES_7;
749        elsif spi_data_low_v then
750          if ctrl_fsm_q /= CMD18_DATA then
751            cmd_fsm_s <= R1;
752          else
753            -- CMD18_DATA startbit detected, read payload
754            cmd_fsm_s <= CMD;
755            res_bc_s  <= RES_MAX;
756          end if;
757        else
758          cmd_fsm_s   <= START;
759          res_bc_s    <= RES_7;
760        end if;
761
762      -- Read R1 response -----------------------------------------------------
763      when R1 =>
764        if cnt_zero_v then
765          res_bc_s  <= RES_7;
766
767          if not (ctrl_fsm_q = CMD18 or ctrl_fsm_q = CMD18_DATA) then
768            cmd_fsm_s        <= PAUSE;
769          else
770            -- CMD18 needs another startbit detection for the data token.
771            -- CMD18_DATA needs a startbit after having received the CRC, either
772            --   * next data token
773            --   * R1 response of CMD12
774            cmd_fsm_s        <= START;
775
776            if ctrl_fsm_q = CMD18 then
777              -- CMD18 response received -> advance to CMD18_DATA
778              cmd_finished_s <= true;
779            end if;
780          end if;
781        else
782          cmd_fsm_s <= R1;
783        end if;
784
785      -- PAUSE state -> required for Nrc, card response to host command -------
786      when PAUSE =>
787        if cnt_zero_v then
788          cmd_fsm_s <= CMD;
789          res_bc_s  <= RES_47;
790          cmd_finished_s <= true;
791        else
792          cmd_fsm_s <= PAUSE;
793        end if;
794
795      when others =>
796        null;
797
798    end case;
799
800  end process cmd_fsm;
801  --
802  -----------------------------------------------------------------------------
803
804
805  -----------------------------------------------------------------------------
806  -- Process transmit
807  --
808  -- Purpose:
809  --   Generates the serial data output values based on the current FSM state
810  --
811  --   The local variable cmd_v is 64 bits wide in contrast to an SPI command
812  --   with 48 bits. There are two reasons for this:
813  --   * During "overlaid" sending of CMD12 in FSM state CMD18_DATA, the bit
814  --     counter will start from 3F on its lowest 6 bits. Therefore, it is
815  --     necessary to provide all 64 positions in cmd_v.
816  --   * Reduces logic.
817  --
818  transmit: process (ctrl_fsm_q,
819                     cmd_fsm_q,
820                     bit_cnt_q,
821                     img_cnt_s,
822                     send_cmd12_q,
823                     set_sel_i,
824                     upper_bitcnt_zero_s)
825
826    subtype cmd_r is natural range 47 downto 0;
827    subtype cmd_t is std_logic_vector(cmd_r);
828    subtype ext_cmd_t is std_logic_vector(63 downto 0);
829    --                            STCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcccccccS
830    constant cmd0_c   : cmd_t := "010000000000000000000000000000000000000010010101";
831    constant cmd1_c   : cmd_t := "0100000100000000000000000000000000000000-------1";
832    constant cmd12_c  : cmd_t := "0100110000000000000000000000000000000000-------1";
833    constant cmd16_c  : cmd_t := "0101000000000000000000000000000000000000-------1";
834    constant cmd18_c  : cmd_t := "0101001000000000000000000000000000000000-------1";
835    constant cmd55_c  : cmd_t := "0111011100000000000000000000000000000000-------1";
836    constant acmd41_c : cmd_t := "0110100100000000000000000000000000000000-------1";
837
838    variable cmd_v      : ext_cmd_t;
839    variable tx_v       : boolean;
840
841  begin
842    -- default assignments
843    spi_dat_s    <= '1';
844    cmd_v        := (others => '1');
845    tx_v         := false;
846
847    if cmd_fsm_q = CMD then
848      case ctrl_fsm_q is
849        when CMD0 =>
850          cmd_v(cmd_r) := cmd0_c;
851          tx_v := true;
852        when CMD1 =>
853          cmd_v(cmd_r) := cmd1_c;
854          tx_v := true;
855        when CMD16 =>
856          cmd_v(cmd_r) := cmd16_c;
857          cmd_v(8 + width_bit_cnt_g-3) := '1';
858          tx_v := true;
859        when CMD18 =>
860          cmd_v(cmd_r) := cmd18_c;
861          -- insert image counter
862          cmd_v(8 + num_bits_per_img_g + width_img_cnt_g
863                downto 8 + num_bits_per_img_g) := img_cnt_s;
864          -- insert set selection
865          cmd_v(8 + 31
866                downto 8 + num_bits_per_img_g + width_img_cnt_g) := set_sel_i;
867          tx_v := true;
868        when CMD18_DATA =>
869          cmd_v(cmd_r) := cmd12_c;
870
871          if send_cmd12_q and upper_bitcnt_zero_s then
872            tx_v := true;
873          end if;
874        when CMD55 =>
875          cmd_v(cmd_r) := cmd55_c;
876          tx_v := true;
877        when ACMD41 =>
878          cmd_v(cmd_r) := acmd41_c;
879          tx_v := true;
880
881        when others =>
882          null;
883      end case;
884    end if;
885
886    if tx_v then
887      spi_dat_s <= cmd_v(to_integer(bit_cnt_q(5 downto 0)));
888    end if;
889
890  end process transmit;
891  --
892  -----------------------------------------------------------------------------
893
894
895  -----------------------------------------------------------------------------
896  -- Optional Image Counter
897  -----------------------------------------------------------------------------
898  img_cnt: if width_img_cnt_g > 0 generate
899    img_cnt_b : spi_counter
900      generic map (
901        cnt_width_g   => width_img_cnt_g,
902        cnt_max_g     => 2**width_img_cnt_g - 1
903      )
904      port map (
905        clk_i         => clk_i,
906        reset_i       => reset_s,
907        cnt_en_i      => cnt_en_img_s,
908        cnt_o         => img_cnt_s(width_img_cnt_g-1 downto 0),
909        cnt_ovfl_o    => open
910      );
911    img_cnt_s(width_img_cnt_g) <= '0';
912  end generate;
913
914  no_img_cnt: if width_img_cnt_g = 0 generate
915    img_cnt_s <= (others => '0');
916  end generate;
917
918
919  -----------------------------------------------------------------------------
920  -- Optional MMC compatibility counter
921  -----------------------------------------------------------------------------
922  mmc_cnt: if mmc_compat_clk_div_g > 0 generate
923    mmc_cnt_b : spi_counter
924      generic map (
925        cnt_width_g   => width_mmc_clk_div_g,
926        cnt_max_g     => mmc_compat_clk_div_g
927      )
928      port map (
929        clk_i         => clk_i,
930        reset_i       => reset_s,
931        cnt_en_i      => true_s,
932        cnt_o         => open,
933        cnt_ovfl_o    => mmc_cnt_ovfl_s
934      );
935  end generate;
936
937  no_mmc_cnt: if mmc_compat_clk_div_g = 0 generate
938    mmc_cnt_ovfl_s <= true;
939  end generate;
940
941
942  -----------------------------------------------------------------------------
943  -- Output Mapping
944  -----------------------------------------------------------------------------
945  spi_clk_o      <=   spi_clk_q;
946  spi_cs_n_o     <=   spi_cs_n_q;
947  spi_data_out_o <=   spi_dat_q;
948  spi_en_outs_o  <=   '1'
949                    when en_outs_q else
950                      '0';
951  cfg_clk_o      <= cfg_clk_q;
952  cfg_dat_o      <= cfg_dat_q;
953  detached_o     <=   '0'
954                    when en_outs_q else
955                      '1';
956
957end rtl;
Note: See TracBrowser for help on using the repository browser.