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/] [leon3/] [mmutw.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:      mmutw
20
-- File:        mmutw.vhd
21
-- Author:      Konrad Eisele, Jiri Gaisler, Gaisler Research
22
-- Description: MMU table-walk logic
23
------------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
library grlib;
28
use grlib.amba.all;
29
use grlib.stdlib.all;
30
library gaisler;
31
use gaisler.libiu.all;
32
use gaisler.libcache.all;
33
use gaisler.leon3.all;
34
use gaisler.mmuconfig.all;
35
use gaisler.mmuiface.all;
36
 
37
entity mmutw is
38
  port (
39
    rst     : in  std_logic;
40
    clk     : in  std_logic;
41
    mmctrl1 : in  mmctrl_type1;
42
    twi     : in  mmutw_in_type;
43
    two     : out mmutw_out_type;
44
    mcmmo   : in  memory_mm_out_type;
45
    mcmmi   : out memory_mm_in_type
46
    );
47
end mmutw;
48
 
49
architecture rtl of mmutw is
50
 
51
  type write_buffer_type is record                      -- write buffer 
52
    addr, data  : std_logic_vector(31 downto 0);
53
    read        : std_logic;
54
  end record;
55
 
56
  type states is (idle, waitm, pte, lv1, lv2, lv3, lv4);
57
  type tw_rtype is record
58
    state       : states;
59
    wb          : write_buffer_type;
60
    req         : std_logic;
61
    walk_op     : std_logic;
62
 
63
    --#dump
64
    -- pragma translate_off
65
    finish      : std_logic;
66
    index       : std_logic_vector(31-2 downto 0);
67
    lvl         : std_logic_vector(1 downto 0);
68
    fault_mexc  : std_logic;
69
    fault_trans : std_logic;
70
    fault_lvl   : std_logic_vector(1 downto 0);
71
    pte,ptd,inv,rvd : std_logic;
72
    goon, found : std_logic;
73
    base        : std_logic_vector(31 downto 0);
74
    -- pragma translate_on
75
  end record;
76
  signal c,r : tw_rtype;
77
 
78
begin
79
 
80
  p0: process (rst, r, c, twi, mcmmo, mmctrl1)
81
  variable v           : tw_rtype;
82
  variable finish      : std_logic;
83
  variable index       : std_logic_vector(31-2 downto 0);
84
  variable lvl         : std_logic_vector(1 downto 0);
85
  variable fault_mexc  : std_logic;
86
  variable fault_trans : std_logic;
87
  variable fault_inv   : std_logic;
88
  variable fault_lvl   : std_logic_vector(1 downto 0);
89
  variable pte,ptd,inv,rvd : std_logic;
90
  variable goon, found : std_logic;
91
  variable base        : std_logic_vector(31 downto 0);
92
 
93
  begin
94
    v := r;
95
 
96
    --#init
97
    finish := '0';
98
    index := (others => '0');
99
    lvl := (others => '0');
100
    fault_mexc := '0';
101
    fault_trans := '0';
102
    fault_inv := '0';
103
    fault_lvl := (others => '0');
104
    pte := '0';ptd := '0';inv := '0';rvd := '0';
105
    goon := '0'; found := '0';
106
    base := (others => '0');
107
    base(PADDR_PTD_U downto PADDR_PTD_D) := mcmmo.data(PTD_PTP32_U downto PTD_PTP32_D);
108
 
109
    if mcmmo.grant = '1' then
110
      v.req := '0';
111
    end if;
112
 
113
    if mcmmo.retry = '1' then v.req := '1'; end if;
114
 
115
    -- # pte/ptd
116
    if ((mcmmo.ready and not r.req)= '1') then -- context
117
      case mcmmo.data(PT_ET_U downto PT_ET_D) is
118
        when ET_INV => inv := '1';
119
        when ET_PTD => ptd := '1'; goon := '1';
120
        when ET_PTE => pte := '1'; found := '1';
121
        when ET_RVD => rvd := '1'; null;
122
        when others => null;
123
      end case;
124
    end if;
125
    fault_trans := (rvd);
126
    fault_inv := inv;
127
 
128
    -- # state machine
129
    case r.state is
130
      when idle =>
131
        if (twi.walk_op_ur) = '1' then
132
          v.walk_op := '1';
133
          index(M_CTX_SZ-1 downto 0) := mmctrl1.ctx;
134
          base := (others => '0');
135
          base(PADDR_PTD_U downto PADDR_PTD_D) := mmctrl1.ctxp(MMCTRL_PTP32_U downto MMCTRL_PTP32_D);
136
          v.wb.addr := base or (index&"00");
137
          v.wb.read := '1';
138
          v.req := '1';
139
          v.state := lv1;
140
        elsif (twi.areq_ur) = '1' then
141
          index := (others => '0');
142
          v.wb.addr := twi.aaddr;
143
          v.wb.data := twi.adata;
144
          v.wb.read := '0';
145
          v.req := '1';
146
          v.state := waitm;
147
        end if;
148
      when waitm =>
149
        if ((mcmmo.ready and not r.req)= '1') then          -- amba: result ready current cycle
150
          fault_mexc := mcmmo.mexc;
151
          v.state := idle;
152
          finish := '1';
153
        end if;
154
      when lv1 =>
155
 
156
        if ((mcmmo.ready and not r.req)= '1') then
157
          lvl := LVL_CTX; fault_lvl := FS_L_CTX;
158
          index(VA_I1_SZ-1 downto 0) := twi.data(VA_I1_U downto VA_I1_D);
159
          v.state := lv2;
160
        end if;
161
      when lv2 =>
162
 
163
        if ((mcmmo.ready and not r.req)= '1') then
164
          lvl := LVL_REGION; fault_lvl :=  FS_L_L1;
165
          index(VA_I2_SZ-1 downto 0) := twi.data(VA_I2_U downto VA_I2_D);
166
          v.state := lv3;
167
        end if;
168
      when lv3 =>
169
 
170
        if ((mcmmo.ready and not r.req)= '1') then
171
          lvl := LVL_SEGMENT; fault_lvl := FS_L_L2;
172
          index(VA_I3_SZ-1 downto 0) := twi.data(VA_I3_U downto VA_I3_D);
173
          v.state := lv4;
174
        end if;
175
      when lv4 =>
176
 
177
        if ((mcmmo.ready and not r.req)= '1') then
178
          lvl := LVL_PAGE; fault_lvl := FS_L_L3;
179
          fault_trans := fault_trans or ptd;
180
          v.state := idle;
181
          finish := '1';
182
        end if;
183
      when others =>
184
        v.state := idle;
185
        finish := '0';
186
 
187
    end case;
188
    base := base or (index&"00");
189
 
190
    if r.walk_op = '1' then
191
      if (mcmmo.ready and (not r.req)) = '1' then
192
        fault_mexc := mcmmo.mexc;
193
        if (( ptd and
194
              (not fault_mexc ) and
195
              (not fault_trans) and
196
              (not fault_inv  )) = '1') then -- tw  : break table walk?
197
          v.wb.addr := base;
198
          v.req := '1';
199
        else
200
          v.walk_op := '0';
201
          finish := '1';
202
          v.state := idle;
203
        end if;
204
      end if;
205
    end if;
206
 
207
    -- # reset
208
    if ( rst = '0' ) then
209
      v.state := idle;
210
      v.req := '0';
211
      v.walk_op := '0';
212
      v.wb.read := '0';
213
    end if;
214
 
215
    --# drive signals
216
    two.finish      <= finish;
217
    two.data        <= mcmmo.data;
218
    two.addr        <= r.wb.addr(31 downto 0);
219
    two.lvl         <= lvl;
220
    two.fault_mexc  <= fault_mexc;
221
    two.fault_trans <= fault_trans;
222
    two.fault_inv   <= fault_inv;
223
    two.fault_lvl   <= fault_lvl;
224
 
225
    mcmmi.address  <= r.wb.addr;
226
    mcmmi.data     <= r.wb.data;
227
    mcmmi.burst    <= '0';
228
    mcmmi.size     <= "10";
229
    mcmmi.read     <= r.wb.read;
230
    mcmmi.lock     <= '0';
231
    mcmmi.req      <= r.req;
232
 
233
    --#dump
234
    -- pragma translate_off
235
    v.finish := finish;
236
    v.index := index;
237
    v.lvl   := lvl;
238
    v.fault_mexc := fault_mexc;
239
    v.fault_trans := fault_trans;
240
    v.fault_lvl := fault_lvl;
241
    v.pte   := pte;
242
    v.ptd   := ptd;
243
    v.inv   := inv;
244
    v.rvd   := rvd;
245
    v.goon  := goon;
246
    v.found := found;
247
    v.base  := base;
248
    -- pragma translate_on
249
 
250
    c <= v;
251
  end process p0;
252
 
253
  p1: process (clk)
254
  begin if rising_edge(clk) then r <= c; end if;
255
  end process p1;
256
 
257
end rtl;

powered by: WebSVN 2.1.0

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