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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [designs/] [leon3-avnet-3s1500/] [mctrl_avnet.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
 
2
 
3
 
4
 
5
----------------------------------------------------------------------------
6
--  This file is a part of the LEON VHDL model
7
--  Copyright (C) 1999  European Space Agency (ESA)
8
--
9
--  This library is free software; you can redistribute it and/or
10
--  modify it under the terms of the GNU Lesser General Public
11
--  License as published by the Free Software Foundation; either
12
--  version 2 of the License, or (at your option) any later version.
13
--
14
--  See the file COPYING.LGPL for the full details of the license.
15
 
16
 
17
-----------------------------------------------------------------------------
18
-- Entity:      mctrl
19
-- File:        mctrl.vhd
20
-- Author:      Jiri Gaisler - ESA/ESTEC
21
-- Description: External memory controller.
22
------------------------------------------------------------------------------
23
 
24
library ieee;
25
use ieee.std_logic_1164.all;
26
library grlib;
27
use grlib.amba.all;
28
use grlib.devices.all;
29
use grlib.stdlib.all;
30
library gaisler;
31
use gaisler.memctrl.all;
32
library esa;
33
use esa.memoryctrl.all;
34
 
35
entity mctrl_avnet is
36
  generic (
37
    hindex    : integer := 0;
38
    pindex    : integer := 0;
39
    romaddr   : integer := 16#000#;
40
    rommask   : integer := 16#E00#;
41
    ioaddr    : integer := 16#200#;
42
    iomask    : integer := 16#E00#;
43
    ramaddr   : integer := 16#400#;
44
    rammask   : integer := 16#C00#;
45
    paddr     : integer := 0;
46
    pmask     : integer := 16#fff#;
47
    wprot     : integer := 0;
48
    invclk    : integer := 0;
49
    fast      : integer := 0;
50
    romasel   : integer := 28;
51
    sdrasel   : integer := 29;
52
    srbanks   : integer := 4;
53
    ram8      : integer := 0;
54
    ram16     : integer := 0;
55
    sden      : integer := 0;
56
    sepbus    : integer := 0;
57
    sdbits    : integer := 32;
58
    sdlsb     : integer := 2;          -- set to 12 for the GE-HPE board
59
    oepol     : integer := 0;
60
    syncrst   : integer := 0;
61
    pageburst : integer := 0;
62
    avnetmezz : integer := 0
63
  );
64
  port (
65
    rst       : in  std_ulogic;
66
    clk       : in  std_ulogic;
67
    memi      : in  memory_in_type;
68
    memo      : out memory_out_type;
69
    ahbsi     : in  ahb_slv_in_type;
70
    ahbso     : out ahb_slv_out_type;
71
    apbi      : in  apb_slv_in_type;
72
    apbo      : out apb_slv_out_type;
73
    wpo       : in  wprot_out_type;
74
    sdo       : out sdram_out_type
75
  );
76
end;
77
 
78
architecture rtl of mctrl_avnet is
79
 
80
constant REVISION  : integer := 1;
81
 
82
constant prom : integer := 1;
83
constant memory : integer := 0;
84
 
85
constant hconfig : ahb_config_type := (
86
 
87
  4 => ahb_membar(romaddr, '1', '1', rommask),
88
  5 => ahb_membar(ioaddr,  '0', '0', iomask),
89
  6 => ahb_membar(ramaddr, '1', '1', rammask),
90
  others => zero32);
91
 
92
constant pconfig : apb_config_type := (
93
 
94
  1 => apb_iobar(paddr, pmask));
95
 
96
constant RAMSEL5 : boolean := srbanks = 5;
97
constant SDRAMEN : boolean := (sden /= 0);
98
constant BUS16EN : boolean := (ram16 /= 0);
99
constant BUS8EN  : boolean := (ram8 /= 0);
100
constant WPROTEN : boolean := (wprot /= 0);
101
constant WENDFB  : boolean := false;
102
constant SDSEPBUS: boolean := (sepbus /= 0);
103
constant BUS64   : boolean := (sdbits = 64);
104
 
105
constant rom : integer := 0;
106
constant io  : integer := 1;
107
constant ram : integer := 2;
108
type memcycletype is (idle, berr, bread, bwrite, bread8, bwrite8, bread16, bwrite16);
109
 
110
-- memory configuration register 1 type
111
 
112
type mcfg1type is record
113
  romrws           : std_logic_vector(3 downto 0);
114
  romwws           : std_logic_vector(3 downto 0);
115
  romwidth         : std_logic_vector(1 downto 0);
116
  romwrite         : std_logic;
117
 
118
  ioen             : std_logic;
119
  iows             : std_logic_vector(3 downto 0);
120
  bexcen           : std_logic;
121
  brdyen           : std_logic;
122
  iowidth          : std_logic_vector(1 downto 0);
123
end record;
124
 
125
-- memory configuration register 2 type
126
 
127
type mcfg2type is record
128
  ramrws           : std_logic_vector(1 downto 0);
129
  ramwws           : std_logic_vector(1 downto 0);
130
  ramwidth         : std_logic_vector(1 downto 0);
131
  rambanksz        : std_logic_vector(3 downto 0);
132
  rmw              : std_logic;
133
  brdyen           : std_logic;
134
  srdis            : std_logic;
135
  sdren            : std_logic;
136
end record;
137
 
138
-- memory status register type
139
 
140
-- local registers
141
 
142
type reg_type is record
143
  address          : std_logic_vector(31 downto 0);  -- memory address
144
  addressx         : std_logic_vector(31 downto 0);  -- shifted memory address
145
  data             : std_logic_vector(31 downto 0);  -- latched memory data
146
  writedata        : std_logic_vector(31 downto 0);
147
  writedata8       : std_logic_vector(15 downto 0);  -- lsb write data buffer
148
  sdwritedata      : std_logic_vector(63 downto 0);
149
  readdata         : std_logic_vector(31 downto 0);
150
  brdyn            : std_logic;
151
  ready            : std_logic;
152
  ready8           : std_logic;
153
  bdrive           : std_logic_vector(3 downto 0);
154
  nbdrive          : std_logic_vector(3 downto 0);
155
  ws               : std_logic_vector(3 downto 0);
156
  romsn            : std_logic_vector(1 downto 0);
157
  ramsn            : std_logic_vector(4 downto 0);
158
  ramoen           : std_logic_vector(4 downto 0);
159
  size             : std_logic_vector(1 downto 0);
160
  busw             : std_logic_vector(1 downto 0);
161
  oen              : std_logic;
162
  iosn             : std_logic_vector(1 downto 0);
163
  read             : std_logic;
164
  wrn              : std_logic_vector(3 downto 0);
165
  writen           : std_logic;
166
  bstate           : memcycletype;
167
  area             : std_logic_vector(0 to 2);
168
  mcfg1            : mcfg1type;
169
  mcfg2            : mcfg2type;
170
  bexcn            : std_logic;         -- latched external bexcn
171
  echeck           : std_logic;
172
  brmw             : std_logic;
173
  haddr            : std_logic_vector(31 downto 0);
174
  hsel             : std_logic;
175
  srhsel           : std_logic;
176
  sdhsel           : std_logic;
177
  hwrite           : std_logic;
178
  hburst           : std_logic_vector(2 downto 0);
179
  htrans           : std_logic_vector(1 downto 0);
180
  hresp            : std_logic_vector(1 downto 0);
181
  sa               : std_logic_vector(14 downto 0);
182
  sd               : std_logic_vector(63 downto 0);
183
  mben             : std_logic_vector(3 downto 0);
184
end record;
185
 
186
signal r, ri : reg_type;
187
signal wrnout : std_logic_vector(3 downto 0);
188
signal sdmo : sdram_mctrl_out_type;
189
signal sdi  : sdram_in_type;
190
signal lsdo   : sdram_out_type;
191
 
192
-- vectored output enable to data pads 
193
signal rbdrive, ribdrive : std_logic_vector(31 downto 0);
194
signal rsbdrive, risbdrive : std_logic_vector(63 downto 0);
195
attribute syn_preserve : boolean;
196
attribute syn_preserve of rbdrive : signal is true;
197
attribute syn_preserve of rsbdrive : signal is true;
198
 
199
-- **** tame: added signal to invert polarity
200
-- signal bprom_cs : std_ulogic;
201
 
202
begin
203
 
204
  ctrl : process(rst, ahbsi, apbi, memi, r, wpo, sdmo, rbdrive, rsbdrive, lsdo)
205
  variable v : reg_type;                -- local variables for registers
206
  variable start : std_logic;
207
  variable dataout : std_logic_vector(31 downto 0); -- data from memory
208
  variable regsd : std_logic_vector(31 downto 0);   -- data from registers
209
  variable memdata : std_logic_vector(31 downto 0);   -- data to memory
210
  variable rws : std_logic_vector(3 downto 0);           -- read waitstates
211
  variable wws : std_logic_vector(3 downto 0);           -- write waitstates
212
  variable wsnew : std_logic_vector(3 downto 0);         -- write waitstates
213
  variable adec : std_logic_vector(1 downto 0);
214
  variable rams : std_logic_vector(4 downto 0);
215
  variable bready, leadin : std_logic;
216
  variable csen : std_logic;                    -- Generate chip selects
217
  variable aprot   : std_logic_vector(14 downto 0); --
218
  variable wrn   : std_logic_vector(3 downto 0); --
219
  variable bexc, addrerr : std_logic;
220
  variable ready : std_logic;
221
  variable writedata : std_logic_vector(31 downto 0);
222
  variable bwdata : std_logic_vector(31 downto 0);
223
  variable merrtype  : std_logic_vector(2 downto 0); -- memory error type
224
  variable noerror : std_logic;
225
  variable area  : std_logic_vector(0 to 2);
226
  variable bdrive : std_logic_vector(3 downto 0);
227
  variable ramsn : std_logic_vector(4 downto 0);
228
  variable romsn, busw : std_logic_vector(1 downto 0);
229
  variable iosn : std_logic;
230
  variable lock : std_logic;
231
  variable wprothitx : std_logic;
232
  variable brmw : std_logic;
233
  variable bidle: std_logic;
234
  variable haddr   : std_logic_vector(31 downto 0);
235
  variable hsize   : std_logic_vector(1 downto 0);
236
  variable hwrite  : std_logic;
237
  variable hburst  : std_logic_vector(2 downto 0);
238
  variable htrans  : std_logic_vector(1 downto 0);
239
  variable sdhsel, srhsel, hready  : std_logic;
240
  variable vbdrive : std_logic_vector(31 downto 0);
241
  variable vsbdrive : std_logic_vector(63 downto 0);
242
  variable bdrive_sel : std_logic_vector(3 downto 0);
243
  begin
244
 
245
-- Variable default settings to avoid latches
246
 
247
    v := r; wprothitx := '0'; v.ready8 := '0'; v.iosn(0) := r.iosn(1);
248
 
249
    ready := '0'; addrerr := '0'; regsd := (others => '0'); csen := '0';
250
 
251
    v.ready := '0'; v.echeck := '0';
252
    merrtype := "---"; bready := '1';
253
 
254
    vbdrive := rbdrive; vsbdrive := rsbdrive;
255
 
256
    v.data := memi.data; v.bexcn := memi.bexcn; v.brdyn := memi.brdyn;
257
    if (((r.brdyn and r.mcfg1.brdyen) = '1') and (r.area(io) = '1')) or
258
       (((r.brdyn and r.mcfg2.brdyen) = '1') and (r.area(ram) = '1') and
259
         (r.ramsn(4) = '0') and RAMSEL5)
260
    then
261
      bready := '0';
262
    else bready := '1'; end if;
263
 
264
    v.hresp := HRESP_OKAY;
265
 
266
    if SDRAMEN and (r.hsel = '1') and (ahbsi.hready = '0') then
267
      haddr := r.haddr;  hsize := r.size; hburst := r.hburst;
268
      htrans := r.htrans; hwrite := r.hwrite;
269
      area := r.area;
270
    else
271
      haddr := ahbsi.haddr;  hsize := ahbsi.hsize(1 downto 0);
272
      hburst := ahbsi.hburst; htrans := ahbsi.htrans; hwrite := ahbsi.hwrite;
273
      area := ahbsi.hmbsel(0 to 2);
274
    end if;
275
 
276
    if SDRAMEN then
277
      if fast = 1 then
278
        sdhsel := ahbsi.hsel(hindex) and ahbsi.haddr(sdrasel) and
279
           ahbsi.htrans(1) and ahbsi.hmbsel(2);
280
      else
281
        sdhsel := ahbsi.hsel(hindex) and ahbsi.htrans(1) and
282
          r.mcfg2.sdren and ahbsi.hmbsel(2) and (ahbsi.haddr(sdrasel) or r.mcfg2.srdis);
283
      end if;
284
      srhsel := ahbsi.hsel(hindex) and not sdhsel;
285
    else  sdhsel := '0'; srhsel := ahbsi.hsel(hindex); end if;
286
 
287
-- decode memory area parameters
288
 
289
    leadin := '0'; rws := "----"; wws := "----"; adec := "--";
290
    busw := (others => '-'); brmw := '0';
291
    if area(rom) = '1' then
292
      busw := r.mcfg1.romwidth;
293
    end if;
294
    if area(ram) = '1' then
295
      adec := genmux(r.mcfg2.rambanksz, haddr(sdrasel downto 14)) &
296
              genmux(r.mcfg2.rambanksz, haddr(sdrasel-1 downto 13));
297
 
298
      if sdhsel = '1' then busw := "10";
299
 
300
      else
301
        busw := r.mcfg2.ramwidth;
302
        if ((r.mcfg2.rmw and hwrite) = '1') and
303
         ((BUS16EN and (busw = "01") and (hsize = "00")) or
304
          ((busw(1) = '1') and (hsize(1) = '0'))
305
 
306
        )
307
        then brmw := '1'; end if;        -- do a read-modify-write cycle
308
      end if;
309
    end if;
310
    if area(io) = '1' then
311
      leadin := '1';
312
      busw := r.mcfg1.iowidth;
313
    end if;
314
 
315
-- decode waitstates, illegal access and cacheability
316
 
317
    if r.area(rom) = '1' then
318
      rws := r.mcfg1.romrws; wws := r.mcfg1.romwws;
319
      if (r.mcfg1.romwrite or r.read) = '0' then addrerr := '1'; end if;
320
    end if;
321
    if r.area(ram) = '1' then
322
      rws := "00" & r.mcfg2.ramrws; wws := "00" & r.mcfg2.ramwws;
323
    end if;
324
    if r.area(io) = '1' then
325
      rws := r.mcfg1.iows; wws := r.mcfg1.iows;
326
      if r.mcfg1.ioen = '0' then addrerr := '1'; end if;
327
    end if;
328
 
329
-- generate data buffer enables
330
 
331
    bdrive := (others => '1');
332
    case r.busw is
333
    when "00" => if BUS8EN then bdrive := "0001"; end if;
334
    when "01" => if BUS16EN then bdrive := "0011"; end if;
335
    when others =>
336
    end case;
337
 
338
-- generate chip select and output enable
339
 
340
    rams := '0' & decode(adec);
341
    case srbanks is
342
    when 0 => rams := "00000";
343
    when 1 => rams := "00001";
344
    when 2 => rams := "000" & (rams(3 downto 2) or rams(1 downto 0));
345
    when others =>
346
      if RAMSEL5 and (haddr(sdrasel) = '1') then rams := "10000"; end if;
347
    end case;
348
 
349
    iosn := '1'; ramsn := (others => '1'); romsn := (others => '1');
350
    if area(rom) = '1' then
351
      romsn := (not haddr(romasel)) & haddr(romasel);
352
    end if;
353
    if area(ram) = '1' then ramsn := not rams; end if;
354
    if area(io) = '1' then iosn := '0'; end if;
355
 
356
-- generate write strobe
357
 
358
    wrn := "0000";
359
    case r.busw is
360
    when "00" =>
361
      if BUS8EN then wrn := "1110"; end if;
362
    when "01" =>
363
      if BUS16EN then
364
        if (r.size = "00") and (r.brmw = '0') then
365
          wrn := "11" & (not r.address(0)) & r.address(0);
366
        else wrn := "1100"; end if;
367
      end if;
368
    when "10" | "11" =>
369
      case r.size is
370
      when "00" =>
371
        case r.address(1 downto 0) is
372
        when "00" => wrn := "1110";
373
        when "01" => wrn := "1101";
374
        when "10" => wrn := "1011";
375
        when others => wrn := "0111";
376
        end case;
377
      when "01" =>
378
        wrn := not r.address(1) & not r.address(1) & r.address(1) & r.address(1);
379
      when others => null;
380
      end case;
381
    when others => null;
382
    end case;
383
 
384
    if (r.mcfg2.rmw = '1') and (r.area(ram) = '1') then wrn := not bdrive; end if;
385
 
386
    if (((ahbsi.hready and ahbsi.hsel(hindex) and ahbsi.htrans(1)) = '1'))
387
    then
388
      v.area := area;
389
      v.address  := haddr;
390
      if (busw = "00") and (hwrite = '0') and (area(io) = '0') and BUS8EN
391
      then v.address(1 downto 0) := "00"; end if;
392
      if (busw = "01") and (hwrite = '0') and (area(io) = '0') and BUS16EN
393
      then v.address(1 downto 0) := "00"; end if;
394
      if (brmw = '1') then
395
        v.read := '1';
396
 
397
      else v.read := not hwrite; end if;
398
      v.busw := busw; v.brmw := brmw;
399
 
400
    end if;
401
 
402
    if (((sdmo.aload and r.hsel) = '1') and SDRAMEN) then
403
      v.address  := haddr;
404
      if (busw = "00") and (hwrite = '0') and (area(io) = '0') and BUS8EN
405
      then v.address(1 downto 0) := "00"; end if;
406
      if (busw = "01") and (hwrite = '0') and (area(io) = '0') and BUS16EN
407
      then v.address(1 downto 0) := "00"; end if;
408
    end if;
409
 
410
-- Select read data depending on bus width
411
 
412
    if BUS8EN and (r.busw = "00") then
413
      memdata := r.readdata(23 downto 0) & r.data(31 downto 24);
414
    elsif BUS16EN and (r.busw = "01") then
415
      memdata := r.readdata(15 downto 0) & r.data(31 downto 16);
416
    else
417
      memdata := r.data;
418
    end if;
419
 
420
    bwdata := memdata;
421
 
422
-- Merge data during byte write
423
 
424
    writedata := ahbsi.hwdata;
425
    if ((r.brmw and r.busw(1)) = '1')
426
 
427
    then
428
      case r.address(1 downto 0) is
429
 
430
      when "00" =>
431
        writedata(15 downto 0) := bwdata(15 downto 0);
432
        if r.size = "00" then
433
          writedata(23 downto 16) := bwdata(23 downto 16);
434
        end if;
435
      when "01" =>
436
        writedata(31 downto 24) := bwdata(31 downto 24);
437
        writedata(15 downto 0) := bwdata(15 downto 0);
438
      when "10" =>
439
        writedata(31 downto 16) := bwdata(31 downto 16);
440
        if r.size = "00" then
441
          writedata(7 downto 0) := bwdata(7 downto 0);
442
        end if;
443
      when  others =>
444
        writedata(31 downto 8) := bwdata(31 downto 8);
445
      end case;
446
    end if;
447
    if (r.brmw = '1') and (r.busw = "01") and BUS16EN then
448
      if (r.address(0) = '0') then
449
        writedata(23 downto 16) :=  r.data(23 downto 16);
450
      else
451
        writedata(31 downto 24) :=  r.data(31 downto 24);
452
      end if;
453
    end if;
454
 
455
-- save read data during 8/16 bit reads
456
 
457
    if BUS8EN and (r.ready8 = '1') and (r.busw = "00") then
458
      v.readdata := v.readdata(23 downto 0) & r.data(31 downto 24);
459
    elsif BUS16EN and (r.ready8 = '1') and (r.busw = "01") then
460
      v.readdata := v.readdata(15 downto 0) & r.data(31 downto 16);
461
    end if;
462
 
463
-- Ram, rom, IO access FSM
464
 
465
    if r.read = '1' then wsnew := rws; else wsnew := wws; end if;
466
 
467
    case r.bstate is
468
    when idle =>
469
      v.ws := wsnew;
470
 
471
      if r.bdrive(0) = '1' then
472
 
473
        if r.busw(1) = '1' then
474
          v.writedata(31 downto 16) := writedata(31 downto 16);
475
        elsif r.busw = "01" then
476
          if r.address(1) = '0' then
477
            v.writedata(31 downto 16) := writedata(31 downto 16);
478
          else
479
            v.writedata(31 downto 16) := writedata(15 downto 0);
480
          end if;
481
        else
482
          case r.address(1 downto 0) is
483
            when "00" =>
484
              v.writedata(31 downto 16) := writedata(31 downto 16);
485
            when "01" =>
486
              v.writedata(31 downto 24) := writedata(23 downto 16);
487
            when "10" =>
488
              v.writedata(31 downto 16) := writedata(15 downto 0);
489
            when "11" =>
490
             v.writedata(31 downto 24) := writedata(7 downto 0);
491
            when others =>
492
              null;
493
          end case;
494
        end if;
495
        v.writedata(15 downto 0) := writedata(15 downto 0);
496
        if r.busw(1) = '0' then
497
          v.writedata8 := writedata(15 downto 0);
498
        end if;
499
      end if;
500
      if (r.srhsel = '1') and ((sdmo.busy = '0') or not SDRAMEN)
501
 
502
      then
503
        if WPROTEN then wprothitx := wpo.wprothit; end if;
504
        if (wprothitx or addrerr) = '1' then
505
          v.hresp := HRESP_ERROR; v.bstate := berr; v.bdrive := (others => '1');
506
        elsif r.read = '0' then
507
          if (r.busw = "00") and (r.area(io) = '0') and BUS8EN then
508
            v.bstate := bwrite8;
509
          elsif (r.busw = "01") and (r.area(io) = '0') and BUS16EN then
510
            v.bstate := bwrite16;
511
          else v.bstate := bwrite; end if;
512
          v.wrn := wrn; v.writen := '0'; v.bdrive := not bdrive;
513
        else
514
          if r.oen = '1' then v.ramoen := r.ramsn; v.oen := '0';
515
          else
516
            if (r.busw = "00") and (r.area(io) = '0') and BUS8EN then v.bstate := bread8;
517
            elsif (r.busw = "01") and (r.area(io) = '0') and BUS16EN then v.bstate := bread16;
518
            else v.bstate := bread; end if;
519
          end if;
520
        end if;
521
      end if;
522
    when berr =>
523
      v.bstate := idle; ready := '1';
524
      v.hresp := HRESP_ERROR;
525
      v.ramsn := (others => '1'); v.romsn := (others => '1');
526
      v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11"; v.bdrive := (others => '1');
527
    when bread =>
528
      if ((r.ws = "0000") and (r.ready = '0') and (bready = '1'))
529
      then
530
        if r.brmw = '0' then
531
          ready := '1'; v.echeck := '1';
532
          if r.area(io) = '0' then
533
            v.address := ahbsi.haddr;
534
          end if;
535
        end if;
536
        if (((ahbsi.hsel(hindex) = '0') or (ahbsi.htrans /= HTRANS_SEQ)) or
537
             (r.hburst = HBURST_SINGLE) or (r.area(io) = '1'))
538
        then
539
          v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";
540
          v.bstate := idle; v.read := not r.hwrite;
541
          if r.brmw = '0' then
542
            v.ramsn := (others => '1'); v.romsn := (others => '1');
543
          else
544
            v.echeck := '1';
545
          end if;
546
        end if;
547
      end if;
548
      if r.ready = '1' then
549
        v.ws := rws;
550
      else
551
        if r.ws /= "0000" then v.ws := r.ws - 1; end if;
552
      end if;
553
    when bwrite =>
554
      if (r.ws = "0000") and (bready = '1') then
555
        ready := '1'; v.wrn := (others => '1'); v.writen := '1'; v.echeck := '1';
556
        v.ramsn := (others => '1'); v.romsn := (others => '1'); v.iosn := "11";
557
        v.bdrive := (others => '1'); v.bstate := idle;
558
      end if;
559
      if r.ws /= "0000" then v.ws := r.ws - 1; end if;
560
    when bread8 =>
561
      if BUS8EN then
562
        if (r.ws = "0000") and (r.ready8 = '0') and (bready = '1') then
563
          v.ready8 := '1'; v.ws := rws;
564
          v.address(1 downto 0) := r.address(1 downto 0) + 1;
565
 
566
          if (r.address(1 downto 0) = "11") then
567
            ready := '1'; v.address := ahbsi.haddr; v.echeck := '1';
568
 
569
            if (((ahbsi.hsel(hindex) = '0') or (ahbsi.htrans /= HTRANS_SEQ)) or
570
                (r.hburst = HBURST_SINGLE))
571
            then
572
              v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";
573
              v.bstate := idle;
574
 
575
              v.ramsn := (others => '1'); v.romsn := (others => '1');
576
 
577
            end if;
578
          end if;
579
        end if;
580
        if (r.ready8 = '1') then v.ws := rws;
581
        elsif r.ws /= "0000" then v.ws := r.ws - 1; end if;
582
      else
583
        v.bstate := idle;
584
      end if;
585
    when bwrite8 =>
586
      if BUS8EN then
587
        if (r.ws = "0000") and (r.ready8 = '0') and (bready = '1') then
588
          v.ready8 := '1'; v.wrn := (others => '1'); v.writen := '1';
589
        end if;
590
 
591
        if (r.ws = "0000") and (bready = '1') and
592
           ((r.address(1 downto 0) = "11") or
593
            ((r.address(1 downto 0) = "01") and (r.size = "01")) or
594
            (r.size = "00"))
595
 
596
        then
597
          ready := '1'; v.wrn := (others => '1'); v.writen := '1'; v.echeck := '1';
598
          v.ramsn := (others => '1'); v.romsn := (others => '1'); v.iosn := "11";
599
          v.bdrive := (others => '1'); v.bstate := idle;
600
 
601
        end if;
602
        if (r.ready8 = '1') then
603
          v.address(1 downto 0) := r.address(1 downto 0) + 1; v.ws := rws;
604
          v.writedata(31 downto 16) := r.writedata(23 downto 16) & r.writedata8(15 downto 8);
605
          v.writedata8(15 downto 8) := r.writedata8(7 downto 0);
606
          v.bstate := idle;
607
 
608
        end if;
609
        if r.ws /= "0000" then v.ws := r.ws - 1; end if;
610
      else
611
        v.bstate := idle;
612
      end if;
613
    when bread16 =>
614
      if BUS16EN then
615
        if (r.ws = "0000") and (bready = '1') and ((r.address(1) or r.brmw) = '1') and
616
           (r.ready8 = '0')
617
        then
618
          if r.brmw = '0' then
619
            ready := '1'; v.address := ahbsi.haddr; v.echeck := '1';
620
          end if;
621
          if (((ahbsi.hsel(hindex) = '0') or (ahbsi.htrans /= HTRANS_SEQ)) or
622
              (r.hburst = HBURST_SINGLE))
623
          then
624
            if r.brmw = '0' then
625
              v.ramsn := (others => '1'); v.romsn := (others => '1');
626
            end if;
627
            v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";
628
            v.bstate := idle; v.read := not r.hwrite;
629
          end if;
630
        end if;
631
        if (r.ws = "0000") and (bready = '1') and (r.ready8 = '0') then
632
          v.ready8 := '1'; v.ws := rws;
633
          if r.brmw = '0' then v.address(1) := not r.address(1); end if;
634
        end if;
635
        if r.ws /= "0000" then v.ws := r.ws - 1; end if;
636
      else
637
        v.bstate := idle;
638
      end if;
639
    when bwrite16 =>
640
      if BUS16EN then
641
        if (r.ws = "0000") and (bready = '1') and
642
           ((r.address(1 downto 0) = "10") or (r.size(1) = '0'))
643
        then
644
          ready := '1'; v.wrn := (others => '1'); v.writen := '1'; v.echeck := '1';
645
          v.ramsn := (others => '1'); v.romsn := (others => '1'); v.iosn := "11";
646
          v.bdrive := (others => '1'); v.bstate := idle;
647
        end if;
648
        if (r.ws = "0000") and (bready = '1') and (r.ready8 = '0') then
649
          v.ready8 := '1'; v.wrn := (others => '1'); v.writen := '1';
650
        end if;
651
        if (r.ready8 = '1') then
652
          v.address(1) := not r.address(1); v.ws := rws;
653
          v.writedata(31 downto 16) := r.writedata8(15 downto 0);
654
          v.bstate := idle;
655
        end if;
656
        if r.ws /= "0000" then v.ws := r.ws - 1; end if;
657
      else
658
        v.bstate := idle;
659
      end if;
660
    when others =>
661
    end case;
662
 
663
-- if BUSY or IDLE cycle seen, or if de-selected, return to idle state
664
    if (ahbsi.hready = '1') then
665
      if ((ahbsi.hsel(hindex) = '0') or (ahbsi.htrans = HTRANS_BUSY) or
666
        (ahbsi.htrans = HTRANS_IDLE))
667
      then
668
        v.bstate := idle;
669
        v.ramsn := (others => '1'); v.romsn := (others => '1');
670
        v.ramoen := (others => '1'); v.oen := '1'; v.iosn := "11";
671
        v.bdrive := (others => '1'); v.wrn := (others => '1');
672
        v.writen := '1'; v.hsel := '0'; ready := ahbsi.hsel(hindex); v.srhsel := '0';
673
      elsif srhsel = '1' then
674
        v.romsn := romsn; v.ramsn(4 downto 0) := ramsn(4 downto 0); v.iosn := iosn & '1';
675
        if v.read = '1' then v.ramoen(4 downto 0) := ramsn(4 downto 0); v.oen := leadin; end if;
676
      end if;
677
    end if;
678
 
679
-- error checking and reporting
680
 
681
    noerror := '1';
682
    if ((r.echeck and r.mcfg1.bexcen and not r.bexcn) = '1') then
683
      noerror := '0'; v.bstate := berr; v.hresp := HRESP_ERROR; v.bdrive := (others => '1');
684
      v.wrn := (others => '1'); v.writen := '1';
685
    end if;
686
 
687
-- APB register access
688
 
689
    case apbi.paddr(3 downto 2) is
690
    when "00" =>
691
      regsd(28 downto 0) := r.mcfg1.iowidth &
692
        r.mcfg1.brdyen & r.mcfg1.bexcen & "0" & r.mcfg1.iows & r.mcfg1.ioen &
693
        '0' &
694
 
695
        "000000" & r.mcfg1.romwrite &
696
 
697
        '0' & r.mcfg1.romwidth & r.mcfg1.romwws & r.mcfg1.romrws;
698
    when "01" =>
699
      if SDRAMEN then
700
        regsd(31 downto 17) := sdmo.prdata(31 downto 17);
701
        if BUS64 then regsd(18) := '1'; end if;
702
        regsd(14 downto 13) := r.mcfg2.sdren & r.mcfg2.srdis;
703
      end if;
704
      regsd(12 downto 9) := r.mcfg2.rambanksz;
705
      if RAMSEL5 then regsd(7) := r.mcfg2.brdyen; end if;
706
      regsd(6 downto 0) := r.mcfg2.rmw & r.mcfg2.ramwidth &
707
        r.mcfg2.ramwws & r.mcfg2.ramrws;
708
    when "10" =>
709
 
710
      if SDRAMEN then
711
        regsd(26 downto 12) := sdmo.prdata(26 downto 12);
712
      end if;
713
    when others => regsd := (others => '0');
714
    end case;
715
 
716
    apbo.prdata <= regsd;
717
 
718
    if (apbi.psel(pindex) and apbi.penable and apbi.pwrite) = '1' then
719
      case apbi.paddr(5 downto 2) is
720
      when "0000" =>
721
        v.mcfg1.romrws      :=  apbi.pwdata(3 downto 0);
722
        v.mcfg1.romwws      :=  apbi.pwdata(7 downto 4);
723
        v.mcfg1.romwidth    :=  apbi.pwdata(9 downto 8);
724
        v.mcfg1.romwrite    :=  apbi.pwdata(11);
725
 
726
        v.mcfg1.ioen        :=  apbi.pwdata(19);
727
        v.mcfg1.iows        :=  apbi.pwdata(23 downto 20);
728
        v.mcfg1.bexcen      :=  apbi.pwdata(25);
729
        v.mcfg1.brdyen      :=  apbi.pwdata(26);
730
        v.mcfg1.iowidth     :=  apbi.pwdata(28 downto 27);
731
      when "0001" =>
732
        v.mcfg2.ramrws      := apbi.pwdata(1 downto 0);
733
        v.mcfg2.ramwws      := apbi.pwdata(3 downto 2);
734
        v.mcfg2.ramwidth    := apbi.pwdata(5 downto 4);
735
        v.mcfg2.rmw         := apbi.pwdata(6);
736
        v.mcfg2.brdyen      := apbi.pwdata(7);
737
        v.mcfg2.rambanksz   := apbi.pwdata(12 downto 9);
738
        if SDRAMEN then
739
          v.mcfg2.srdis     := apbi.pwdata(13);
740
          v.mcfg2.sdren     := apbi.pwdata(14);
741
        end if;
742
 
743
      when others => null;
744
      end case;
745
    end if;
746
 
747
-- select appropriate data during reads
748
 
749
    if (r.area(rom) or r.area(ram)) = '1' then dataout := memdata;
750
    else
751
      if BUS8EN and (r.busw = "00") then
752
        dataout := r.data(31 downto 24) & r.data(31 downto 24)
753
                 & r.data(31 downto 24) & r.data(31 downto 24);
754
      elsif BUS16EN and (r.busw = "01") then
755
        dataout := r.data(31 downto 16) & r.data(31 downto 16);
756
      else dataout := r.data; end if;
757
    end if;
758
 
759
    v.ready := ready;
760
    v.srhsel := r.srhsel and not ready;
761
    if ahbsi.hready = '1' then v.hsel := ahbsi.hsel(hindex); end if;
762
 
763
    if ((ahbsi.hready and ahbsi.hsel(hindex)) = '1') then
764
      v.size := ahbsi.hsize(1 downto 0); v.hwrite := ahbsi.hwrite;
765
      v.hburst := ahbsi.hburst; v.htrans := ahbsi.htrans;
766
      if ahbsi.htrans(1) = '1' then v.hsel := '1'; v.srhsel := srhsel; end if;
767
      if SDRAMEN then
768
        v.haddr := ahbsi.haddr;
769
        v.sdhsel := sdhsel;
770
      end if;
771
    end if;
772
 
773
-- sdram synchronisation
774
 
775
    if SDRAMEN then
776
      v.sa := sdmo.address; v.sd := memi.sd;
777
      if (r.bstate /= idle) or ((r.ramsn & r.romsn & r.iosn) /= "111111111") then bidle := '0';
778
      else
779
        bidle := '1';
780
        if (sdmo.busy and not sdmo.aload) = '1' then
781
          if not SDSEPBUS then
782
            v.address(sdlsb + 14 downto sdlsb) := sdmo.address;
783
          end if;
784
          v.romsn := (others => '1'); v.ramsn(4 downto 0) := (others => '1');
785
          v.iosn := (others =>'1'); v.ramoen(4 downto 0) := (others => '1');
786
          v.oen := '1';
787
          v.bdrive := not (sdmo.bdrive & sdmo.bdrive & sdmo.bdrive & sdmo.bdrive);
788
          if r.sdhsel = '1' then
789
            v.hresp := sdmo.hresp;
790
          end if;
791
        end if;
792
      end if;
793
      if (sdmo.aload and r.srhsel) = '1' then
794
        v.romsn := romsn; v.ramsn(4 downto 0) := ramsn(4 downto 0); v.iosn := iosn & '1';
795
        if v.read = '1' then v.ramoen(4 downto 0) := ramsn(4 downto 0); v.oen := leadin; end if;
796
      end if;
797
      if sdmo.hsel = '1' then
798
        v.writedata := writedata;
799
        v.sdwritedata(31 downto 0) := writedata;
800
        if BUS64 and sdmo.bsel = '1' then
801
          v.sdwritedata(63 downto 32) := writedata;
802
        end if;
803
        hready := sdmo.hready and noerror and not r.brmw;
804
        if SDSEPBUS then
805
          if BUS64 and sdmo.bsel = '1' then dataout := r.sd(63 downto 32);
806
          else dataout := r.sd(31 downto 0); end if;
807
        end if;
808
      else hready := r.ready and noerror; end if;
809
    else
810
      hready := r.ready and noerror;
811
    end if;
812
 
813
    if v.read = '1' then v.mben := "0000"; else v.mben := v.wrn; end if;
814
 
815
    v.nbdrive := not v.bdrive;
816
 
817
    if oepol = 0 then
818
      bdrive_sel := r.bdrive;
819
      vbdrive(31 downto 24) := (others => v.bdrive(0));
820
      vbdrive(23 downto 16) := (others => v.bdrive(1));
821
      vbdrive(15 downto 8) := (others => v.bdrive(2));
822
      vbdrive(7 downto 0) := (others => v.bdrive(3));
823
 
824
      vsbdrive(31 downto 24) := (others => v.bdrive(0));
825
      vsbdrive(23 downto 16) := (others => v.bdrive(1));
826
      vsbdrive(15 downto 8) := (others => v.bdrive(2));
827
      vsbdrive(7 downto 0) := (others => v.bdrive(3));
828
 
829
      vsbdrive(63 downto 56) := (others => v.bdrive(0));
830
      vsbdrive(55 downto 48) := (others => v.bdrive(1));
831
      vsbdrive(47 downto 40) := (others => v.bdrive(2));
832
      vsbdrive(39 downto 32) := (others => v.bdrive(3));
833
    else
834
      bdrive_sel := r.nbdrive;
835
      vbdrive(31 downto 24) := (others => v.nbdrive(0));
836
      vbdrive(23 downto 16) := (others => v.nbdrive(1));
837
      vbdrive(15 downto 8) := (others => v.nbdrive(2));
838
      vbdrive(7 downto 0) := (others => v.nbdrive(3));
839
 
840
      vsbdrive(31 downto 24) := (others => v.nbdrive(0));
841
      vsbdrive(23 downto 16) := (others => v.nbdrive(1));
842
      vsbdrive(15 downto 8) := (others => v.nbdrive(2));
843
      vsbdrive(7 downto 0) := (others => v.nbdrive(3));
844
 
845
      vsbdrive(63 downto 56) := (others => v.nbdrive(0));
846
      vsbdrive(55 downto 48) := (others => v.nbdrive(1));
847
      vsbdrive(47 downto 40) := (others => v.nbdrive(2));
848
      vsbdrive(39 downto 32) := (others => v.nbdrive(3));
849
    end if;
850
 
851
-- reset
852
 
853
    if rst = '0' then
854
 
855
      v.bstate           := idle;
856
      v.read             := '1';
857
      v.wrn              := "1111";
858
      v.writen           := '1';
859
      v.mcfg1.romwrite   := '0';
860
      v.mcfg1.ioen       := '0';
861
      v.mcfg1.brdyen     := '0';
862
      v.mcfg1.bexcen     := '0';
863
      v.hsel             := '0';
864
      v.srhsel           := '0';
865
      v.ready            := '1';
866
      v.mcfg1.iows       := "0000";
867
      v.mcfg2.ramrws     := "00";
868
      v.mcfg2.ramwws     := "00";
869
      v.mcfg1.romrws     := "1111";
870
      v.mcfg1.romwws     := "1111";
871
      v.mcfg1.romwidth   := memi.bwidth;
872
      v.mcfg2.srdis      := '0';
873
      v.mcfg2.sdren      := '0';
874
      if syncrst = 1 then
875
        v.ramsn := (others => '1'); v.romsn := (others => '1');
876
        v.oen := '1'; v.iosn := "11"; v.ramoen := (others => '1');
877
        v.bdrive := (others => '1'); v.nbdrive := (others => '0');
878
        if oepol = 0 then vbdrive := (others => '1'); vsbdrive := (others => '1');
879
        else vbdrive := (others => '0'); vsbdrive := (others => '0'); end if;
880
      end if;
881
    end if;
882
 
883
-- optional feeb-back from write stobe to data bus drivers
884
 
885
    if oepol = 0 then
886
      if WENDFB then bdrive := r.bdrive and memi.wrn;
887
      else bdrive := r.bdrive; end if;
888
    else
889
      if WENDFB then bdrive := r.nbdrive or not memi.wrn;
890
      else bdrive := r.nbdrive; end if;
891
    end if;
892
 
893
-- pragma translate_off
894
    for i in dataout'range loop --'
895
      if is_x(dataout(i)) then dataout(i) := '1'; end if;
896
    end loop;
897
-- pragma translate_on
898
 
899
    v.addressx := v.address;
900
 
901
    if avnetmezz = 1 then
902
      if v.ramsn(1 downto 0) = "11" then  -- SDRAM/SRAM shares strobes
903
        v.mben := lsdo.dqm(3 downto 0);
904
      end if;
905
      if ((v.ramsn(0) and r.ramsn(0)) = '0') then  -- mezz address shift
906
        v.addressx := "00" & v.address(31 downto 2);
907
       else
908
        v.addressx := v.address;
909
      end if;
910
    else
911
        v.addressx := "00" & v.address(31 downto 2);
912
    end if;
913
 
914
-- drive various register inputs and external outputs
915
 
916
    ri <= v;
917
 
918
    ribdrive <= vbdrive;
919
    risbdrive <= vsbdrive;
920
 
921
    ahbso.hcache <= not r.area(io);
922
    memo.address <= r.addressx;
923
    memo.ramsn          <= "111" & r.ramsn;
924
    memo.ramoen         <= "111" & r.ramoen;
925
    memo.romsn          <= "111111" & r.romsn;
926
    memo.oen            <= r.oen;
927
    memo.iosn           <= r.iosn(0);
928
    memo.read           <= r.read;
929
    memo.wrn            <= r.wrn;
930
    if (avnetmezz = 1) then
931
      memo.writen       <= r.writen and lsdo.sdwen;
932
    else
933
      memo.writen       <= r.writen;
934
    end if;
935
    memo.bdrive         <= bdrive;
936
    memo.data           <= r.writedata;
937
    memo.mben           <= r.mben;
938
    memo.vbdrive        <= rbdrive;
939
    sdi.idle            <= bidle;
940
    sdi.haddr           <= haddr;
941
    sdi.rhaddr          <= r.haddr;
942
    sdi.nhtrans         <= htrans;
943
    sdi.rhtrans         <= r.htrans;
944
    sdi.htrans          <= ahbsi.htrans;
945
    sdi.hready          <= ahbsi.hready;
946
    sdi.hsize           <= r.size;
947
    sdi.hwrite          <= r.hwrite;
948
    sdi.hsel            <= sdhsel;
949
    sdi.enable          <= r.mcfg2.sdren;
950
    sdi.srdis           <= r.mcfg2.srdis;
951
 
952
    ahbso.hrdata <= dataout;
953
    ahbso.hready <= hready;
954
    ahbso.hresp  <= r.hresp;
955
 
956
  end process;
957
 
958
  stdregs : process(clk,rst)
959
  begin
960
    if rising_edge(clk) then
961
      r <= ri; rbdrive <= ribdrive; rsbdrive <= risbdrive;
962
      if rst = '0' then r.ws <= (others => '0'); end if;
963
    end if;
964
    if (syncrst = 0) and (rst = '0') then
965
      r.ramsn <= (others => '1'); r.romsn <= (others => '1');
966
      r.oen <= '1'; r.iosn <= "11"; r.ramoen <= (others => '1');
967
      r.bdrive <= (others => '1'); r.nbdrive <= (others => '0');
968
      if oepol = 0 then rbdrive <= (others => '1'); rsbdrive <= (others => '1');
969
      else rbdrive <= (others => '0'); rsbdrive <= (others => '0'); end if;
970
    end if;
971
  end process;
972
 
973
  ahbso.hsplit <= (others => '0');
974
  ahbso.hconfig <= hconfig;
975
  ahbso.hirq    <= (others => '0');
976
  ahbso.hindex <= hindex;
977
  apbo.pconfig  <= pconfig;
978
  apbo.pirq     <= (others => '0');
979
  apbo.pindex   <= pindex;
980
 
981
-- optional sdram controller
982
 
983
  sd0 : if SDRAMEN generate
984
    sdctrl : sdmctrl generic map (pindex, invclk, fast, wprot, sdbits, pageburst)
985
        port map ( rst => rst, clk => clk, sdi => sdi,
986
        sdo => lsdo, apbi => apbi, wpo => wpo, sdmo => sdmo);
987
    rgen : if invclk = 0 generate
988
      memo.sa <= r.sa; sdo <= lsdo; memo.svbdrive <= rsbdrive;
989
      memo.sddata(31 downto 0)  <= r.sdwritedata(31 downto 0);
990
      memo.sddata(63 downto 32) <= r.sdwritedata(63 downto 32);
991
    end generate;
992
 
993
    ngen : if invclk = 1 generate
994
      nregs : process(clk, rst) begin
995
        if falling_edge(clk) then
996
          memo.sa <= r.sa; sdo <= lsdo; memo.svbdrive <= rsbdrive;
997
          memo.sddata(31 downto 0)  <= r.sdwritedata(31 downto 0);
998
          memo.sddata(63 downto 32) <= r.sdwritedata(63 downto 32);
999
        end if;
1000
      end process;
1001
    end generate;
1002
  end generate;
1003
 
1004
  sd1 : if not SDRAMEN generate
1005
        sdo <= ("00", "11", '1', '1', '1', "11111111");
1006
        sdmo.prdata <= (others => '0');
1007
        sdmo.address <= (others => '0'); sdmo.busy <= '0';
1008
        sdmo.aload <= '0'; sdmo.bdrive <= '0'; sdmo.hready <= '1';
1009
        sdmo.hresp <= "11";
1010
 
1011
  end generate;
1012
 
1013
end;
1014
 

powered by: WebSVN 2.1.0

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