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

Subversion Repositories sata_controller_core

[/] [sata_controller_core/] [trunk/] [sata2_bus_v1_00_a/] [base_system/] [pcores/] [sata_core_v1_00_a/] [hdl/] [vhdl/] [command_layer.vhd] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 ashwin_men
-- Copyright (C) 2012
2
-- Ashwin A. Mendon
3
--
4
-- This file is part of SATA2 core.
5
--
6
-- This program is free software; you can redistribute it and/or modify
7
-- it under the terms of the GNU General Public License as published by
8
-- the Free Software Foundation; either version 3 of the License, or
9
-- (at your option) any later version.
10
--
11
-- This program is distributed in the hope that it will be useful,
12
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
-- GNU General Public License for more details.
15
--
16
-- You should have received a copy of the GNU General Public License
17
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.  
18
 
19
----------------------------------------------------------------------------------------
20
-- ENTITY: command_layer 
21
-- Version: 1.0
22
-- Author:  Ashwin Mendon 
23
-- Description: This sub-module implements the Command Layer of the SATA Protocol
24
--              The User Command parameters such as: cmd_type, sector_address, sector_count
25
--              are encoded into a command FIS according to the ATA format and passed to
26
--              the Transport Layer.                   
27
--              
28
-- PORTS: 
29
-----------------------------------------------------------------------------------------
30
 
31
 
32
library IEEE;
33
use IEEE.STD_LOGIC_1164.all;
34
use IEEE.STD_LOGIC_ARITH.all;
35
use IEEE.STD_LOGIC_UNSIGNED.all;
36
 
37
entity command_layer is
38
  generic(
39
    CHIPSCOPE           : boolean := false
40
       );
41
  port(
42
     -- Clock and Reset Signals
43
    clk                   : in  std_logic;
44
    sw_reset              : in  std_logic;
45
    -- ChipScope ILA / Trigger Signals
46
    cmd_layer_ila_control  : in  std_logic_vector(35 downto 0);
47
    ---------------------------------------
48
    -- Signals from/to User Logic
49
    new_cmd               : in  std_logic;
50
    cmd_done              : out std_logic;
51
    cmd_type              : in  std_logic_vector(1 downto 0);
52
    sector_count          : in  std_logic_vector(31 downto 0);
53
    sector_addr           : in  std_logic_vector(31 downto 0);
54
    user_din              : in  std_logic_vector(31 downto 0);
55
    user_din_re_out       : out std_logic;
56
    user_dout             : out std_logic_vector(31 downto 0);
57
    user_dout_re          : in std_logic;
58
    user_fifo_empty       : in std_logic;
59
    user_fifo_full        : in std_logic;
60
    sector_timer_out      : out std_logic_vector(31 downto 0);
61
    -- Signals from/to Link Layer
62
    write_fifo_full       : in std_logic;
63
    ll_ready_for_cmd      : in std_logic;
64
    ll_cmd_start          : out std_logic;
65
    ll_cmd_type           : out std_logic_vector(1 downto 0);
66
    ll_dout               : out std_logic_vector(31 downto 0);
67
    ll_dout_we            : out std_logic;
68
    ll_din                : in  std_logic_vector(31 downto 0);
69
    ll_din_re             : out  std_logic
70
      );
71
end command_layer;
72
 
73
-------------------------------------------------------------------------------
74
-- ARCHITECTURE
75
-------------------------------------------------------------------------------
76
architecture BEHAV of command_layer is
77
 
78
 -------------------------------------------------------------------------------
79
 -- COMMAND LAYER
80
 -------------------------------------------------------------------------------
81
  constant READ_DMA         : std_logic_vector(7 downto 0) := x"25";
82
  constant WRITE_DMA        : std_logic_vector(7 downto 0) := x"35";
83
  constant REG_FIS_VALUE    : std_logic_vector(7 downto 0) := x"27";
84
  constant DATA_FIS_VALUE   : std_logic_vector(7 downto 0) := x"46";
85
  constant DEVICE_REG       : std_logic_vector(7 downto 0) := x"E0";
86
  constant FEATURES         : std_logic_vector(7 downto 0) := x"00";
