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

powered by: WebSVN 2.1.0

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