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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [sim/] [ata_device.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
-----------------------------------------------------------------------------
19
-- Entity: ata_device 
20
-- File: ata_device.vhd
21
-- Author: Erik Jagres, Gaisler Research
22
-- Description: Simulation of ATA device
23
------------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
library grlib;
28
use grlib.stdlib.all;
29
library gaisler;
30
use gaisler.sim.all;
31
 
32
--************************ENTITY************************************************
33
 
34
Entity ata_device is
35
generic(sector_length: integer :=512; --in bytes
36
        disk_size: integer :=32; --in sectors
37
        log2_size : integer :=14; --Log2(sector_length*disk_size), abits
38
        Tlr : time := 35 ns
39
        );
40
port(
41
  --for convinience, not part of ATA interface
42
  clk   : in std_logic;
43
  rst   : in std_logic;
44
 
45
  --interface to host bus adapter
46
  d     : inout std_logic_vector(15 downto 0) := (others=>'Z');
47
  atai  : in  ata_in_type := ATAI_RESET_VECTOR;
48
  atao  : out ata_out_type:= ATAO_RESET_VECTOR);
49
end;
50
 
51
--************************ARCHITECTURE******************************************
52
Architecture behaveioral of ata_device is
53
 
54
type mem_reg_type is record
55
  a  : std_logic_vector(9 downto 0);    --word adress
56
  d  : std_logic_vector(15 downto 0);   --data
57
  lb : std_logic;                       --low byte access (active low)
58
  ub : std_logic;                       --upper byte access (active low)
59
  ce : std_logic;                       --chip enable (active low)
60
  we : std_logic;                       --write enable (active low)
61
  oe : std_logic;                       --output enable (active low)
62
end record;
63
 
64
constant MEM_RESET_VECTOR : mem_reg_type := ((others=>'0'),
65
  (others=>'0'),'1','1','1','1','1');
66
 
67
constant CS1 : integer := 4;
68
constant CS0 : integer := 3;
69
 
70
--status bits
71
constant BSY : integer := 7;
72
constant DRQ : integer := 3;
73
 
74
--control bits
75
constant NIEN : integer := 1;
76
 
77
--commands
78
constant READ : std_logic_vector(7 downto 0):=X"20";
79
constant WRITE : std_logic_vector(7 downto 0):=X"30";
80
constant WRITE_DMA : std_logic_vector(7 downto 0):=X"CA";
81
constant READ_DMA : std_logic_vector(7 downto 0):=X"C8";
82
 
83
constant  ALTSTAT : std_logic_vector(4 downto 0):="10110";
84
constant  CMD     : std_logic_vector(4 downto 0):="01111";
85
constant  CHR     : std_logic_vector(4 downto 0):="01101";
86
constant  CLR     : std_logic_vector(4 downto 0):="01100";
87
constant  DTAR    : std_logic_vector(4 downto 0):="01000";
88
constant  DTAP    : std_logic_vector(4 downto 0):="00000"; --only CSx used
89
constant  CTRL    : std_logic_vector(4 downto 0):="10110";
90
constant  DHR     : std_logic_vector(4 downto 0):="01110";
91
constant  ERR     : std_logic_vector(4 downto 0):="01001"; --read only
92
constant  FEAT    : std_logic_vector(4 downto 0):=ERR; --write only
93
constant  SCR     : std_logic_vector(4 downto 0):="01010";
94
constant  SNR     : std_logic_vector(4 downto 0):="01011";
95
constant  STAT    : std_logic_vector(4 downto 0):="01111";
96
 
97
constant sramfile  : string := "disk.srec";  -- ram contents
98
constant w_adr: integer := log2(sector_length)-1; --word adress bits (within sector)
99
 
100
type ram_type is record
101
  a : std_logic_vector(log2_size-2 downto 0);
102
  ce : std_logic;
103
  we : std_ulogic;
104
  oe : std_ulogic;
105
end record;
106
 
107
constant RAM_RESET_VECTOR : ram_type := ((others=>'0'),'0','0','0');
108
 
109
type ata_reg_type is record                     --ATA task file
110
  altstat : std_logic_vector(7 downto 0);        --Alternate Status register
111
  cmd     : std_logic_vector(7 downto 0);        --Command register
112
  chr     : std_logic_vector(7 downto 0);        --Cylinder High register
113
  clr     : std_logic_vector(7 downto 0);        --Cylinder Low register
114
  dtar    : std_logic_vector(15 downto 0);       --Data register
115
  dtap    : std_logic_vector(15 downto 0);       --Data port
116
  ctrl    : std_logic_vector(7 downto 0);        --Device Control register
117
  dhr     : std_logic_vector(7 downto 0);        --Device/Head register
118
  err     : std_logic_vector(7 downto 0);        --Error register
119
  feat    : std_logic_vector(7 downto 0);        --Features register
120
  scr     : std_logic_vector(7 downto 0);        --Sector Count register
121
  snr     : std_logic_vector(7 downto 0);        --Sector Number register
122
  stat    : std_logic_vector(7 downto 0);        --Status register
123
end record;
124
 
125
constant ATA_RESET_VECTOR : ata_reg_type := ((others=>'0'),
126
  (others=>'0'),(others=>'0'),
127
  (others=>'0'),(others=>'0'),
128
  (others=>'0'),(others=>'0'),
129
  (others=>'0'),(others=>'0'),
130
  (others=>'0'),(others=>'0'),
131
  (others=>'0'),(others=>'0'));
132
 
133
type reg_type is record
134
  cmd_started : boolean;
135
  dtap_written : boolean;
136
  dtar_written : boolean;
137
  dtap_read : boolean;
138
  dtar_read : boolean;
139
  firstadr : boolean;
140
  dior : std_logic;
141
  diow : std_logic;
142
  regadr : std_logic_vector(4 downto 0);
143
  byte_cnt : integer;
144
  offset : integer;
145
  intrq : boolean;
146
  pio_started : boolean;
147
  tf : ata_reg_type;
148
  ram : ram_type;
149
  ram_dta : std_logic_vector(15 downto 0);
150
  scr : std_logic_vector(7 downto 0);
151
end record;
152
 
153
constant REG_RESET_VECTOR : reg_type := (false,false,false,false,false,true,
154
  '1','1',(others=>'0'),0,0,false,false,ATA_RESET_VECTOR,RAM_RESET_VECTOR,
155
  (others=>'0'),(others=>'0'));
156
 
157
signal r,ri : reg_type := REG_RESET_VECTOR;
158
signal s_d : std_logic_vector(15 downto 0) := (others=>'0');
159
 
160
begin
161
  comb: process(atai,r,s_d,rst)
162
  variable v : reg_type:= REG_RESET_VECTOR;
163
  begin
164
    if (rst='0') then
165
      v:=REG_RESET_VECTOR;
166
      d<=(others=>'Z');
167
      atao.intrq<='0';
168
      atao.dmarq<='0';
169
    else
170
      v:=r;
171
 
172
      v.dior:=atai.dior; v.diow:=atai.diow;
173
 
174
      v.regadr(CS1):=not(atai.cs(1)); v.regadr(CS0):=not(atai.cs(0)); --CS active l
175
      v.regadr(2 downto 0):=atai.da(2 downto 0);
176
 
177
      --fix for adressing dtap
178
      if (v.regadr(4 downto 3)="00") then
179
        v.regadr(2 downto 0):="000";
180
      end if;
181
 
182
      --*********************************READ/WRITE registers*****************
183
      if (atai.dior='1' and atai.diow='1' and r.diow='0') then --write register
184
        case v.regadr is
185
          when CMD     => v.tf.cmd:=d(7 downto 0);
186
            v.cmd_started:=true;
187
            v.tf.stat(BSY):='1';
188
            v.tf.feat:="00001111";
189
            v.byte_cnt:=0;
190
            atao.dmarq<='0'; -----------------------------------erik 2006-10-17
191
          when CHR     => v.tf.chr:=d(7 downto 0);
192
          when CLR     => v.tf.clr:=d(7 downto 0);
193
          when DTAR    => v.tf.dtar:=d(15 downto 0);
194
            v.dtar_written:=true;
195
          when CTRL    => v.tf.ctrl:=d(7 downto 0);
196
          when DHR     => v.tf.dhr:=d(7 downto 0);
197
          when FEAT    => v.tf.feat:=d(7 downto 0);
198
          when SCR     => v.tf.scr:=d(7 downto 0); v.scr:=d(7 downto 0);
199
          when SNR     => v.tf.snr:=d(7 downto 0);
200
          when DTAP    => v.tf.dtap:=d(15 downto 0);
201
            v.dtap_written:=true;
202
          when others => v.tf.stat:=d(7 downto 0);
203
        end case;
204
 
205
      elsif (atai.dior='0' and r.dior='1' and atai.diow='1') then --read register
206
        case v.regadr is
207
          when ALTSTAT => d(7 downto 0)<=r.tf.altstat; d(15 downto 8)<="00000000";
208
          when CHR     => d(7 downto 0)<=r.tf.chr; d(15 downto 8)<="00000000";
209
          when CLR     => d(7 downto 0)<=r.tf.clr; d(15 downto 8)<="00000000";
210
          when DTAR    => d<=r.tf.dtar; v.dtar_read:=true;
211
          when DHR     => d(7 downto 0)<=r.tf.dhr; d(15 downto 8)<="00000000";
212
          when ERR     => d(7 downto 0)<=r.tf.err; d(15 downto 8)<="00000000";
213
          when SCR     => d(7 downto 0)<=r.tf.scr; d(15 downto 8)<="00000000";
214
          when SNR     => d(7 downto 0)<=r.tf.snr; d(15 downto 8)<="00000000";
215
          when STAT    => d(7 downto 0)<=r.tf.stat; d(15 downto 8)<="00000000";
216
            atao.intrq<='0'; v.intrq:=false;
217
          when DTAP    =>
218
            d<=r.tf.dtap; v.dtap_read:=true;
219
            if (v.byte_cnt+2=sector_length) then
220
              atao.dmarq<='0' after Tlr;
221
            end if;
222
 
223
          when others => d(15 downto 0)<=(others=>'Z');
224
        end case;
225
        --*********************************READ/WRITE registers end*************
226
 
227
      else
228
 
229
        if (r.tf.stat(BSY)='1') then        --simulate busy, "borrow" feat reg
230
          v.tf.feat:=v.tf.feat-1;           --count down timer
231
          if (v.tf.feat="00000000") then
232
            v.tf.stat(BSY):='0';             --clear busy flag
233
          end if;
234
        elsif(v.cmd_started) then
235
          case r.tf.cmd is
236
            --********************************************************************
237
            when WRITE_DMA =>
238
              atao.dmarq<='1';
239
              v.tf.stat(DRQ):='1';
240
              if v.dtap_written then
241
                v.dtap_written:=false;
242
                v.byte_cnt:=v.byte_cnt+2;
243
                if(v.byte_cnt=sector_length) then
244
                  v.tf.scr:=v.tf.scr-1;
245
                  v.byte_cnt:=0;
246
                  if v.tf.scr=X"00" then
247
                    atao.dmarq<='0';
248
                    v.tf.stat(DRQ):='0';
249
                    v.cmd_started:=false;
250
                    if v.tf.ctrl(NIEN)='0' then
251
                      atao.intrq<='1';
252
                    end if;
253
                  end if;
254
                end if;
255
                if r.dtap_written then
256
                  v.ram.a(log2_size-2 downto log2(sector_length)-1):=
257
                  r.scr((log2_size-log2(sector_length)-1) downto 0) - r.tf.scr((log2_size-log2(sector_length)-1) downto 0);
258
                  v.ram.a(log2(sector_length)-2 downto 0):=
259
                  conv_std_logic_vector((r.byte_cnt/2),log2(sector_length)-1);
260
                  v.ram_dta:=v.tf.dtap; v.ram.oe:='1'; v.ram.ce:='0';v.ram.we:='0';
261
                end if;
262
              end if;
263
            --********************************************************************            
264
            when WRITE     =>
265
              if (not v.pio_started and v.tf.ctrl(NIEN)='0') then
266
                atao.intrq<='1'; v.pio_started:=true; v.intrq:=true;
267
              elsif not v.intrq then
268
                v.tf.stat(DRQ):='1';
269
                if v.dtar_written then
270
                  v.dtar_written:=false;
271
                  v.byte_cnt:=v.byte_cnt+2;
272
                  if(v.byte_cnt=sector_length) then
273
                    v.tf.scr:=v.tf.scr-1;
274
                    if (v.tf.scr=X"00") then
275
                      v.cmd_started:=false; v.pio_started:=false;
276
                    end if;
277
                    v.byte_cnt:=0;
278
                    v.tf.stat(DRQ):='0';
279
                    v.tf.stat(BSY):='1';
280
                    v.tf.feat:="00001111";
281
                    if v.tf.ctrl(NIEN)='0' then
282
                      atao.intrq<='1';
283
                    end if;
284
                  end if;
285
                end if;
286
                if r.dtar_written then
287
                  v.ram.a(log2_size-2 downto log2(sector_length)-1):=
288
                  r.scr((log2_size-log2(sector_length)-1) downto 0) - r.tf.scr((log2_size-log2(sector_length)-1) downto 0);
289
                  v.ram.a(log2(sector_length)-2 downto 0):=
290
                  conv_std_logic_vector((r.byte_cnt/2),log2(sector_length)-1);
291
                  v.ram_dta:=v.tf.dtar; v.ram.oe:='1'; v.ram.ce:='0';v.ram.we:='0';
292
                end if;
293
              end if;
294
            --********************************************************************
295
            when READ_DMA  =>
296
--              atao.dmarq<='1';
297
              v.tf.stat(DRQ):='1';
298
              if not (v.byte_cnt+2=sector_length) then
299
                atao.dmarq<='1';
300
              end if;
301
              if v.dtap_read and r.dior='0' and atai.dior='1' then --rising dior detect
302
                v.dtap_read:=false;
303
                v.byte_cnt:=v.byte_cnt+2;
304
                if(v.byte_cnt=sector_length) then
305
                  v.tf.scr:=v.tf.scr-1;
306
                  v.byte_cnt:=0;
307
                  if v.tf.scr=X"00" then
308
--                    atao.dmarq<='0';
309
                    v.tf.stat(DRQ):='0';
310
                    v.cmd_started:=false;
311
                      v.ram.oe:='1'; v.ram.ce:='1';v.ram.we:='1';
312
                    if v.tf.ctrl(NIEN)='0' then
313
                      atao.intrq<='1';
314
                    end if;
315
                  end if;
316
                end if;
317
              end if;
318
              v.ram.oe:='0'; v.ram.ce:='0';v.ram.we:='1'; v.tf.dtap:=s_d;
319
                  v.ram.a(log2_size-2 downto log2(sector_length)-1):=
320
                  r.scr((log2_size-log2(sector_length)-1) downto 0) - r.tf.scr((log2_size-log2(sector_length)-1) downto 0);
321
                  v.ram.a(log2(sector_length)-2 downto 0):=
322
                  conv_std_logic_vector((r.byte_cnt/2),log2(sector_length)-1);
323
            --********************************************************************
324
            when READ =>
325
              if (not v.pio_started and v.tf.ctrl(NIEN)='0') then
326
                atao.intrq<='1'; v.pio_started:=true; v.intrq:=true;
327
              elsif not v.intrq then
328
                v.tf.stat(DRQ):='1';
329
                if v.dtar_read and r.dior='0' and atai.dior='1' then --rising dior detect
330
                  v.dtar_read:=false;
331
                  v.byte_cnt:=v.byte_cnt+2;
332
                  if(v.byte_cnt=sector_length) then
333
                    v.tf.scr:=v.tf.scr-1;
334
                    if (v.tf.scr=X"00") then
335
                      v.cmd_started:=false;
336
                    end if;
337
                    v.byte_cnt:=0;
338
                    v.tf.stat(DRQ):='0';
339
                    v.tf.stat(BSY):='1';
340
                    v.tf.feat:="00001111";
341
                    if v.tf.ctrl(NIEN)='0' then
342
                      atao.intrq<='1';
343
                    end if;
344
                  end if;
345
                end if;
346
              end if;
347
              v.ram.oe:='0'; v.ram.ce:='0';v.ram.we:='1'; v.tf.dtar:=s_d;
348
                  v.ram.a(log2_size-2 downto log2(sector_length)-1):=
349
                  r.scr((log2_size-log2(sector_length)-1) downto 0) - r.tf.scr((log2_size-log2(sector_length)-1) downto 0);
350
                  v.ram.a(log2(sector_length)-2 downto 0):=
351
                  conv_std_logic_vector((r.byte_cnt/2),log2(sector_length)-1);
352
            --********************************************************************
353
            when others => v.tf.stat:=v.tf.stat; v.cmd_started:=false;
354
          end case;
355
        end if;
356
 
357
        if r.ram.ce='0' and r.ram.oe='1' then
358
          v.ram.oe:='1'; v.ram.ce:='1';v.ram.we:='1'; v.ram_dta:=(others=>'Z');
359
        end if;
360
 
361
        if (r.dior='0' and atai.dior='1') then
362
          d(15 downto 0)<=(others=>'Z');
363
        end if;
364
 
365
      end if; --read write reg
366
    end if; --reset
367
 
368
    ri<=v;
369
  end process comb;
370
 
371
  with r.ram.oe select
372
    s_d<=r.ram_dta when '1',
373
         (others=>'Z') when others;
374
 
375
  disk : sram16 generic map (index => 0, abits => log2_size-1, fname => sramfile)
376
        port map (r.ram.a, s_d, '0', '0', r.ram.ce, r.ram.we, r.ram.oe);
377
 
378
  --**********************SYNC PROCESS******************************************
379
  sync: process(clk) --dior/diow insted?
380
  begin
381
    if rising_edge(clk) then
382
      r<=ri;
383
    end if;
384
  end process sync;
385
end;
386
 
387
--************************END OF FILE*******************************************

powered by: WebSVN 2.1.0

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