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/] [misc/] [ahbtrace.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:      ahbtrace
20
-- File:        ahbtrace.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research
22
-- Description: AHB trace unit
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
use grlib.devices.all;
31
library techmap;
32
use techmap.gencomp.all;
33
library gaisler;
34
 
35
entity ahbtrace is
36
  generic (
37
    hindex  : integer := 0;
38
    ioaddr  : integer := 16#000#;
39
    iomask  : integer := 16#E00#;
40
    tech    : integer := DEFMEMTECH;
41
    irq     : integer := 0;
42
    kbytes  : integer := 1);
43
  port (
44
    rst    : in  std_ulogic;
45
    clk    : in  std_ulogic;
46
    ahbmi  : in  ahb_mst_in_type;
47
    ahbsi  : in  ahb_slv_in_type;
48
    ahbso  : out ahb_slv_out_type
49
  );
50
end;
51
 
52
architecture rtl of ahbtrace is
53
 
54
constant TBUFABITS : integer := log2(kbytes) + 6;
55
constant TIMEBITS  : integer := 32;
56
 
57
constant hconfig : ahb_config_type := (
58
 
59
  4 => ahb_iobar (ioaddr, iomask),
60
  others => zero32);
61
 
62
type tracebuf_in_type is record
63
  addr             : std_logic_vector(11 downto 0);
64
  data             : std_logic_vector(127 downto 0);
65
  enable           : std_logic;
66
  write            : std_logic_vector(3 downto 0);
67
end record;
68
 
69
type tracebuf_out_type is record
70
  data             : std_logic_vector(127 downto 0);
71
end record;
72
 
73
type trace_break_reg is record
74
  addr          : std_logic_vector(31 downto 2);
75
  mask          : std_logic_vector(31 downto 2);
76
  read          : std_logic;
77
  write         : std_logic;
78
end record;
79
 
80
type regtype is record
81
  haddr         : std_logic_vector(31 downto 0);
82
  hwrite        : std_logic;
83
  htrans        : std_logic_vector(1 downto 0);
84
  hsize         : std_logic_vector(2 downto 0);
85
  hburst        : std_logic_vector(2 downto 0);
86
  hwdata        : std_logic_vector(31 downto 0);
87
  hmaster       : std_logic_vector(3 downto 0);
88
  hmastlock     : std_logic;
89
  hsel          : std_logic;
90
  hready        : std_logic;
91
  hready2       : std_logic;
92
  hready3       : std_logic;
93
  ahbactive     : std_logic;
94
  timer         : std_logic_vector(TIMEBITS-1 downto 0);
95
  aindex        : std_logic_vector(TBUFABITS - 1 downto 0); -- buffer index
96
 
97
  enable        : std_logic;    -- trace enable
98
  bahb          : std_logic;    -- break on AHB watchpoint hit
99
  bhit          : std_logic;    -- breakpoint hit
100
  dcnten        : std_logic;    -- delay counter enable
101
  delaycnt      : std_logic_vector(TBUFABITS - 1 downto 0); -- delay counter
102
 
103
  tbreg1        : trace_break_reg;
104
  tbreg2        : trace_break_reg;
105
end record;
106
 
107
signal tbi   : tracebuf_in_type;
108
signal tbo   : tracebuf_out_type;
109
 
110
signal enable : std_logic_vector(1 downto 0);
111
 
112
signal r, rin : regtype;
113
 
114
begin
115
 
116
  ctrl : process(rst, ahbmi, ahbsi, r, tbo)
117
  variable v : regtype;
118
  variable vabufi : tracebuf_in_type;
119
  variable regsd : std_logic_vector(31 downto 0);   -- data from registers
120
  variable aindex : std_logic_vector(TBUFABITS - 1 downto 0); -- buffer index
121
  variable bphit : std_logic;
122
  variable bufdata : std_logic_vector(127 downto 0);
123
  variable hirq : std_logic_vector(NAHBIRQ-1 downto 0);
124
 
125
  begin
126
 
127
    v := r; regsd := (others => '0'); vabufi.enable := '0';
128
    vabufi.data := (others => '0'); vabufi.addr := (others => '0');
129
    vabufi.write := (others => '0'); bphit := '0';
130
    v.hready := r.hready2; v.hready2 := r.hready3; v.hready3 := '0';
131
    bufdata := tbo.data;
132
    hirq := (others => '0'); hirq(irq) := r.bhit;
133
 
134
-- trace buffer index and delay counters
135
    if r.enable = '1' then v.timer := r.timer + 1; end if;
136
    aindex := r.aindex + 1;
137
 
138
-- check for AHB watchpoints
139
    if (ahbsi.hready and r.ahbactive ) = '1' then
140
      if ((((r.tbreg1.addr xor r.haddr(31 downto 2)) and r.tbreg1.mask) = zero32(29 downto 0)) and
141
         (((r.tbreg1.read and not r.hwrite) or (r.tbreg1.write and r.hwrite)) = '1'))
142
        or ((((r.tbreg2.addr xor r.haddr(31 downto 2)) and r.tbreg2.mask) = zero32(29 downto 0)) and
143
           (((r.tbreg2.read and not r.hwrite) or (r.tbreg2.write and r.hwrite)) = '1'))
144
      then
145
        if (r.enable = '1') and (r.dcnten = '0') and
146
           (r.delaycnt /= zero32(TBUFABITS-1 downto 0))
147
        then v.dcnten := '1';
148
        else bphit := '1'; v.enable := '0'; end if;
149
      end if;
150
    end if;
151
 
152
-- generate buffer inputs
153
      vabufi.write := "0000";
154
      if r.enable = '1' then
155
        vabufi.addr(TBUFABITS-1 downto 0) := r.aindex;
156
        vabufi.data(127 downto 96) := r.timer;
157
        vabufi.data(95) := bphit;
158
        vabufi.data(94 downto 80) := ahbmi.hirq(15 downto 1);
159
        vabufi.data(79) := r.hwrite;
160
        vabufi.data(78 downto 77) := r.htrans;
161
        vabufi.data(76 downto 74) := r.hsize;
162
        vabufi.data(73 downto 71) := r.hburst;
163
        vabufi.data(70 downto 67) := r.hmaster;
164
        vabufi.data(66) := r.hmastlock;
165
        vabufi.data(65 downto 64) := ahbmi.hresp;
166
        if r.hwrite = '1' then
167
          vabufi.data(63 downto 32) := ahbsi.hwdata;
168
        else
169
          vabufi.data(63 downto 32) := ahbmi.hrdata;
170
        end if;
171
        vabufi.data(31 downto 0) := r.haddr;
172
      else
173
        vabufi.addr(TBUFABITS-1 downto 0) := r.haddr(TBUFABITS+3 downto 4);
174
        vabufi.data := ahbsi.hwdata & ahbsi.hwdata &
175
                       ahbsi.hwdata & ahbsi.hwdata;
176
      end if;
177
 
178
-- write trace buffer
179
 
180
      if r.enable = '1' then
181
        if (r.ahbactive and ahbsi.hready) = '1' then
182
          v.aindex := aindex;
183
          vabufi.enable := '1'; vabufi.write := "1111";
184
        end if;
185
      end if;
186
 
187
-- trace buffer delay counter handling
188
 
189
    if (r.dcnten = '1') then
190
      if (r.delaycnt = zero32(TBUFABITS-1 downto 0)) then
191
        v.enable := '0'; v.dcnten := '0';
192
      end if;
193
      v.delaycnt := r.delaycnt - 1;
194
    end if;
195
 
196
-- save AHB transfer parameters
197
 
198
    if (ahbsi.hready = '1' ) then
199
      v.haddr := ahbsi.haddr; v.hwrite := ahbsi.hwrite; v.htrans := ahbsi.htrans;
200
      v.hsize := ahbsi.hsize; v.hburst := ahbsi.hburst;
201
      v.hmaster := ahbsi.hmaster; v.hmastlock := ahbsi.hmastlock;
202
    end if;
203
    if r.hsel = '1' then v.hwdata := ahbsi.hwdata; end if;
204
    if ahbsi.hready = '1' then
205
      v.hsel := ahbsi.hsel(hindex);
206
      v.ahbactive := ahbsi.htrans(1);
207
    end if;
208
 
209
-- AHB slave access to DSU registers and trace buffers
210
 
211
    if (r.hsel and not r.hready) = '1' then
212
      if r.haddr(16) = '0' then          -- registers
213
        v.hready := '1';
214
        case r.haddr(4 downto 2) is
215
        when "000" =>
216
          regsd((TBUFABITS + 15) downto 16) := r.delaycnt;
217
          regsd(1 downto 0) := r.dcnten & r.enable;
218
          if r.hwrite = '1' then
219
            v.delaycnt := ahbsi.hwdata((TBUFABITS+ 15) downto 16);
220
            v.dcnten := ahbsi.hwdata(1);
221
            v.enable := ahbsi.hwdata(0);
222
          end if;
223
        when "001" =>
224
            regsd((TBUFABITS - 1 + 4) downto 4) := r.aindex;
225
            if r.hwrite = '1' then
226
              v.aindex := ahbsi.hwdata((TBUFABITS- 1) downto 0);
227
            end if;
228
        when "010" =>
229
          regsd((TIMEBITS - 1) downto 0) := r.timer;
230
          if r.hwrite = '1' then
231
            v.timer := ahbsi.hwdata((TIMEBITS- 1) downto 0);
232
          end if;
233
        when "100" =>
234
          regsd(31 downto 2) := r.tbreg1.addr;
235
          if r.hwrite = '1' then
236
            v.tbreg1.addr := ahbsi.hwdata(31 downto 2);
237
          end if;
238
        when "101" =>
239
          regsd := r.tbreg1.mask & r.tbreg1.read & r.tbreg1.write;
240
          if r.hwrite = '1' then
241
            v.tbreg1.mask := ahbsi.hwdata(31 downto 2);
242
            v.tbreg1.read := ahbsi.hwdata(1);
243
            v.tbreg1.write := ahbsi.hwdata(0);
244
          end if;
245
        when "110" =>
246
          regsd(31 downto 2) := r.tbreg2.addr;
247
          if r.hwrite = '1' then
248
            v.tbreg2.addr := ahbsi.hwdata(31 downto 2);
249
          end if;
250
        when others =>
251
          regsd := r.tbreg2.mask & r.tbreg2.read & r.tbreg2.write;
252
          if r.hwrite = '1' then
253
            v.tbreg2.mask := ahbsi.hwdata(31 downto 2);
254
            v.tbreg2.read := ahbsi.hwdata(1);
255
            v.tbreg2.write := ahbsi.hwdata(0);
256
          end if;
257
        end case;
258
        v.hwdata := regsd;
259
      else              -- read/write access to trace buffer
260
          if r.hwrite = '1' then v.hready := '1'; else v.hready2 := not (r.hready2 or r.hready); end if;
261
          vabufi.enable := not r.enable;
262
          bufdata := tbo.data;
263
          case r.haddr(3 downto 2) is
264
          when "00" =>
265
            v.hwdata := bufdata(127 downto 96);
266
            if r.hwrite = '1' then
267
              vabufi.write(3) := vabufi.enable;
268
            end if;
269
          when "01" =>
270
            v.hwdata := bufdata(95 downto 64);
271
            if r.hwrite = '1' then
272
              vabufi.write(2) := vabufi.enable;
273
            end if;
274
          when "10" =>
275
            v.hwdata := bufdata(63 downto 32);
276
            if r.hwrite = '1' then
277
              vabufi.write(1) := vabufi.enable;
278
            end if;
279
          when others =>
280
            v.hwdata := bufdata(31 downto 0);
281
            if r.hwrite = '1' then
282
              vabufi.write(0) := vabufi.enable;
283
            end if;
284
          end case;
285
      end if;
286
    end if;
287
 
288
    if ((ahbsi.hsel(hindex) and ahbsi.hready) = '1') and
289
          ((ahbsi.htrans = HTRANS_BUSY) or (ahbsi.htrans = HTRANS_IDLE))
290
    then v.hready := '1'; end if;
291
 
292
    if rst = '0' then
293
      v.ahbactive := '0'; v.enable := '0'; v.timer := (others => '0');
294
      v.hsel := '0'; v.dcnten := '0'; v.bhit := '0';
295
      v.tbreg1.read := '0'; v.tbreg1.write := '0';
296
      v.tbreg2.read := '0'; v.tbreg2.write := '0';
297
    end if;
298
 
299
    tbi <= vabufi;
300
    rin <= v;
301
 
302
    ahbso.hconfig <= hconfig;
303
    ahbso.hirq    <= hirq;
304
    ahbso.hsplit  <= (others => '0');
305
    ahbso.hcache  <= '0';
306
    ahbso.hrdata <= r.hwdata;
307
    ahbso.hready <= r.hready;
308
    ahbso.hindex <= hindex;
309
 
310
  end process;
311
 
312
  ahbso.hresp <= HRESP_OKAY;
313
 
314
  regs : process(clk)
315
  begin if rising_edge(clk) then r <= rin; end if; end process;
316
 
317
--  mem0 : tbufmem
318
--  generic map (tech => tech, tbuf => kbytes) port map (clk, tbi, tbo);
319
 
320
  enable <= tbi.enable & tbi.enable;
321
  mem0 : for i in 0 to 1 generate
322
    ram0 : syncram64 generic map (tech => tech, abits => TBUFABITS)
323
      port map (clk, tbi.addr(TBUFABITS-1 downto 0), tbi.data(((i*64)+63) downto (i*64)),
324
                 tbo.data(((i*64)+63) downto (i*64)), enable, tbi.write(i*2+1 downto i*2));
325
  end generate;
326
 
327
-- pragma translate_off
328
    bootmsg : report_version
329
    generic map ("ahbtrace" & tost(hindex) &
330
    ": AHB Trace Buffer, " & tost(kbytes) & " kbytes");
331
-- pragma translate_on
332
 
333
end;
334
 
335
 

powered by: WebSVN 2.1.0

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