87
  constant READ_DMA_CMD     : std_logic_vector(1 downto 0) := "01";
88
  constant WRITE_DMA_CMD    : std_logic_vector(1 downto 0) := "10";
89
  constant DATA_FIS_HEADER  : std_logic_vector(31 downto 0) := x"00000046";
90
  constant NDWORDS_PER_DATA_FIS : std_logic_vector(15 downto 0) := conv_std_logic_vector(2048, 16);--128*16       
91
  constant SECTOR_NDWORDS     : integer := 128;  -- 128 DWORDS / 512 Byte Sector    
92
 
93
  component cmd_layer_ila
94
    port (
95
      control : in std_logic_vector(35 downto 0);
96
      clk     : in std_logic;
97
      trig0   : in std_logic_vector(3  downto 0);
98
      trig1   : in std_logic_vector(31 downto 0);
99
      trig2   : in std_logic_vector(31 downto 0);
100
      trig3   : in std_logic_vector(31 downto 0);
101
      trig4   : in std_logic_vector(31 downto 0);
102
      trig5   : in std_logic_vector(1 downto 0);
103
      trig6   : in std_logic_vector(1 downto 0);
104
      trig7   : in std_logic_vector(31 downto 0);
105
      trig8   : in std_logic_vector(31 downto 0);
106
      trig9   : in std_logic_vector(23 downto 0);
107
      trig10  : in std_logic_vector(15 downto 0);
108
      trig11  : in std_logic_vector(11 downto 0);
109
      trig12  : in std_logic_vector(15 downto 0);
110
      trig13  : in std_logic_vector(31 downto 0)
111
   );
112
  end component;
113
 
114
 
115
 -----------------------------------------------------------------------------
116
  -- Finite State Machine Declaration (curr and next states)
117
 -----------------------------------------------------------------------------
118
  type COMMAND_FSM_TYPE is (wait_for_cmd, build_REG_FIS, send_REG_FIS_DW1,
119
                           send_REG_FIS_DW2, send_REG_FIS_DW3, send_REG_FIS_DW4, send_REG_FIS_DW5,
120
                           send_DATA_FIS_HEADER, send_write_data, send_cmd_start, wait_for_cmd_start,
121
                           wait_for_cmd_done, dead
122
                     );
123
  signal command_fsm_curr, command_fsm_next : COMMAND_FSM_TYPE := wait_for_cmd;
124
  signal command_fsm_value                  : std_logic_vector (0 to 3);
125
 
126
  signal ll_cmd_start_next                 : std_logic;
127
  signal ll_cmd_start_out                  : std_logic;
128
  signal cmd_done_next                  : std_logic;
129
  signal cmd_done_out                   : std_logic;
130
  signal read_fifo_empty                : std_logic;
131
  signal ll_dout_next                   : std_logic_vector(0 to 31);
132
  signal ll_dout_we_next                : std_logic;
133
  signal ll_dout_out                    : std_logic_vector(0 to 31);
134
  signal ll_dout_we_out                 : std_logic;
135
  signal ll_cmd_type_next               : std_logic_vector(0 to 1);
136
  signal ll_cmd_type_out                : std_logic_vector(0 to 1);
137
  signal dword_count                    : std_logic_vector(0 to 15);
138
  signal dword_count_next               : std_logic_vector(0 to 15);
139
  signal write_data_count               : std_logic_vector(0 to 31);
140
  signal write_data_count_next          : std_logic_vector(0 to 31);
141
  signal user_din_re                    : std_logic;
142
  signal sector_count_int               : integer;
143
 
144
  --- ILA signals ----
145
  signal user_dout_ila                  : std_logic_vector(0 to 31);
146
  signal ll_din_re_ila                  : std_logic;
147
 
148
  --- Timer ----
149
  signal sector_timer                   : std_logic_vector(31 downto 0);
150
  --signal sata_timer                     : std_logic_vector(31 downto 0);
151
 
152
  type reg_fis_type is
153
    record
154
      FIS_type      : std_logic_vector(7 downto 0);
