OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.7/] [rtl/] [ibus/] [ibd_ibmon.vhd] - Blame information for rev 36

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 wfjm
-- $Id: ibd_ibmon.vhd 672 2015-05-02 21:58:28Z mueller $
2
--
3
-- Copyright 2015- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15
-- Module Name:    ibd_ibmon - syn
16
-- Description:    ibus dev: ibus monitor
17
--
18
-- Dependencies:   memlib/ram_1swsr_wfirst_gen
19
--
20
-- Test bench:     -
21
--
22
-- Target Devices: generic
23
-- Tool versions:  xst 14.7; viv 2014.4; ghdl 0.31
24
--
25
-- Synthesized (xst):
26
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
27
-- 2015-04-24   668 14.7  131013 xc6slx16-2   112  235    0   83 s  5.6
28
--
29
-- Revision History: 
30
-- Date         Rev Version  Comment
31
-- 2015-05-02   672   1.0.1  use natural for AWIDTH to work around a ghdl issue
32
-- 2015-04-24   668   1.0    Initial version (derived from rbd_rbmon)
33
------------------------------------------------------------------------------
34
--
35
-- Addr   Bits  Name        r/w/f  Function
36
--  000         cntl        r/w/f  Control register
37
--          05    conena    r/w/-    con enable
38
--          04    remena    r/w/-    rem enable
39
--          03    locena    r/w/-    loc enable
40
--          02    wena      r/w/-    wrap enable
41
--          01    stop      r/w/f    writing 1 stops  moni
42
--          00    start     r/w/f    writing 1 starts moni and clears addr
43
--  001         stat        r/w/-  Status register
44
--       15:13    bsize     r/-/-    buffer size (AWIDTH-9)
45
--          00    wrap      r/-/-    line address wrapped (cleared on go)
46
--  010  12:01  hilim       r/w/-  upper address limit, inclusive (def: 177776)
47
--  011  12:01  lolim       r/w/-  lower address limit, inclusive (def: 160000)
48
--  100         addr        r/w/-  Address register
49
--        *:02    laddr     r/w/-    line address
50
--       01:00    waddr     r/w/-    word address
51
--  101         data        r/w/-  Data register
52
--
53
--     data format:
54
--     word 3     15 : burst      (2nd re/we in a aval sequence)
55
--                14 : tout       (busy in last re-we cycle)
56
--                13 : nak        (no ack in last non-busy cycle)
57
--                12 : ack        (ack  seen)
58
--                11 : busy       (busy seen)
59
--                10 : --         (reserved in case err is implemented)
60
--                09 : we         (write cycle)
61
--                08 : rmw        (read-modify-write)
62
--             07:00 : delay to prev (msb's)
63
--     word 2  15:10 : delay to prev (lsb's)
64
--             09:00 : number of busy cycles
65
--     word 1        : data
66
--     word 0     15 : be1        (byte enable low)
67
--                14 : be0        (byte enable high)
68
--                13 : racc       (remote access)
69
--             12:01 : addr       (word address)
70
--                 0 : cacc       (console access)
71
-- 
72
 
73
 
74
library ieee;
75
use ieee.std_logic_1164.all;
76
use ieee.numeric_std.all;
77
 
78
use work.slvtypes.all;
79
use work.memlib.all;
80
use work.iblib.all;
81
 
82
-- Note: AWIDTH has type natural to allow AWIDTH=0 can be used in if generates
83
--       to control the instantiation. ghdl checks even for not instantiated
84
--       entities the validity of generics, that's why natural needed here ....
85
 
86
entity ibd_ibmon is                     -- ibus dev: ibus monitor
87
  generic (
88
    IB_ADDR : slv16 := slv(to_unsigned(8#160000#,16));  -- base address
89
    AWIDTH : natural := 9);                             -- buffer size
90
  port (
91
    CLK  : in slbit;                    -- clock
92
    RESET : in slbit;                   -- reset
93
    IB_MREQ : in ib_mreq_type;          -- ibus: request
94
    IB_SRES : out ib_sres_type;         -- ibus: response
95
    IB_SRES_SUM : in ib_sres_type       -- ibus: response (sum for monitor)
96
  );
97
end entity ibd_ibmon;
98
 
99
 
100
architecture syn of ibd_ibmon is
101
 
102
  constant ibaddr_cntl  : slv3 := "000";   -- cntl  address offset
103
  constant ibaddr_stat  : slv3 := "001";   -- stat  address offset
104
  constant ibaddr_hilim : slv3 := "010";   -- hilim address offset
105
  constant ibaddr_lolim : slv3 := "011";   -- lolim address offset
106
  constant ibaddr_addr  : slv3 := "100";   -- addr  address offset
107
  constant ibaddr_data  : slv3 := "101";   -- data  address offset
108
 
109
  constant cntl_ibf_conena   : integer :=     5;
110
  constant cntl_ibf_remena   : integer :=     4;
111
  constant cntl_ibf_locena   : integer :=     3;
112
  constant cntl_ibf_wena     : integer :=     2;
113
  constant cntl_ibf_stop     : integer :=     1;
114
  constant cntl_ibf_start    : integer :=     0;
115
  subtype  stat_ibf_bsize   is integer range 15 downto 13;
116
  constant stat_ibf_wrap     : integer :=     0;
117
  subtype  addr_ibf_laddr   is integer range 2+AWIDTH-1 downto  2;
118
  subtype  addr_ibf_waddr   is integer range  1 downto  0;
119
 
120
  subtype  iba_ibf_pref     is integer range 15 downto 13;
121
  subtype  iba_ibf_addr     is integer range 12 downto  1;
122
 
123
  constant dat3_ibf_burst    : integer :=    15;
124
  constant dat3_ibf_tout     : integer :=    14;
125
  constant dat3_ibf_nak      : integer :=    13;
126
  constant dat3_ibf_ack      : integer :=    12;
127
  constant dat3_ibf_busy     : integer :=    11;
128
  constant dat3_ibf_we       : integer :=     9;
129
  constant dat3_ibf_rmw      : integer :=     8;
130
  subtype  dat3_ibf_ndlymsb is integer range  7 downto  0;
131
  subtype  dat2_ibf_ndlylsb is integer range 15 downto 10;
132
  subtype  dat2_ibf_nbusy   is integer range  9 downto  0;
133
  constant dat0_ibf_be1      : integer :=    15;
134
  constant dat0_ibf_be0      : integer :=    14;
135
  constant dat0_ibf_racc     : integer :=    13;
136
  subtype  dat0_ibf_addr    is integer range 12 downto  1;
137
  constant dat0_ibf_cacc     : integer :=     0;
138
 
139
  type regs_type is record              -- state registers
140
    ibsel : slbit;                      -- ibus select
141
    conena : slbit;                     -- conena flag (record console access)
142
    remena : slbit;                     -- remena flag (record remote access)
143
    locena : slbit;                     -- locena flag (record local access)
144
    wena : slbit;                       -- wena flag (wrap enable)
145
    go : slbit;                         -- go flag
146
    hilim : slv13_1;                    -- upper address limit
147
    lolim : slv13_1;                    -- lower address limit
148
    wrap : slbit;                       -- laddr wrap flag
149
    laddr : slv(AWIDTH-1 downto 0);     -- line address
150
    waddr : slv2;                       -- word address
151
    ibtake_1 : slbit;                   -- ib capture active in last cycle
152
    ibaddr  : slv13_1;                  -- ibus trace: addr
153
    ibwe    : slbit;                    -- ibus trace: we
154
    ibrmw   : slbit;                    -- ibus trace: rmw
155
    ibbe0   : slbit;                    -- ibus trace: be0
156
    ibbe1   : slbit;                    -- ibus trace: be1
157
    ibcacc  : slbit;                    -- ibus trace: cacc
158
    ibracc  : slbit;                    -- ibus trace: racc
159
    iback   : slbit;                    -- ibus trace: ack  seen
160
    ibbusy  : slbit;                    -- ibus trace: busy seen
161
    ibnak   : slbit;                    -- ibus trace: nak  detected
162
    ibtout  : slbit;                    -- ibus trace: tout detected
163
    ibburst : slbit;                    -- ibus trace: burst detected
164
    ibdata  : slv16;                    -- ibus trace: data
165
    ibnbusy : slv10;                    -- ibus number of busy cycles
166
    ibndly  : slv14;                    -- ibus delay to prev. access
167
  end record regs_type;
168
 
169
  constant laddrzero : slv(AWIDTH-1 downto 0) := (others=>'0');
170
  constant laddrlast : slv(AWIDTH-1 downto 0) := (others=>'1');
171
 
172
  constant regs_init : regs_type := (
173
    '0',                                -- ibsel
174
    '1','1','1','1','1',                -- conena,remena,locena,wena,go
175
    (others=>'1'),                      -- hilim (def: 177776)
176
    (others=>'0'),                      -- lolim (def: 160000)
177
    '0',                                -- wrap
178
    laddrzero,                          -- laddr
179
    "00",                               -- waddr
180
    '0',                                -- ibtake_1
181
    (others=>'0'),                      -- ibaddr
182
    '0','0','0','0','0','0',            -- ibwe,ibrmw,ibbe0,ibbe1,ibcacc,ibracc
183
    '0','0',                            -- iback,ibbusy
184
    '0','0','0',                        -- ibnak,ibtout,ibburst
185
    (others=>'0'),                      -- ibdata
186
    (others=>'0'),                      -- ibnbusy
187
    (others=>'0')                       -- ibndly
188
  );
189
 
190
  constant ibnbusylast : slv10 := (others=>'1');
191
  constant ibndlylast  : slv14 := (others=>'1');
192
 
193
  signal R_REGS : regs_type := regs_init;
194
  signal N_REGS : regs_type := regs_init;
195
 
196
  signal BRAM_EN : slbit := '0';
197
  signal BRAM_WE : slbit := '0';
198
  signal BRAM0_DI : slv32 := (others=>'0');
199
  signal BRAM1_DI : slv32 := (others=>'0');
200
  signal BRAM0_DO : slv32 := (others=>'0');
201
  signal BRAM1_DO : slv32 := (others=>'0');
202
 
203
begin
204
 
205
  assert AWIDTH>=9 and AWIDTH<=14
206
    report "assert(AWIDTH>=9 and AWIDTH<=14): unsupported AWIDTH"
207
    severity failure;
208
 
209
  BRAM1 : ram_1swsr_wfirst_gen
210
    generic map (
211
      AWIDTH => AWIDTH,
212
      DWIDTH => 32)
213
    port map (
214
      CLK   => CLK,
215
      EN    => BRAM_EN,
216
      WE    => BRAM_WE,
217
      ADDR  => R_REGS.laddr,
218
      DI    => BRAM1_DI,
219
      DO    => BRAM1_DO
220
    );
221
 
222
  BRAM0 : ram_1swsr_wfirst_gen
223
    generic map (
224
      AWIDTH => AWIDTH,
225
      DWIDTH => 32)
226
    port map (
227
      CLK   => CLK,
228
      EN    => BRAM_EN,
229
      WE    => BRAM_WE,
230
      ADDR  => R_REGS.laddr,
231
      DI    => BRAM0_DI,
232
      DO    => BRAM0_DO
233
    );
234
 
235
  proc_regs: process (CLK)
236
  begin
237
    if rising_edge(CLK) then
238
      if RESET = '1' then
239
        R_REGS <= regs_init;
240
      else
241
        R_REGS <= N_REGS;
242
      end if;
243
    end if;
244
  end process proc_regs;
245
 
246
  proc_next : process (R_REGS, IB_MREQ, IB_SRES_SUM, BRAM0_DO, BRAM1_DO)
247
    variable r : regs_type := regs_init;
248
    variable n : regs_type := regs_init;
249
    variable iib_ack  : slbit := '0';
250
    variable iib_busy : slbit := '0';
251
    variable iib_dout  : slv16 := (others=>'0');
252
    variable iibena  : slbit := '0';
253
    variable ibramen : slbit := '0';    -- BRAM enable
254
    variable ibramwe : slbit := '0';    -- BRAN we
255
    variable ibtake : slbit := '0';
256
    variable laddr_inc : slbit := '0';
257
    variable idat0 : slv16 := (others=>'0');
258
    variable idat1 : slv16 := (others=>'0');
259
    variable idat2 : slv16 := (others=>'0');
260
    variable idat3 : slv16 := (others=>'0');
261
  begin
262
 
263
    r := R_REGS;
264
    n := R_REGS;
265
 
266
    iib_ack  := '0';
267
    iib_busy := '0';
268
    iib_dout := (others=>'0');
269
 
270
    iibena  := IB_MREQ.re or IB_MREQ.we;
271
 
272
    ibramen := '0';
273
    ibramwe := '0';
274
 
275
    laddr_inc := '0';
276
 
277
    -- ibus address decoder
278
    n.ibsel := '0';
279
    if IB_MREQ.aval='1' and IB_MREQ.addr(12 downto 4)=IB_ADDR(12 downto 4) then
280
      n.ibsel := '1';
281
      ibramen := '1';
282
    end if;
283
 
284
    -- ibus transactions (react only on console (this includes racc))
285
    if r.ibsel = '1' and IB_MREQ.cacc='1' then
286
 
287
      iib_ack := iibena;                -- ack all accesses
288
 
289
      case IB_MREQ.addr(3 downto 1) is
290
 
291
        when ibaddr_cntl =>                 -- cntl ------------------
292
          if IB_MREQ.we = '1' then
293
            n.conena := IB_MREQ.din(cntl_ibf_conena);
294
            n.remena := IB_MREQ.din(cntl_ibf_remena);
295
            n.locena := IB_MREQ.din(cntl_ibf_locena);
296
            n.wena   := IB_MREQ.din(cntl_ibf_wena);
297
            if IB_MREQ.din(cntl_ibf_start) = '1' then
298
              n.go    := '1';
299
              n.wrap  := '0';
300
              n.laddr := laddrzero;
301
              n.waddr := "00";
302
            end if;
303
            if IB_MREQ.din(cntl_ibf_stop) = '1' then
304
              n.go    := '0';
305
            end if;
306
          end if;
307
 
308
        when ibaddr_stat => null;           -- stat ------------------
309
 
310
        when ibaddr_hilim =>                -- hilim -----------------
311
          if IB_MREQ.we = '1' then
312
            n.hilim := IB_MREQ.din(iba_ibf_addr);
313
          end if;
314
 
315
        when ibaddr_lolim =>                -- lolim -----------------
316
          if IB_MREQ.we = '1' then
317
            n.lolim := IB_MREQ.din(iba_ibf_addr);
318
          end if;
319
 
320
        when ibaddr_addr =>                 -- addr ------------------
321
          if IB_MREQ.we = '1' then
322
            n.go    := '0';
323
            n.wrap  := '0';
324
            n.laddr := IB_MREQ.din(addr_ibf_laddr);
325
            n.waddr := IB_MREQ.din(addr_ibf_waddr);
326
          end if;
327
 
328
        when ibaddr_data =>                 -- data ------------------
329
          if r.go='1' or IB_MREQ.we='1' then
330
            iib_ack := '0';                   -- error, do nak
331
          end if;
332
          if IB_MREQ.re = '1' then
333
            n.waddr := slv(unsigned(r.waddr) + 1);
334
            if r.waddr = "11" then
335
              laddr_inc := '1';
336
            end if;
337
          end if;
338
 
339
        when others =>                      -- <> --------------------
340
          iib_ack := '0';                     -- error, do nak
341
 
342
      end case;
343
    end if;
344
 
345
    -- ibus output driver
346
    if r.ibsel = '1' then
347
      case IB_MREQ.addr(3 downto 1) is
348
        when ibaddr_cntl =>                 -- cntl ------------------
349
          iib_dout(cntl_ibf_conena) := r.conena;
350
          iib_dout(cntl_ibf_remena) := r.remena;
351
          iib_dout(cntl_ibf_locena) := r.locena;
352
          iib_dout(cntl_ibf_wena)   := r.wena;
353
          iib_dout(cntl_ibf_start)  := r.go;
354
        when ibaddr_stat =>                 -- stat ------------------
355
          iib_dout(stat_ibf_bsize) := slv(to_unsigned(AWIDTH-9,3));
356
          iib_dout(stat_ibf_wrap)  := r.wrap;
357
        when ibaddr_hilim =>                -- hilim -----------------
358
          iib_dout(iba_ibf_pref)   := (others=>'1');
359
          iib_dout(iba_ibf_addr)   := r.hilim;
360
        when ibaddr_lolim =>                -- lolim -----------------
361
          iib_dout(iba_ibf_pref)   := (others=>'1');
362
          iib_dout(iba_ibf_addr)   := r.lolim;
363
        when ibaddr_addr =>                 -- addr ------------------
364
          iib_dout(addr_ibf_laddr) := r.laddr;
365
          iib_dout(addr_ibf_waddr) := r.waddr;
366
        when ibaddr_data =>                 -- data ------------------
367
          case r.waddr is
368
            when "11" => iib_dout := BRAM1_DO(31 downto 16);
369
            when "10" => iib_dout := BRAM1_DO(15 downto  0);
370
            when "01" => iib_dout := BRAM0_DO(31 downto 16);
371
            when "00" => iib_dout := BRAM0_DO(15 downto  0);
372
            when others => null;
373
          end case;
374
        when others => null;
375
      end case;
376
    end if;
377
 
378
    -- ibus monitor 
379
    --   a ibus transaction are captured if the address is in alim window
380
    --   and the access is not refering to ibd_ibmon itself
381
 
382
    ibtake := '0';
383
    if IB_MREQ.aval='1' and iibena='1' then              -- aval and (re or we)
384
      if unsigned(IB_MREQ.addr)>=unsigned(r.lolim) and   -- and in addr window
385
         unsigned(IB_MREQ.addr)<=unsigned(r.hilim) and
386
         r.ibsel='0' then                                -- and not self
387
        if (r.locena='1' and IB_MREQ.cacc='0' and IB_MREQ.racc='0') or
388
           (r.remena='1' and IB_MREQ.racc='1') or
389
           (r.conena='1' and IB_MREQ.cacc='1') then
390
          ibtake := '1';
391
        end if;
392
      end if;
393
    end if;
394
 
395
    if ibtake = '1' then                -- if capture active
396
      n.ibaddr := IB_MREQ.addr;           -- keep track of some state
397
      n.ibwe   := IB_MREQ.we;
398
      n.ibrmw  := IB_MREQ.rmw;
399
      n.ibbe0  := IB_MREQ.be0;
400
      n.ibbe1  := IB_MREQ.be1;
401
      n.ibcacc := IB_MREQ.cacc;
402
      n.ibracc := IB_MREQ.racc;
403
      if IB_MREQ.we='1' then                -- for write of din
404
        n.ibdata := IB_MREQ.din;
405
      else                                  -- for read of dout
406
        n.ibdata := IB_SRES_SUM.dout;
407
      end if;
408
 
409
      if r.ibtake_1 = '0' then            -- if initial cycle of a transaction
410
        n.iback  := IB_SRES_SUM.ack;
411
        n.ibbusy := IB_SRES_SUM.busy;
412
        n.ibnbusy := (others=>'0');
413
      else                                -- if non-initial cycles
414
        if r.ibnbusy /= ibnbusylast then      -- and count  
415
          n.ibnbusy := slv(unsigned(r.ibnbusy) + 1);
416
        end if;
417
      end if;
418
      n.ibnak  := not IB_SRES_SUM.ack;
419
      n.ibtout := IB_SRES_SUM.busy;
420
 
421
    else                                -- if capture not active
422
      if r.go='1' and r.ibtake_1='1' then -- active and transaction just ended
423
        ibramen := '1';
424
        ibramwe := '1';
425
        laddr_inc := '1';
426
        n.ibburst := '1';                   -- assume burst
427
      end if;
428
      if r.ibtake_1 = '1' then            -- ibus transaction just ended
429
        n.ibndly := (others=>'0');          -- clear delay counter
430
      else                                -- just idle
431
        if r.ibndly /= ibndlylast then      -- count cycles
432
          n.ibndly := slv(unsigned(r.ibndly) + 1);
433
        end if;
434
      end if;
435
    end if;
436
 
437
    if IB_MREQ.aval = '0' then          -- if aval gone
438
      n.ibburst := '0';                   -- clear burst flag
439
    end if;
440
 
441
    if laddr_inc = '1' then
442
      n.laddr := slv(unsigned(r.laddr) + 1);
443
      if r.go='1' and r.laddr=laddrlast then
444
        if r.wena = '1' then
445
          n.wrap := '1';
446
        else
447
          n.go   := '0';
448
        end if;
449
      end if;
450
    end if;
451
 
452
    idat3 := (others=>'0');
453
    idat3(dat3_ibf_burst)  := r.ibburst;
454
    idat3(dat3_ibf_tout)   := r.ibtout;
455
    idat3(dat3_ibf_nak)    := r.ibnak;
456
    idat3(dat3_ibf_ack)    := r.iback;
457
    idat3(dat3_ibf_busy)   := r.ibbusy;
458
    idat3(dat3_ibf_we)     := r.ibwe;
459
    idat3(dat3_ibf_rmw)    := r.ibrmw;
460
    idat3(dat3_ibf_ndlymsb):= r.ibndly(13 downto 6);
461
    idat2(dat2_ibf_ndlylsb):= r.ibndly( 5 downto 0);
462
    idat2(dat2_ibf_nbusy)  := r.ibnbusy;
463
    idat1                  := r.ibdata;
464
    idat0(dat0_ibf_be1)    := r.ibbe1;
465
    idat0(dat0_ibf_be0)    := r.ibbe0;
466
    idat0(dat0_ibf_racc)   := r.ibracc;
467
    idat0(dat0_ibf_addr)   := r.ibaddr;
468
    idat0(dat0_ibf_cacc)   := r.ibcacc;
469
 
470
    n.ibtake_1 := ibtake;
471
 
472
    N_REGS <= n;
473
 
474
    BRAM_EN <= ibramen;
475
    BRAM_WE <= ibramwe;
476
 
477
    BRAM1_DI <= idat3 & idat2;
478
    BRAM0_DI <= idat1 & idat0;
479
 
480
    IB_SRES.dout <= iib_dout;
481
    IB_SRES.ack  <= iib_ack;
482
    IB_SRES.busy <= iib_busy;
483
 
484
  end process proc_next;
485
 
486
end syn;

powered by: WebSVN 2.1.0

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