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/] [memctrl/] [srctrl.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:      srctrl
20
-- File:        srctrl.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research
22
-- Modified:    Marko Isomaki - Gaisler Research
23
-- Description: 32-bit SRAM memory controller with read-modify-write
24
------------------------------------------------------------------------------
25
 
26
library ieee;
27
use ieee.std_logic_1164.all;
28
library grlib;
29
use grlib.amba.all;
30
use grlib.stdlib.all;
31
library gaisler;
32
use grlib.devices.all;
33
use gaisler.memctrl.all;
34
 
35
entity srctrl is
36
  generic (
37
    hindex  : integer := 0;
38
    romaddr : integer := 0;
39
    rommask : integer := 16#ff0#;
40
    ramaddr : integer := 16#400#;
41
    rammask : integer := 16#ff0#;
42
    ioaddr  : integer := 16#200#;
43
    iomask  : integer := 16#ff0#;
44
    ramws   : integer := 0;
45
    romws   : integer := 2;
46
    iows    : integer := 2;
47
    rmw     : integer := 0;              -- read-modify-write enable
48
    prom8en : integer := 0;
49
    oepol   : integer := 0;
50
    srbanks : integer range 1 to 5  := 1;
51
    banksz  : integer range 0 to 13 := 13;
52
    romasel : integer range 0 to 28 := 19
53
  );
54
  port (
55
    rst     : in  std_ulogic;
56
    clk     : in  std_ulogic;
57
    ahbsi   : in  ahb_slv_in_type;
58
    ahbso   : out ahb_slv_out_type;
59
    sri     : in  memory_in_type;
60
    sro     : out memory_out_type;
61
    sdo     : out sdctrl_out_type
62
  );
63
end;
64
 
65
architecture rtl of srctrl is
66
 
67
constant VERSION : amba_version_type := 0;
68
constant hconfig : ahb_config_type := (
69
 
70
  4 => ahb_membar(romaddr, '1', '1', rommask),
71
  5 => ahb_membar(ramaddr, '1', '1', rammask),
72
  6 => ahb_membar(ioaddr, '0', '0', iomask),
73
  others => zero32);
74
 
75
type srcycletype is (idle, read1, read2, write1, write2, rmw1, rmw2, rmw3);
76
type prom8cycletype is (idle, read1, read2);
77
 
78
function byteswap (rdata, wdata, addr, size : std_logic_vector) return std_logic_vector is
79
variable tmp : std_logic_vector(31 downto 0);
80
variable a : std_logic_vector(1 downto 0);
81
begin
82
  tmp := rdata; a := addr(1 downto 0);
83
  if size(0) = '0' then
84
    case a is
85
    when "00" => tmp(31 downto 24) := wdata(31 downto 24);
86
    when "01" => tmp(23 downto 16) := wdata(23 downto 16);
87
    when "10" => tmp(15 downto 8) := wdata(15 downto 8);
88
    when others => tmp(7 downto 0) := wdata(7 downto 0);
89
    end case;
90
  else
91
    if addr(1) = '0' then tmp(31 downto 16) := wdata(31 downto 16);
92
    else tmp(15 downto 0) := wdata(15 downto 0); end if;
93
  end if;
94
  return(tmp);
95
end;
96
 
97
-- local registers
98
 
99
type reg_type is record
100
  hready        : std_ulogic;
101
  hsel          : std_ulogic;
102
  hmbsel        : std_logic_vector(0 to 2);
103
  bdrive        : std_ulogic;
104
  nbdrive       : std_ulogic;
105
  srstate       : srcycletype;
106
  haddr         : std_logic_vector(31 downto 0);
107
  hrdata        : std_logic_vector(31 downto 0);
108
  hwdata        : std_logic_vector(31 downto 0);
109
  hwrite        : std_ulogic;
110
  htrans        : std_logic_vector(1 downto 0);
111
  hburst        : std_logic_vector(2 downto 0);
112
  hresp         : std_logic_vector(1 downto 0);
113
  size          : std_logic_vector(1 downto 0);
114
  read          : std_ulogic;
115
  oen           : std_ulogic;
116
  ramsn         : std_ulogic;
117
  romsn         : std_ulogic;
118
  vramsn        : std_logic_vector(4 downto 0);
119
  ramoen        : std_logic_vector(4 downto 0);
120
  vromsn        : std_logic_vector(1 downto 0);
121
  writen        : std_ulogic;
122
  wen           : std_logic_vector(3 downto 0);
123
  mben          : std_logic_vector(3 downto 0);
124
  ws            : std_logic_vector(3 downto 0);
125
  iosn          : std_ulogic;
126
-- 8-bit prom access
127
  pr8state      : prom8cycletype;
128
  data8         : std_logic_vector(23 downto 0);
129
  ready8        : std_ulogic;
130
  bwidth        : std_logic_vector(1 downto 0);
131
end record;
132
 
133
signal r, ri : reg_type;
134
 
135
-- vectored output enable to data pads
136
signal rbdrive, ribdrive : std_logic_vector(31 downto 0);
137
attribute syn_preserve : boolean;
138
attribute syn_preserve of rbdrive : signal is true;
139
 
140
begin
141
 
142
  ctrl : process(rst, ahbsi, r, sri, rbdrive)
143
  variable v       : reg_type;          -- local variables for registers
144
  variable dqm     : std_logic_vector(3 downto 0);
145
  variable adec    : std_logic_vector(1 downto 0);
146
  variable rams    : std_logic_vector(4 downto 0);
147
  variable roms    : std_logic_vector(1 downto 0);
148
  variable haddr   : std_logic_vector(31 downto 0);
149
  variable hrdata  : std_logic_vector(31 downto 0);
150
  variable hsize   : std_logic_vector(1 downto 0);
151
  variable hwrite  : std_ulogic;
152
  variable htrans  : std_logic_vector(1 downto 0);
153
  variable vramws, vromws, viows : std_logic_vector(3 downto 0);
154
-- 8-bit prom access
155
  variable romsn   : std_ulogic;
156
  variable bdrive  : std_ulogic;
157
  variable oen     : std_ulogic;
158
  variable writen  : std_ulogic;
159
  variable hready  : std_ulogic;
160
  variable ws      : std_logic_vector(3 downto 0);
161
  variable hwdata  : std_logic_vector(31 downto 0);
162
  variable prom8sel : std_ulogic;
163
  variable vbdrive : std_logic_vector(31 downto 0);
164
  variable sbdrive  : std_ulogic;
165
  begin
166
 
167
-- Variable default settings to avoid latches
168
 
169
    v := r; v.hresp := HRESP_OKAY; v.hrdata := sri.data; hrdata := r.hrdata;
170
    vramws := conv_std_logic_vector(ramws, 4); vbdrive := rbdrive;
171
    vromws := conv_std_logic_vector(romws, 4);
172
    viows := conv_std_logic_vector(iows, 4);
173
    v.bwidth := sri.bwidth;
174
    if (prom8en = 1) and (r.bwidth = "00") then prom8sel := '1';
175
    else prom8sel := '0'; end if;
176
 
177
    if (ahbsi.hready = '1') then
178
      if (ahbsi.hsel(hindex) and ahbsi.htrans(1)) = '1' then
179
        v.size := ahbsi.hsize(1 downto 0); v.hwrite := ahbsi.hwrite;
180
        v.htrans := ahbsi.htrans; v.hburst := ahbsi.hburst;
181
        v.hsel := '1'; v.hmbsel := ahbsi.hmbsel(0 to 2);
182
        v.haddr := ahbsi.haddr; v.hready := '0';
183
      else
184
        v.hsel := '0';
185
      end if;
186
    end if;
187
 
188
    if (r.hsel = '1') and (ahbsi.hready = '0') then
189
      haddr := r.haddr;  hsize := r.size;
190
      htrans := r.htrans; hwrite := r.hwrite;
191
    else
192
      haddr := ahbsi.haddr;  hsize := ahbsi.hsize(1 downto 0);
193
      htrans := ahbsi.htrans; hwrite := ahbsi.hwrite;
194
    end if;
195
 
196
-- chip-select decoding
197
   adec := haddr(banksz+14 downto banksz+13);
198
 
199
   rams := '0' & decode(adec);
200
 
201
   case srbanks is
202
   when 1 => rams := "00001";
203
   when 2 => rams := "000" & (rams(3 downto 2) or rams(1 downto 0));
204
   when others => null;
205
   end case;
206
   roms := haddr(romasel) & not haddr(romasel);
207
 
208
-- generate write strobes
209
 
210
    if rmw = 1 then dqm := "0000"; else
211
      case r.size is
212
      when "00" =>
213
        case r.haddr(1 downto 0) is
214
        when "00" => dqm := "1110";
215
        when "01" => dqm := "1101";
216
        when "10" => dqm := "1011";
217
        when others => dqm := "0111";
218
        end case;
219
      when "01" =>
220
        if r.haddr(1) = '0' then dqm := "1100"; else  dqm := "0011"; end if;
221
      when others => dqm := "0000";
222
      end case;
223
    end if;
224
 
225
-- main FSM
226
 
227
    case r.srstate is
228
    when idle =>
229
      if (v.hsel = '1') and not
230
        (((v.ramsn or r.romsn) = '0') or ((v.romsn or r.ramsn) = '0')) and not
231
        ((v.hmbsel(0) and not hwrite and prom8sel) = '1' and prom8en = 1)
232
      then
233
        v.hready := '0';
234
        v.ramsn := not v.hmbsel(1); v.romsn := not v.hmbsel(0);
235
        v.iosn := not v.hmbsel(2);
236
        v.read := not hwrite;
237
        if hwrite = '1' then
238
          if (rmw = 1) and (hsize(1) = '0') and (v.hmbsel(1) = '1') then
239
            v.srstate := rmw1; v.read := '1';
240
          else v.srstate := write1; end if;
241
        elsif ahbsi.htrans = "10" then v.srstate := read1;
242
        else v.srstate := read2; end if;
243
        v.oen := not v.read;
244
      else
245
        v.ramsn := '1'; v.romsn := '1'; v.bdrive := '1'; v.oen := '1';
246
         v.iosn := '1';
247
      end if;
248
      if v.romsn = '0' then v.ws := vromws;
249
      elsif v.iosn = '0' then v.ws := viows;
250
      else v.ws := vramws; end if;
251
    when read1 =>
252
      v.srstate := read2;
253
    when read2 =>
254
      v.ws := r.ws -1; v.oen := '0';
255
      if r.ws = "0000" then
256
        v.srstate := idle; v.hready := '1'; v.haddr := ahbsi.haddr;
257
        v.ramsn := not (ahbsi.hmbsel(1) and ahbsi.htrans(1));
258
        v.romsn := not (ahbsi.hmbsel(0) and ahbsi.htrans(1));
259
        v.oen := not (ahbsi.hsel(hindex) and ahbsi.htrans(1) and not ahbsi.hwrite);
260
      end if;
261
    when write1 =>
262
      if r.romsn = '0' then v.ws := vromws;
263
      elsif v.iosn = '0' then v.ws := viows;
264
      else v.ws := vramws; end if;
265
      v.srstate := write2; v.bdrive := '0'; v.wen := dqm; v.writen := '0';
266
      v.hwdata := ahbsi.hwdata;
267
    when write2 =>
268
      if r.ws = "0000" then
269
        v.srstate := idle; v.bdrive := '1'; v.wen := "1111"; v.writen := '1';
270
        v.hready := '1';
271
      end if;
272
      v.ws := r.ws -1;
273
    when rmw1 =>
274
      if (rmw = 1) then v.oen := '0';
275
        v.srstate := rmw2;
276
        v.hwdata := ahbsi.hwdata;
277
      end if;
278
    when rmw2 =>
279
      if (rmw = 1) then
280
        v.ws := r.ws -1;
281
        if r.ws = "0000" then v.oen := '1'; v.srstate := rmw3; end if;
282
      end if;
283
    when rmw3 =>
284
      if (rmw = 1) then
285
        v.hwdata := byteswap(r.hrdata, r.hwdata, r.haddr, r.size);
286
        v.srstate := write2; v.bdrive := '0'; v.wen := dqm; v.writen := '0';
287
      end if;
288
      if r.romsn = '0' then v.ws := vromws; else v.ws := vramws; end if;
289
    end case;
290
 
291
    if (ahbsi.hready and ahbsi.hsel(hindex) ) = '1' then
292
      if ahbsi.htrans(1) = '0' then v.hready := '1'; end if;
293
    end if;
294
 
295
-- 8-bit PROM access FSM
296
    if prom8en = 1 then
297
      hready := '0'; ws := v.ws; v.ready8 := '0';
298
      bdrive := '1'; oen := '1'; writen := '1'; romsn := '1';
299
 
300
      if r.ready8 = '1' then
301
        v.data8 := r.data8(15 downto 0) & r.hrdata(31 downto 24);
302
        case r.size is
303
        when "00" => hrdata :=  r.hrdata(31 downto 24) &
304
          r.hrdata(31 downto 24) &  r.hrdata(31 downto 24) &  r.hrdata(31 downto 24);
305
        when "01" => hrdata := r.data8(7 downto 0) &  r.hrdata(31 downto 24) &
306
                r.data8(7 downto 0) & r.hrdata(31 downto 24);
307
        when others => hrdata := r.data8 & r.hrdata(31 downto 24);
308
        end case;
309
      end if;
310
 
311
      case r.pr8state is
312
        when idle =>
313
          if ( (v.hsel and v.hmbsel(0) and not hwrite and prom8sel) = '1')
314
          then
315
            romsn := '0'; v.pr8state := read1; oen := '0';
316
          end if;
317
        when read1 =>
318
          oen := '0'; romsn := '0'; v.pr8state := read2; ws := vromws;
319
        when read2 =>
320
          oen := '0'; ws := r.ws - 1; romsn := '0';
321
          if r.ws = "0000" then
322
            v.haddr(1 downto 0) := r.haddr(1 downto 0) + 1;
323
            if (r.size = "00") or ((r.size = "01") and  (r.haddr(0) = '1'))
324
              or r.haddr(1 downto 0) = "11"
325
            then
326
              hready := '1'; v.pr8state := idle; oen := '1';
327
            else
328
              v.pr8state := read1;
329
            end if;
330
            v.ready8 := '1';
331
          end if;
332
        when others =>
333
          v.pr8state := idle;
334
      end case;
335
 
336
      v.romsn := v.romsn and romsn; v.bdrive := v.bdrive and bdrive;
337
      v.oen := v.oen and oen; v.writen := v.writen and writen;
338
      v.hready := v.hready or hready; v.ws := ws;
339
    end if;
340
 
341
    if (v.oen or v.ramsn) = '0' then v.ramoen := not rams;
342
    else v.ramoen := (others => '1'); end if;
343
 
344
    if v.romsn = '0' then v.vromsn := not roms;
345
    else v.vromsn := (others => '1'); end if;
346
 
347
    if v.ramsn = '0' then v.vramsn := not rams;
348
    else v.vramsn := (others => '1'); end if;
349
 
350
    if v.read = '1' then v.mben := "0000"; else v.mben := v.wen; end if;
351
 
352
    v.nbdrive := not v.bdrive;
353
 
354
    if oepol = 1 then sbdrive := r.nbdrive; vbdrive := (others => v.nbdrive);
355
    else sbdrive := r.bdrive; vbdrive := (others => v.bdrive);  end if;
356
 
357
-- reset
358
 
359
    if rst = '0' then
360
      v.srstate := idle; v.hsel := '0'; v.writen := '1';
361
      v.wen := (others => '1'); v.hready := '1'; v.read := '1';
362
      v.ws := (others => '0');
363
      if prom8en = 1 then v.pr8state := idle; end if;
364
    end if;
365
 
366
    ribdrive <= vbdrive;
367
    ri <= v;
368
 
369
    sro.address  <= r.haddr;
370
    sro.bdrive   <= (others => sbdrive);
371
    sro.vbdrive  <= rbdrive;
372
    sro.ramsn    <= "111" & r.vramsn;
373
    sro.ramoen   <= "111" & r.ramoen;
374
    sro.romsn    <= "111111" & r.vromsn;
375
    sro.iosn     <= r.iosn;
376
    sro.wrn      <= r.wen;
377
    sro.oen      <= r.oen;
378
    sro.read     <= r.read;
379
    sro.data     <= r.hwdata;
380
    sro.writen   <= r.writen;
381
    sro.ramn     <= r.ramsn;
382
    sro.romn     <= r.romsn;
383
 
384
    ahbso.hready  <= r.hready;
385
    ahbso.hresp   <= r.hresp;
386
    ahbso.hrdata  <= hrdata;
387
    ahbso.hconfig <= hconfig;
388
    ahbso.hcache  <= '1';
389
    ahbso.hirq    <= (others => '0');
390
    ahbso.hindex  <= hindex;
391
    ahbso.hsplit  <= (others => '0');
392
 
393
  end process;
394
 
395
  sdo.sdcsn <= "11";
396
  sdo.sdcke <= "11";
397
  sdo.sdwen <= '1';
398
  sdo.rasn  <= '1';
399
  sdo.casn  <= '1';
400
  sdo.dqm   <= (others => '1');
401
  sdo.address  <= (others => '0');
402
  sdo.data  <= (others => '0');
403
  sro.mben  <= r.mben;
404
 
405
  regs : process(clk,rst)
406
  begin
407
 
408
    if rising_edge(clk) then r <= ri; rbdrive <= ribdrive; end if;
409
 
410
    if rst = '0' then
411
      r.ramsn  <= '1';
412
      r.romsn  <= '1'; r.oen    <= '1';
413
      r.bdrive <= '1'; r.nbdrive <= '0';
414
      r.vramsn <= (others => '1'); r.vromsn <= (others => '1');
415
      if oepol  = 0 then rbdrive <= (others => '1');
416
      else rbdrive <= (others => '0'); end if;
417
    end if;
418
  end process;
419
 
420
-- pragma translate_off
421
  bootmsg : report_version
422
  generic map ("srctrl" & tost(hindex) &
423
        ": 32-bit PROM/SRAM controller rev " & tost(VERSION));
424
-- pragma translate_on
425
 
426
end;
427
 

powered by: WebSVN 2.1.0

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