155
      pad_8         : std_logic_vector(7 downto 0);
156
      command       : std_logic_vector(7 downto 0);
157
      features      : std_logic_vector(7 downto 0);
158
      LBA           : std_logic_vector(23 downto 0);
159
      device        : std_logic_vector(7 downto 0);
160
      LBA_exp       : std_logic_vector(23 downto 0);
161
      features_exp  : std_logic_vector(7 downto 0);
162
      sector_count  : std_logic_vector(15 downto 0);
163
      pad_16        : std_logic_vector(15 downto 0);
164
      pad_32        : std_logic_vector(31 downto 0);
165
    end record;
166
 
167
  signal reg_fis   : reg_fis_type;
168
  signal reg_fis_next   : reg_fis_type;
169
 
170
-------------------------------------------------------------------------------
171
-- BEGIN
172
-------------------------------------------------------------------------------
173
begin
174
 
175
-------------------------------------------------------------------------------
176
-- LINK LAYER
177
-------------------------------------------------------------------------------
178
  -----------------------------------------------------------------------------
179
  -- PROCESS: COMMAND_FSM_VALUE_PROC
180
  -- PURPOSE: ChipScope State Indicator Signal
181
  -----------------------------------------------------------------------------
182
  COMMAND_FSM_VALUE_PROC : process (command_fsm_curr) is
183
  begin
184
    case (command_fsm_curr) is
185
      when wait_for_cmd       => command_fsm_value <= x"0";
186
      when build_REG_FIS      => command_fsm_value <= x"1";
187
      when send_REG_FIS_DW1   => command_fsm_value <= x"2";
188
      when send_REG_FIS_DW2   => command_fsm_value <= x"3";
189
      when send_REG_FIS_DW3   => command_fsm_value <= x"4";
190
      when send_REG_FIS_DW4   => command_fsm_value <= x"5";
191
      when send_REG_FIS_DW5   => command_fsm_value <= x"6";
192
      when send_DATA_FIS_HEADER => command_fsm_value <= x"7";
193
      when send_write_data    => command_fsm_value <= x"8";
194
      when send_cmd_start     => command_fsm_value <= x"9";
195
      when wait_for_cmd_start => command_fsm_value <= x"A";
196
      when wait_for_cmd_done  => command_fsm_value <= x"B";
197
      when dead               => command_fsm_value <= x"C";
198
      when others             => command_fsm_value <= x"D";
199
    end case;
200
  end process COMMAND_FSM_VALUE_PROC;
201
 
202
  -----------------------------------------------------------------------------
203
  -- PROCESS: COMMAND_FSM_STATE_PROC
204
  -- PURPOSE: Registering Signals and Next State
205
  -----------------------------------------------------------------------------
206
  COMMAND_FSM_STATE_PROC: process (clk)
207
  begin
