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/] [logan.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:      logan
20
-- File:        logan.vhd
21
-- Author:      Kristoffer Carlsson, Gaisler Research
22
-- Description: On-chip logic analyzer IP core
23
-----------------------------------------------------------------------------
24
 
25
library ieee;
26
use ieee.std_logic_1164.all;
27
 
28
library grlib;
29
use grlib.amba.all;
30
use grlib.stdlib.all;
31
use grlib.devices.all;
32
library techmap;
33
use techmap.gencomp.all;
34
 
35
entity logan is
36
  generic (
37
    dbits       : integer range 0  to 256 := 32;              -- Number of traced signals
38
    depth       : integer range 256 to 16384 := 1024;         -- Depth of trace buffer
39
    trigl       : integer range 1 to 63 := 1;                 -- Number of trigger levels
40
    usereg      : integer range 0 to 1 := 1;                  -- Use input register
41
    usequal     : integer range 0 to 1 := 0;                  -- Use qualifer bit
42
    usediv      : integer range 0 to 1 := 1;                  -- Enable/disable div counter
43
    pindex      : integer := 0;
44
    paddr       : integer := 0;
45
    pmask       : integer := 16#F00#;
46
    memtech     : integer := DEFMEMTECH);
47
  port (
48
    rstn        : in  std_logic;                              -- Synchronous reset
49
    clk         : in  std_logic;                              -- System clock 
50
    tclk        : in  std_logic;                              -- Trace clock
51
    apbi        : in  apb_slv_in_type;                        -- APB in record
52
    apbo        : out apb_slv_out_type;                       -- APB out record
53
    signals     : in  std_logic_vector(dbits - 1 downto 0));  -- Traced signals
54
end logan;
55
 
56
 
57
architecture rtl of logan is
58
 
59
  constant REVISION : amba_version_type := 0;
60
  constant pconfig : apb_config_type := (
61
 
62
    1 => apb_iobar(paddr, pmask));
63
 
64
  constant abits: integer := 8 + log2x(depth/256 - 1);
65
  constant az   : std_logic_vector(abits-1 downto 0) := (others => '0');
66
  constant dz   : std_logic_vector(dbits-1 downto 0) := (others => '0');
67
 
68
  type trig_cfg_type is record
69
      pattern    : std_logic_vector(dbits-1 downto 0);           -- Pattern to trig on
70
      mask       : std_logic_vector(dbits-1 downto 0);           -- trigger mask
71
      count      : std_logic_vector(5 downto 0);                 -- match counter
72
      eq         : std_ulogic;                                   -- Trig on match or no match?
73
  end record;
74
 
75
  type trig_cfg_arr is array (0 to trigl-1) of trig_cfg_type;
76
 
77
  type reg_type is record
78
       armed       : std_ulogic;
79
       trig_demet  : std_ulogic;
80
       trigged     : std_ulogic;
81
       fin_demet   : std_ulogic;
82
       finished    : std_ulogic;
83
       qualifier   : std_logic_vector(7 downto 0);
84
       qual_val    : std_ulogic;
85
       divcount    : std_logic_vector(15 downto 0);
86
       counter     : std_logic_vector(abits-1 downto 0);
87
       page        : std_logic_vector(3 downto 0);
88
       trig_conf   : trig_cfg_arr;
89
  end record;
90
 
91
  type trace_reg_type is record
92
       armed       : std_ulogic;
93
       arm_demet   : std_ulogic;
94
       trigged     : std_ulogic;
95
       finished    : std_ulogic;
96
       sample      : std_ulogic;
97
       divcounter  : std_logic_vector(15 downto 0);
98
       match_count : std_logic_vector(5 downto 0);
99
       counter     : std_logic_vector(abits-1 downto 0);
100
       curr_tl     : integer range 0 to trigl-1;
101
       w_addr      : std_logic_vector(abits-1 downto 0);
102
  end record;
103
 
104
  signal r_addr         : std_logic_vector(13 downto 0);
105
  signal bufout         : std_logic_vector(255 downto 0);
106
  signal r_en           : std_ulogic;
107
  signal r, rin         : reg_type;
108
  signal tr, trin       : trace_reg_type;
109
  signal sigreg         : std_logic_vector(dbits-1 downto 0);
110
  signal sigold         : std_logic_vector(dbits-1 downto 0);
111
 
112
begin
113
 
114
  bufout(255 downto dbits) <= (others => '0');
115
 
116
  -- Combinatorial process for AMBA clock domain
117
  comb1: process(rstn, apbi, r, tr, bufout)
118
 
119
    variable v              : reg_type;
120
    variable rdata          : std_logic_vector(31 downto 0);
121
    variable tl             : integer range 0 to trigl-1;
122
    variable pattern, mask  : std_logic_vector(255 downto 0);
123
 
124
  begin
125
 
126
    v := r;
127
    rdata := (others => '0'); tl := 0;
128
    pattern := (others => '0'); mask := (others => '0');
129
 
130
    -- Two stage synch
131
    v.trig_demet := tr.trigged;
132
    v.trigged := r.trig_demet;
133
    v.fin_demet := tr.finished;
134
    v.finished := r.fin_demet;
135
 
136
    if r.finished = '1' then
137
      v.armed := '0';
138
    end if;
139
 
140
    r_en <= '0';
141
 
142
    -- Read/Write --
143
    if apbi.psel(pindex) = '1' then
144
 
145
      -- Write
146
      if apbi.pwrite = '1' and apbi.penable = '1' then
147
 
148
        -- Only conf area writeable
149
        if apbi.paddr(15) = '0' then
150
 
151
          -- pattern/mask
152
          if apbi.paddr(14 downto 13) = "11" then
153
 
154
            tl                              := conv_integer(apbi.paddr(11 downto 6));
155
            pattern(dbits-1 downto 0)       := v.trig_conf(tl).pattern;
156
            mask(dbits-1 downto 0)          := v.trig_conf(tl).mask;
157
 
158
            case apbi.paddr(5 downto 2) is
159
 
160
              when "0000" => pattern(31 downto 0)     := apbi.pwdata;
161
              when "0001" => pattern(63 downto 32)    := apbi.pwdata;
162
              when "0010" => pattern(95 downto 64)    := apbi.pwdata;
163
              when "0011" => pattern(127 downto 96)   := apbi.pwdata;
164
              when "0100" => pattern(159 downto 128)  := apbi.pwdata;
165
              when "0101" => pattern(191 downto 160)  := apbi.pwdata;
166
              when "0110" => pattern(223 downto 192)  := apbi.pwdata;
167
              when "0111" => pattern(255 downto 224)  := apbi.pwdata;
168
 
169
              when "1000" => mask(31 downto 0)        := apbi.pwdata;
170
              when "1001" => mask(63 downto 32)       := apbi.pwdata;
171
              when "1010" => mask(95 downto 64)       := apbi.pwdata;
172
              when "1011" => mask(127 downto 96)      := apbi.pwdata;
173
              when "1100" => mask(159 downto 128)     := apbi.pwdata;
174
              when "1101" => mask(191 downto 160)     := apbi.pwdata;
175
              when "1110" => mask(223 downto 192)     := apbi.pwdata;
176
              when "1111" => mask(255 downto 224)     := apbi.pwdata;
177
 
178
              when others => null;
179
 
180
            end case;
181
 
182
            -- write back updated pattern/mask
183
            v.trig_conf(tl).pattern := pattern(dbits-1 downto 0);
184
            v.trig_conf(tl).mask    := mask(dbits-1 downto 0);
185
 
186
            -- count/eq 
187
          elsif apbi.paddr(14 downto 13) = "01" then
188
            tl                              := conv_integer(apbi.paddr(7 downto 2));
189
            v.trig_conf(tl).count           := apbi.pwdata(6 downto 1);
190
            v.trig_conf(tl).eq              := apbi.pwdata(0);
191
 
192
            -- arm/reset
193
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00000" then
194
            v.armed := apbi.pwdata(0);
195
 
196
            -- Page reg
197
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00010" then
198
            v.page := apbi.pwdata(3 downto 0);
199
 
200
            -- Trigger counter
201
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00011" then
202
            v.counter := apbi.pwdata(abits-1 downto 0);
203
 
204
            -- div count
205
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00100" then
206
            v.divcount := apbi.pwdata(15 downto 0);
207
 
208
           -- qualifier bit
209
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00101" then
210
            v.qualifier := apbi.pwdata(7 downto 0);
211
            v.qual_val  := apbi.pwdata(8);
212
          end if;
213
        end if;
214
 
215
        -- end write
216
 
217
 
218
        -- Read
219
      else
220
 
221
        -- Read config/status area
222
        if apbi.paddr(15) = '0' then
223
 
224
          -- pattern/mask 
225
          if apbi.paddr(14 downto 13) = "11" then
226
 
227
            tl                              := conv_integer(apbi.paddr(11 downto 6));
228
            pattern(dbits-1 downto 0)       := v.trig_conf(tl).pattern;
229
            mask(dbits-1 downto 0)          := v.trig_conf(tl).mask;
230
 
231
            case apbi.paddr(5 downto 2) is
232
              when "0000" => rdata   := pattern(31 downto 0);
233
              when "0001" => rdata   := pattern(63 downto 32);
234
              when "0010" => rdata   := pattern(95 downto 64);
235
              when "0011" => rdata   := pattern(127 downto 96);
236
              when "0100" => rdata   := pattern(159 downto 128);
237
              when "0101" => rdata   := pattern(191 downto 160);
238
              when "0110" => rdata   := pattern(223 downto 192);
239
              when "0111" => rdata   := pattern(255 downto 224);
240
 
241
              when "1000" => rdata   := mask(31 downto 0);
242
              when "1001" => rdata   := mask(63 downto 32);
243
              when "1010" => rdata   := mask(95 downto 64);
244
              when "1011" => rdata   := mask(127 downto 96);
245
              when "1100" => rdata   := mask(159 downto 128);
246
              when "1101" => rdata   := mask(191 downto 160);
247
              when "1110" => rdata   := mask(223 downto 192);
248
              when "1111" => rdata   := mask(255 downto 224);
249
 
250
              when others => rdata  := (others => '0');
251
            end case;
252
 
253
            -- count/eq
254
          elsif apbi.paddr(14 downto 13) = "01" then
255
            tl                     := conv_integer(apbi.paddr(7 downto 2));
256
            rdata(6 downto 1)      := v.trig_conf(tl).count;
257
            rdata(0)               := v.trig_conf(tl).eq;
258
 
259
            -- status
260
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00000" then
261
            rdata := conv_std_logic_vector(usereg,1) & conv_std_logic_vector(usequal,1) &
262
                     r.armed & r.trigged &
263
                     conv_std_logic_vector(dbits,8)&
264
                     conv_std_logic_vector(depth-1,14)&
265
                     conv_std_logic_vector(trigl,6);
266
 
267
            -- trace buffer index
268
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00001" then
269
            rdata(abits-1 downto 0) := tr.w_addr(abits-1 downto 0);
270
 
271
            -- page reg
272
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00010" then
273
            rdata(3 downto 0) := r.page;
274
 
275
            -- trigger counter
276
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00011" then
277
            rdata(abits-1 downto 0) := r.counter;
278
 
279
            -- divcount
280
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00100" then
281
            rdata(15 downto 0) := r.divcount;
282
 
283
            -- qualifier
284
          elsif apbi.paddr(14 downto 13)&apbi.paddr(4 downto 2) = "00101" then
285
            rdata(7 downto 0) := r.qualifier;
286
            rdata(8) := r.qual_val;
287
          end if;
288
 
289
 
290
          -- Read from trace buffer
291
        else
292
 
293
          -- address always r.page & apbi.paddr(14 downto 5)
294
 
295
          r_en        <= '1';
296
 
297
          -- Select word from pattern
298
          case apbi.paddr(4 downto 2) is
299
          when "000" => rdata   := bufout(31 downto 0);
300
          when "001" => rdata   := bufout(63 downto 32);
301
          when "010" => rdata   := bufout(95 downto 64);
302
          when "011" => rdata   := bufout(127 downto 96);
303
          when "100" => rdata   := bufout(159 downto 128);
304
          when "101" => rdata   := bufout(191 downto 160);
305
          when "110" => rdata   := bufout(223 downto 192);
306
          when "111" => rdata   := bufout(255 downto 224);
307
          when others => rdata := (others => '0');
308
          end case;
309
 
310
        end if;
311
 
312
      end if; -- end read
313
 
314
    end if;
315
 
316
    if rstn = '0' then
317
      v.armed := '0'; v.trigged := '0'; v.finished := '0'; v.trig_demet := '0'; v.fin_demet := '0';
318
      v.counter := (others => '0');
319
      v.divcount := X"0001";
320
      v.qualifier := (others => '0');
321
      v.qual_val := '0';
322
      v.page := (others => '0');
323
    end if;
324
 
325
    apbo.prdata <= rdata;
326
    rin <= v;
327
  end process;
328
 
329
 
330
  -- Combinatorial process for trace clock domain
331
  comb2 : process (rstn, tr, r, sigreg)
332
 
333
    variable v  : trace_reg_type;
334
 
335
  begin
336
    v := tr;
337
 
338
    v.sample := '0';
339
    if tr.armed = '0' then
340
      v.trigged := '0'; v.counter := (others => '0'); v.curr_tl := 0;
341
    end if;
342
 
343
    -- Synch arm signal
344
    v.arm_demet := r.armed;
345
    v.armed := tr.arm_demet;
346
 
347
    if tr.finished = '1' then
348
      v.finished := tr.armed;
349
    end if;
350
 
351
    -- Trigger --
352
    if tr.armed = '1' and tr.finished = '0' then
353
 
354
      if usediv = 1 then
355
        if tr.divcounter = X"0000" then
356
          v.divcounter := r.divcount-1;
357
          if usequal = 0 or sigreg(conv_integer(r.qualifier)) = r.qual_val then
358
            v.sample := '1';
359
          end if;
360
        else
361
          v.divcounter := v.divcounter - 1;
362
        end if;
363
      else
364
        v.sample := '1';
365
      end if;
366
 
367
      if tr.sample = '1' then v.w_addr := tr.w_addr + 1; end if;
368
 
369
      if tr.trigged = '1' and tr.sample = '1' then
370
 
371
        if tr.counter = r.counter then
372
          v.trigged := '0';
373
          v.sample := '0';
374
          v.finished := '1';
375
          v.counter := (others => '0');
376
        else v.counter := tr.counter + 1; end if;
377
 
378
      else
379
 
380
        -- match?
381
        if ((sigreg xor r.trig_conf(tr.curr_tl).pattern) and r.trig_conf(tr.curr_tl).mask) = dz then
382
 
383
          -- trig on equal
384
          if r.trig_conf(tr.curr_tl).eq = '1' then
385
 
386
            if tr.match_count /= r.trig_conf(tr.curr_tl).count then
387
              v.match_count := tr.match_count + 1;
388
            else
389
 
390
              -- final match?
391
              if tr.curr_tl = trigl-1 then
392
                v.trigged := '1';
393
              else
394
                v.curr_tl := tr.curr_tl + 1;
395
              end if;
396
 
397
            end if;
398
 
399
          end if;
400
 
401
        else -- not a match
402
 
403
          -- trig on inequal
404
          if r.trig_conf(tr.curr_tl).eq = '0' then
405
 
406
            if tr.match_count /= r.trig_conf(tr.curr_tl).count then
407
              v.match_count := tr.match_count + 1;
408
            else
409
 
410
              -- final match?
411
              if tr.curr_tl = trigl-1 then
412
                v.trigged := '1';
413
              else
414
                v.curr_tl := tr.curr_tl + 1;
415
              end if;
416
 
417
            end if;
418
          end if;
419
        end if;
420
      end if;
421
    end if;
422
 
423
    -- end trigger
424
 
425
    if rstn = '0' then
426
      v.armed := '0'; v.trigged := '0'; v.sample := '0'; v.finished := '0'; v.arm_demet := '0';
427
      v.curr_tl := 0;
428
      v.counter := (others => '0');
429
      v.divcounter := (others => '0');
430
      v.match_count := (others => '0');
431
      v.w_addr := (others => '0');
432
    end if;
433
 
434
    trin <= v;
435
 
436
  end process;
437
 
438
  -- clk traced signals through register to minimize fan out
439
  inreg: if usereg = 1 generate
440
    process (tclk)
441
    begin
442
      if rising_edge(tclk) then
443
        sigold <= sigreg;
444
        sigreg <= signals;
445
      end if;
446
    end process;
447
  end generate;
448
 
449
  noinreg: if usereg = 0 generate
450
    sigreg <= signals;
451
    sigold <= signals;
452
  end generate;
453
 
454
  -- Update registers
455
  reg: process(clk)
456
  begin
457
    if rising_edge(clk) then r <= rin; end if;
458
  end process;
459
 
460
  treg: process(tclk)
461
  begin
462
    if rising_edge(tclk) then tr <= trin; end if;
463
  end process;
464
 
465
  r_addr    <= r.page & apbi.paddr(14 downto 5);
466
 
467
  trace_buf : syncram_2p
468
    generic map (tech => memtech, abits => abits, dbits => dbits)
469
    port map (clk, r_en, r_addr(abits-1 downto 0), bufout(dbits-1 downto 0),  -- read
470
              tclk, tr.sample, tr.w_addr, sigold);                            -- write
471
 
472
  apbo.pconfig <= pconfig;
473
  apbo.pindex  <= pindex;
474
  apbo.pirq    <= (others => '0');
475
 
476
end architecture;

powered by: WebSVN 2.1.0

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