208
    if ((clk'event) and (clk = '1')) then
209
      if (sw_reset = '1') then
210
        --Initializing internal signals
211
        command_fsm_curr       <= wait_for_cmd;
212
        cmd_done_out           <= '0';
213
        ll_cmd_start_out       <= '0';
214
        ll_dout_we_out         <= '0';
215
        ll_dout_out            <= (others => '0');
216
        ll_cmd_type_out        <= (others => '0');
217
        write_data_count       <= (others => '0');
218
        dword_count            <= (others => '0');
219
        reg_fis.FIS_type       <= (others => '0');
220
        reg_fis.pad_8          <= (others => '0');
221
        reg_fis.command        <= (others => '0');
222
        reg_fis.features       <= (others => '0');
223
        reg_fis.LBA            <= (others => '0');
224
        reg_fis.device         <= (others => '0');
225
        reg_fis.LBA_exp        <= (others => '0');
226
        reg_fis.features_exp   <= (others => '0');
227
        reg_fis.sector_count   <= (others => '0');
228
        reg_fis.pad_16         <= (others => '0');
229
        reg_fis.pad_32         <= (others => '0');
230
      else
231
        -- Register all Current Signals to their _next Signals
232
        command_fsm_curr       <= command_fsm_next;
233
        cmd_done_out           <= cmd_done_next;
234
        ll_cmd_start_out       <= ll_cmd_start_next;
235
        ll_dout_we_out         <= ll_dout_we_next;
236
        ll_dout_out            <= ll_dout_next;
237
        ll_cmd_type_out        <= ll_cmd_type_next;
238
        dword_count            <= dword_count_next;
239
        write_data_count       <= write_data_count_next;
240
        reg_fis.FIS_type       <= reg_fis_next.FIS_type ;
241
        reg_fis.pad_8          <= reg_fis_next.pad_8;
242
        reg_fis.command        <= reg_fis_next.command;
243
        reg_fis.features       <= reg_fis_next.features;
244
        reg_fis.LBA            <= reg_fis_next.LBA;
245
        reg_fis.device         <= reg_fis_next.device;
246
        reg_fis.LBA_exp        <= reg_fis_next.LBA_exp;
247
        reg_fis.features_exp   <= reg_fis_next.features_exp;
248
        reg_fis.sector_count   <= reg_fis_next.sector_count;
249
        reg_fis.pad_16         <= reg_fis_next.pad_16;
250
        reg_fis.pad_32         <= reg_fis_next.pad_32;
251
      end if;
252
    end if;
253
  end process COMMAND_FSM_STATE_PROC;
254
 
255
  -----------------------------------------------------------------------------
256
  -- PROCESS: COMMAND_FSM_LOGIC_PROC 
257
  -- PURPOSE: Registering Signals and Next State
258
  -----------------------------------------------------------------------------
259
  COMMAND_FSM_LOGIC_PROC : process (command_fsm_curr, new_cmd, cmd_type,
260
                                   ll_cmd_start_out, ll_dout_we_out,
261
                                   ll_dout_out, dword_count, write_data_count
262
                                   ) is
263
  begin
264
    -- Register _next to current signals
265
    command_fsm_next          <= command_fsm_curr;
266
    cmd_done_next             <= cmd_done_out;
267
    ll_cmd_start_next         <= ll_cmd_start_out;
268
    ll_dout_we_next           <= ll_dout_we_out;
269
    ll_dout_next              <= ll_dout_out;
270
    ll_cmd_type_next          <= cmd_type;
271
    user_din_re               <= '0';
272
    dword_count_next          <= dword_count;
273
    write_data_count_next     <= write_data_count;
274
    reg_fis_next.FIS_type     <= reg_fis.FIS_type ;
275
    reg_fis_next.pad_8        <= reg_fis.pad_8;
276
    reg_fis_next.command      <= reg_fis.command;
277
    reg_fis_next.features     <= reg_fis.features;
278
    reg_fis_next.LBA          <= reg_fis.LBA;
279
    reg_fis_next.device       <= reg_fis.device;
280
    reg_fis_next.LBA_exp      <= reg_fis.LBA_exp;
281
    reg_fis_next.features_exp <= reg_fis.features_exp;
282
    reg_fis_next.sector_count <= reg_fis.sector_count;
283
    reg_fis_next.pad_16       <= reg_fis.pad_16;
284
    reg_fis_next.pad_32       <= reg_fis.pad_32;
285
 
286
    ---------------------------------------------------------------------------
287
    -- Finite State Machine
288
    ---------------------------------------------------------------------------
289
    case (command_fsm_curr) is
290
 
291
     -- x0
292
     when wait_for_cmd =>
293
         cmd_done_next     <= '1';
294
         ll_cmd_start_next    <= '0';
295
         ll_dout_we_next   <= '0';
296
         ll_dout_next      <= (others => '0');
297
         if (new_cmd = '1') then
298
            cmd_done_next     <= '0';
299
            command_fsm_next  <= build_REG_FIS;
300
         end if;
301
 
302
     -- x1
303
     when build_REG_FIS =>
304
          reg_fis_next.FIS_type      <= REG_FIS_VALUE;
305
          reg_fis_next.pad_8         <= x"80";
306
          if (cmd_type = READ_DMA_CMD) then
307
             reg_fis_next.command    <= READ_DMA;
308
          else
309
             reg_fis_next.command    <= WRITE_DMA;
310
          end if;
311
          reg_fis_next.features      <= FEATURES;
312
          reg_fis_next.LBA           <= sector_addr(23 downto 0);
313
          reg_fis_next.device        <= DEVICE_REG;
314
          reg_fis_next.LBA_exp       <= (others => '0');
315
          reg_fis_next.features_exp  <= FEATURES;
316
          reg_fis_next.sector_count  <= sector_count(15 downto 0);
317
          reg_fis_next.pad_16        <= (others => '0');
318
          reg_fis_next.pad_32        <= (others => '0');
319
          command_fsm_next           <= send_REG_FIS_DW1;
320
 
321
     -- x2
322
     when send_REG_FIS_DW1 =>
323
          ll_dout_next         <= reg_fis.FEATURES & reg_fis.command & reg_fis.pad_8 & reg_fis.FIS_type;
324
          ll_dout_we_next      <= '1';
325
          command_fsm_next     <= send_REG_FIS_DW2;
326
 
327
     -- x3
328
     when send_REG_FIS_DW2 =>
329
          ll_dout_next         <= reg_fis.device & reg_fis.LBA;
330
          ll_dout_we_next      <= '1';
331
          command_fsm_next     <= send_REG_FIS_DW3;
332
 
333
     -- x4
334
     when send_REG_FIS_DW3 =>
335
          ll_dout_next         <= reg_fis.features_exp & reg_fis.LBA_exp;
336
          ll_dout_we_next      <= '1';
337
          command_fsm_next     <= send_REG_FIS_DW4;
338
 
339
     -- x5
340
     when send_REG_FIS_DW4 =>
341
          ll_dout_next         <= reg_fis.pad_16 & reg_fis.sector_count ;
342
          ll_dout_we_next      <= '1';
343
          command_fsm_next     <= send_REG_FIS_DW5;
344
 
345
     -- x6
346
     when send_REG_FIS_DW5 =>
347
          ll_dout_next         <= reg_fis.pad_32;
348
          ll_dout_we_next      <= '1';
349
          command_fsm_next  <= send_cmd_start;
350
 
351
     -- x7
352
     when send_DATA_FIS_HEADER =>
353
          if (user_fifo_full = '1') then
354
             ll_dout_next         <= DATA_FIS_HEADER;
355
             ll_dout_we_next      <= '1';
356
             command_fsm_next     <= send_write_data;
357
          end if;
358
 
359
     -- x8
360
     when send_write_data =>
361
          if(dword_count >= NDWORDS_PER_DATA_FIS) then
362
            user_din_re        <= '0';
363
            ll_dout_we_next    <= '0';
364
            ll_dout_next       <= (others => '0');
365
            dword_count_next   <= (others => '0');
366
            command_fsm_next   <= send_DATA_FIS_HEADER;
367
          elsif (write_fifo_full = '1' or user_fifo_empty = '1') then
368
            user_din_re        <= '0';
369
            ll_dout_we_next    <= '0';
370
            ll_dout_next       <= (others => '0');
371
          else
372
            write_data_count_next <= write_data_count + 1;
373
            dword_count_next   <= dword_count + 1;
374
            user_din_re        <= '1';
375
            ll_dout_next       <= user_din;
376
            ll_dout_we_next    <= '1';
377
          end if;
378
 
379
          if (write_data_count = (SECTOR_NDWORDS*sector_count_int)) then
380
             write_data_count_next <= (others => '0');
381
             dword_count_next   <= (others => '0');
382
             user_din_re        <= '0';
383
             ll_dout_we_next    <= '0';
384
             ll_dout_next       <= (others => '0');
385
             command_fsm_next   <= wait_for_cmd_done;
386
          end if;
387
 
388
     -- x9
389
     when send_cmd_start =>
390
          ll_dout_we_next   <= '0';
391
          ll_dout_next      <= (others => '0');
392
          if (ll_ready_for_cmd = '1') then
393
            ll_cmd_start_next           <= '1';
394
            command_fsm_next         <= wait_for_cmd_start;
395
          end if;
396
 
397
     -- xA
398
     when wait_for_cmd_start =>
399
          ll_cmd_start_next           <= '0';
400
          if (ll_ready_for_cmd = '0') then
401
             if (cmd_type = READ_DMA_CMD) then
402
               command_fsm_next   <= wait_for_cmd_done;
403
             else
404
               command_fsm_next   <= send_DATA_FIS_HEADER;
405
             end if;
406
          end if;
407
 
408
     -- xB
409
     when wait_for_cmd_done =>
410
          if (ll_ready_for_cmd = '1') then
411
             cmd_done_next     <= '1';
412
             command_fsm_next      <= wait_for_cmd;
413
          end if;
414
 
415
     -- xC
416
     when dead =>
417
         command_fsm_next  <= dead;
418
 
419
     -- xD
420
     when others =>
421
         command_fsm_next  <= dead;
422
 
423
   end case;
424
 end process COMMAND_FSM_LOGIC_PROC;
425
 
426
  cmd_done         <= cmd_done_out;
427
  ll_cmd_start     <= ll_cmd_start_out;
428
  ll_cmd_type      <= ll_cmd_type_out;
429
 
430
  user_din_re_out  <= user_din_re;
431
  user_dout_ila    <= ll_din;
432
  user_dout        <= user_dout_ila;
433
  ll_dout          <= ll_dout_out;
434
  ll_dout_we       <= ll_dout_we_out;
435
  ll_din_re_ila    <= user_dout_re;
436
  ll_din_re        <= ll_din_re_ila;
437
 
438
  sector_count_int <= conv_integer(sector_count);
439
 
440
  -----------------------------------------------------------------------------
441
  -- PROCESS: TIMER PROCESS 
442
  -- PURPOSE: Count time to read a sector
443
  -----------------------------------------------------------------------------
444
  TIMER_PROC: process (clk)
445
  begin
446
    if ((clk'event) and (clk = '1')) then
447
      if (sw_reset = '1') then
448
        sector_timer    <= (others => '0');
449
     --   sata_timer      <= (others => '0');
450
      --elsif ((command_fsm_curr = wait_for_cmd_done) and (ready_for_cmd = '1')) then
451
        --sata_timer      <= sata_timer + sector_timer;
452
      elsif (command_fsm_curr = wait_for_cmd) then
453
        if (new_cmd = '1') then
454
           sector_timer    <= (others => '0');
455
        else
456
           sector_timer    <= sector_timer;
457
        end if;
458
      else
459
        sector_timer    <= sector_timer + '1';
460
      end if;
461
    end if;
462
  end process TIMER_PROC;
463
  sector_timer_out        <= sector_timer;
464
 
465
 
466
 chipscope_gen_ila : if (CHIPSCOPE) generate
467
  CMD_LAYER_ILA_i : cmd_layer_ila
468
    port map (
469
      control  => cmd_layer_ila_control,
470
      clk      => clk,
471
      trig0    => command_fsm_value,
472
      trig1    => user_din,
473
      trig2    => user_dout_ila,
474
      trig3    => ll_din,
475
      trig4    => ll_dout_out,
476
      trig5    => cmd_type,
477
      trig6    => ll_cmd_type_out,
478
      trig7    => sector_timer,
479
      trig8    => sector_addr,
480
      trig9    => reg_fis.LBA,
481
      trig10    => reg_fis.sector_count,
482
      trig11(0) => new_cmd,
483
      trig11(1) => user_din_re,
484
      trig11(2) => user_dout_re,
485
      trig11(3) => ll_ready_for_cmd,
486
      trig11(4) => ll_cmd_start_out,
487
      trig11(5) => ll_dout_we_out,
488
      trig11(6) => ll_din_re_ila,
489
      trig11(7) => cmd_done_out,
490
      trig11(8) => '0',
491
      trig11(9) => write_fifo_full,
492
      trig11(10) => user_fifo_empty,
493
      trig11(11) => user_fifo_full,
494
      trig12    => dword_count,
495
      trig13    => write_data_count
496
     );
497
 end generate chipscope_gen_ila;
498
 
499
end BEHAV;

powered by: WebSVN 2.1.0

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