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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [vlib/] [rbus/] [rbd_rbmon.vhd] - Blame information for rev 38

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 wfjm
-- $Id: rbd_rbmon.vhd 758 2016-04-02 18:01:39Z mueller $
2 10 wfjm
--
3 30 wfjm
-- Copyright 2010-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 10 wfjm
--
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:    rbd_rbmon - syn
16
-- Description:    rbus dev: rbus monitor
17
--
18
-- Dependencies:   memlib/ram_1swsr_wfirst_gen
19
--
20
-- Test bench:     rlink/tb/tb_rlink_tba_ttcombo
21
--
22
-- Target Devices: generic
23 36 wfjm
-- Tool versions:  xst 12.1-14.7; viv 2014.4-2015.4; ghdl 0.29-0.33
24 10 wfjm
--
25
-- Synthesized (xst):
26
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
27 28 wfjm
-- 2014-12-22   619 14.7  131013 xc6slx16-2   114  209    -   72 s  5.6
28
-- 2014-12-21   593 14.7  131013 xc6slx16-2    99  207    -   77 s  7.0
29 10 wfjm
-- 2010-12-27   349 12.1    M53d xc3s1000-4    95  228    -  154 s 10.4
30
--
31
-- Revision History: 
32
-- Date         Rev Version  Comment
33 30 wfjm
-- 2015-05-02   672   5.0.1  use natural for AWIDTH to work around a ghdl issue
34 28 wfjm
-- 2014-12-22   619   5.0    reorganized, supports now 16 bit addresses
35 27 wfjm
-- 2014-09-13   593   4.1    change default address -> ffe8
36 28 wfjm
-- 2014-08-15   583   4.0    rb_mreq addr now 16 bit (but only 8 bit recorded)
37 13 wfjm
-- 2011-11-19   427   1.0.3  now numeric_std clean
38 10 wfjm
-- 2011-03-27   374   1.0.2  rename ncyc -> nbusy because it counts busy cycles
39
-- 2010-12-31   352   1.0.1  simplify irb_ack logic
40
-- 2010-12-27   349   1.0    Initial version 
41
------------------------------------------------------------------------------
42
--
43 28 wfjm
-- Addr   Bits  Name        r/w/f  Function
44
--  000         cntl        r/w/f  Control register
45
--          02    wena      r/w/-    wrap enable
46
--          01    stop      r/w/f    writing 1 stops  moni
47
--          00    start     r/w/f    writing 1 starts moni and clears addr
48
--  001         stat        r/w/-  Status register
49 30 wfjm
--       15:13    bsize     r/-/-    buffer size (AWIDTH-9)
50 28 wfjm
--          00    wrap      r/-/-    line address wrapped (cleared on go)
51 30 wfjm
--  010         hilim       r/w/-  upper address limit, inclusive (def: 0xfffb)
52
--  011         lolim       r/w/-  lower address limit, inclusive (def: 0x0000)
53 28 wfjm
--  100         addr        r/w/-  Address register
54
--        *:02    laddr     r/w/-    line address
55
--       01:00    waddr     r/w/-    word address
56
--  101         data        r/w/-  Data register
57 10 wfjm
--
58
--     data format:
59 28 wfjm
--     word 3     15 : burst      (2nd re/we in a aval sequence)
60
--                14 : tout       (busy in last re-we cycle)
61
--                13 : nak        (no ack in last non-busy cycle)
62
--                12 : ack        (ack  seen)
63
--                11 : busy       (busy seen)
64
--                10 : err        (err  seen)
65
--                09 : we         (write cycle)
66
--                08 : init       (init  cycle)
67
--             07:00 : delay to prev (msb's)
68
--     word 2  15:10 : delay to prev (lsb's)
69
--             09:00 : number of busy cycles
70
--     word 1        : data
71
--     word 0        : addr
72 10 wfjm
-- 
73
 
74
 
75
library ieee;
76
use ieee.std_logic_1164.all;
77 13 wfjm
use ieee.numeric_std.all;
78 10 wfjm
 
79
use work.slvtypes.all;
80
use work.memlib.all;
81
use work.rblib.all;
82
 
83 30 wfjm
-- Note: AWIDTH has type natural to allow AWIDTH=0 can be used in if generates
84
--       to control the instantiation. ghdl checks even for not instantiated
85
--       entities the validity of generics, that's why natural needed here ....
86
 
87 10 wfjm
entity rbd_rbmon is                     -- rbus dev: rbus monitor
88
  generic (
89 27 wfjm
    RB_ADDR : slv16 := slv(to_unsigned(16#ffe8#,16));
90 30 wfjm
    AWIDTH : natural := 9);
91 10 wfjm
  port (
92
    CLK  : in slbit;                    -- clock
93
    RESET : in slbit;                   -- reset
94
    RB_MREQ : in rb_mreq_type;          -- rbus: request
95
    RB_SRES : out rb_sres_type;         -- rbus: response
96
    RB_SRES_SUM : in rb_sres_type       -- rbus: response (sum for monitor)
97
  );
98
end entity rbd_rbmon;
99
 
100
 
101
architecture syn of rbd_rbmon is
102
 
103 28 wfjm
  constant rbaddr_cntl  : slv3 := "000";   -- cntl  address offset
104
  constant rbaddr_stat  : slv3 := "001";   -- stat  address offset
105
  constant rbaddr_hilim : slv3 := "010";   -- hilim address offset
106
  constant rbaddr_lolim : slv3 := "011";   -- lolim address offset
107
  constant rbaddr_addr  : slv3 := "100";   -- addr  address offset
108
  constant rbaddr_data  : slv3 := "101";   -- data  address offset
109 10 wfjm
 
110 28 wfjm
  constant cntl_rbf_wena     : integer :=     2;
111
  constant cntl_rbf_stop     : integer :=     1;
112
  constant cntl_rbf_start    : integer :=     0;
113
  subtype  stat_rbf_bsize   is integer range 15 downto 13;
114
  constant stat_rbf_wrap     : integer :=     0;
115 10 wfjm
  subtype  addr_rbf_laddr   is integer range 2+AWIDTH-1 downto  2;
116
  subtype  addr_rbf_waddr   is integer range  1 downto  0;
117
 
118 28 wfjm
  constant dat3_rbf_burst    : integer :=    15;
119
  constant dat3_rbf_tout     : integer :=    14;
120
  constant dat3_rbf_nak      : integer :=    13;
121
  constant dat3_rbf_ack      : integer :=    12;
122
  constant dat3_rbf_busy     : integer :=    11;
123
  constant dat3_rbf_err      : integer :=    10;
124
  constant dat3_rbf_we       : integer :=     9;
125
  constant dat3_rbf_init     : integer :=     8;
126
  subtype  dat3_rbf_ndlymsb is integer range  7 downto  0;
127
  subtype  dat2_rbf_ndlylsb is integer range 15 downto 10;
128
  subtype  dat2_rbf_nbusy   is integer range  9 downto  0;
129 10 wfjm
 
130
  type regs_type is record              -- state registers
131
    rbsel : slbit;                      -- rbus select
132 28 wfjm
    wena : slbit;                       -- wena flag (wrap enable)
133 10 wfjm
    go : slbit;                         -- go flag
134 28 wfjm
    hilim : slv16;                      -- upper address limit
135
    lolim : slv16;                      -- lower address limit
136 10 wfjm
    wrap : slbit;                       -- laddr wrap flag
137
    laddr : slv(AWIDTH-1 downto 0);     -- line address
138
    waddr : slv2;                       -- word address
139
    rbtake_1 : slbit;                   -- rb capture active in last cycle
140 28 wfjm
    rbaddr  : slv16;                    -- rbus trace: addr
141 10 wfjm
    rbinit  : slbit;                    -- rbus trace: init
142
    rbwe    : slbit;                    -- rbus trace: we
143
    rback   : slbit;                    -- rbus trace: ack  seen
144
    rbbusy  : slbit;                    -- rbus trace: busy seen
145
    rberr   : slbit;                    -- rbus trace: err  seen
146
    rbnak   : slbit;                    -- rbus trace: nak  detected
147
    rbtout  : slbit;                    -- rbus trace: tout detected
148 28 wfjm
    rbburst : slbit;                    -- rbus trace: burst detected
149 10 wfjm
    rbdata  : slv16;                    -- rbus trace: data
150 28 wfjm
    rbnbusy : slv10;                    -- rbus number of busy cycles
151
    rbndly  : slv14;                    -- rbus delay to prev. access
152 10 wfjm
  end record regs_type;
153
 
154
  constant laddrzero : slv(AWIDTH-1 downto 0) := (others=>'0');
155
  constant laddrlast : slv(AWIDTH-1 downto 0) := (others=>'1');
156
 
157
  constant regs_init : regs_type := (
158
    '0',                                -- rbsel
159 28 wfjm
    '0','0',                            -- wena,go
160
    x"fffb",                            -- hilim (def: fffb)
161
    x"0000",                            -- lolim (def: 0000)
162 10 wfjm
    '0',                                -- wrap
163
    laddrzero,                          -- laddr
164
    "00",                               -- waddr
165
    '0',                                -- rbtake_1
166
    (others=>'0'),                      -- rbaddr
167
    '0','0','0','0','0',                -- rbinit,rbwe,rback,rbbusy,rberr
168 28 wfjm
    '0','0','0',                        -- rbnak,rbtout,rbburst
169 10 wfjm
    (others=>'0'),                      -- rbdata
170
    (others=>'0'),                      -- rbnbusy
171
    (others=>'0')                       -- rbndly
172
  );
173
 
174 28 wfjm
  constant rbnbusylast : slv10 := (others=>'1');
175
  constant rbndlylast  : slv14 := (others=>'1');
176 10 wfjm
 
177
  signal R_REGS : regs_type := regs_init;
178
  signal N_REGS : regs_type := regs_init;
179
 
180
  signal BRAM_EN : slbit := '0';
181
  signal BRAM_WE : slbit := '0';
182
  signal BRAM0_DI : slv32 := (others=>'0');
183
  signal BRAM1_DI : slv32 := (others=>'0');
184
  signal BRAM0_DO : slv32 := (others=>'0');
185
  signal BRAM1_DO : slv32 := (others=>'0');
186
 
187
begin
188
 
189 28 wfjm
  assert AWIDTH>=9 and AWIDTH<=14
190
    report "assert(AWIDTH>=9 and AWIDTH<=14): unsupported AWIDTH"
191 10 wfjm
    severity failure;
192
 
193
  BRAM1 : ram_1swsr_wfirst_gen
194
    generic map (
195
      AWIDTH => AWIDTH,
196
      DWIDTH => 32)
197
    port map (
198
      CLK   => CLK,
199
      EN    => BRAM_EN,
200
      WE    => BRAM_WE,
201
      ADDR  => R_REGS.laddr,
202
      DI    => BRAM1_DI,
203
      DO    => BRAM1_DO
204
    );
205
 
206
  BRAM0 : ram_1swsr_wfirst_gen
207
    generic map (
208
      AWIDTH => AWIDTH,
209
      DWIDTH => 32)
210
    port map (
211
      CLK   => CLK,
212
      EN    => BRAM_EN,
213
      WE    => BRAM_WE,
214
      ADDR  => R_REGS.laddr,
215
      DI    => BRAM0_DI,
216
      DO    => BRAM0_DO
217
    );
218
 
219
  proc_regs: process (CLK)
220
  begin
221 13 wfjm
    if rising_edge(CLK) then
222 10 wfjm
      if RESET = '1' then
223
        R_REGS <= regs_init;
224
      else
225
        R_REGS <= N_REGS;
226
      end if;
227
    end if;
228
  end process proc_regs;
229
 
230
  proc_next : process (R_REGS, RB_MREQ, RB_SRES_SUM, BRAM0_DO, BRAM1_DO)
231
    variable r : regs_type := regs_init;
232
    variable n : regs_type := regs_init;
233
    variable irb_ack  : slbit := '0';
234
    variable irb_busy : slbit := '0';
235
    variable irb_err  : slbit := '0';
236
    variable irb_dout  : slv16 := (others=>'0');
237
    variable irbena  : slbit := '0';
238 28 wfjm
    variable ibramen : slbit := '0';    -- BRAM enable
239
    variable ibramwe : slbit := '0';    -- BRAN we
240 10 wfjm
    variable rbtake : slbit := '0';
241
    variable laddr_inc : slbit := '0';
242
    variable idat0 : slv16 := (others=>'0');
243
    variable idat1 : slv16 := (others=>'0');
244
    variable idat2 : slv16 := (others=>'0');
245
    variable idat3 : slv16 := (others=>'0');
246
  begin
247
 
248
    r := R_REGS;
249
    n := R_REGS;
250
 
251
    irb_ack  := '0';
252
    irb_busy := '0';
253
    irb_err  := '0';
254
    irb_dout := (others=>'0');
255
 
256
    irbena  := RB_MREQ.re or RB_MREQ.we;
257
 
258
    ibramen := '0';
259
    ibramwe := '0';
260
 
261
    laddr_inc := '0';
262
 
263
    -- rbus address decoder
264
    n.rbsel := '0';
265 28 wfjm
    if RB_MREQ.aval='1' and RB_MREQ.addr(15 downto 3)=RB_ADDR(15 downto 3) then
266 10 wfjm
      n.rbsel := '1';
267
      ibramen := '1';
268
    end if;
269
 
270
    -- rbus transactions
271
    if r.rbsel = '1' then
272
 
273 28 wfjm
      irb_ack := irbena;                -- ack all accesses
274 10 wfjm
 
275 28 wfjm
      case RB_MREQ.addr(2 downto 0) is
276 10 wfjm
 
277 28 wfjm
        when rbaddr_cntl =>                 -- cntl ------------------
278 10 wfjm
          if RB_MREQ.we = '1' then
279 28 wfjm
            n.wena := RB_MREQ.din(cntl_rbf_wena);
280
            if RB_MREQ.din(cntl_rbf_start) = '1' then
281
              n.go    := '1';
282 10 wfjm
              n.wrap  := '0';
283
              n.laddr := laddrzero;
284
              n.waddr := "00";
285
            end if;
286 28 wfjm
            if RB_MREQ.din(cntl_rbf_stop) = '1' then
287
              n.go    := '0';
288
            end if;
289 10 wfjm
          end if;
290
 
291 28 wfjm
        when rbaddr_stat => null;           -- stat ------------------
292
 
293
        when rbaddr_hilim =>                -- hilim -----------------
294 10 wfjm
          if RB_MREQ.we = '1' then
295 28 wfjm
            n.hilim := RB_MREQ.din;
296 10 wfjm
          end if;
297
 
298 28 wfjm
        when rbaddr_lolim =>                -- lolim -----------------
299 10 wfjm
          if RB_MREQ.we = '1' then
300 28 wfjm
            n.lolim := RB_MREQ.din;
301
          end if;
302
 
303
        when rbaddr_addr =>                 -- addr ------------------
304
          if RB_MREQ.we = '1' then
305 10 wfjm
            n.go    := '0';
306
            n.wrap  := '0';
307
            n.laddr := RB_MREQ.din(addr_rbf_laddr);
308
            n.waddr := RB_MREQ.din(addr_rbf_waddr);
309
          end if;
310
 
311 28 wfjm
        when rbaddr_data =>                 -- data ------------------
312 10 wfjm
          if r.go='1' or RB_MREQ.we='1' then
313
            irb_err := '1';
314
          end if;
315
          if RB_MREQ.re = '1' then
316 13 wfjm
            n.waddr := slv(unsigned(r.waddr) + 1);
317 10 wfjm
            if r.waddr = "11" then
318
              laddr_inc := '1';
319
            end if;
320
          end if;
321
 
322 28 wfjm
        when others =>                      -- <> --------------------
323
          irb_err := '1';
324
 
325 10 wfjm
      end case;
326
    end if;
327
 
328
    -- rbus output driver
329
    if r.rbsel = '1' then
330 28 wfjm
      case RB_MREQ.addr(2 downto 0) is
331
        when rbaddr_cntl =>                 -- cntl ------------------
332
          irb_dout(cntl_rbf_wena)  := r.wena;
333
          irb_dout(cntl_rbf_start) := r.go;
334
        when rbaddr_stat =>                 -- stat ------------------
335
          irb_dout(stat_rbf_bsize) := slv(to_unsigned(AWIDTH-9,3));
336
          irb_dout(stat_rbf_wrap)  := r.wrap;
337
        when rbaddr_hilim =>                -- hilim -----------------
338
          irb_dout                 := r.hilim;
339
        when rbaddr_lolim =>                -- lolim -----------------
340
          irb_dout                 := r.lolim;
341
        when rbaddr_addr =>                 -- addr ------------------
342 10 wfjm
          irb_dout(addr_rbf_laddr) := r.laddr;
343
          irb_dout(addr_rbf_waddr) := r.waddr;
344 28 wfjm
        when rbaddr_data =>                 -- data ------------------
345 10 wfjm
          case r.waddr is
346
            when "11" => irb_dout := BRAM1_DO(31 downto 16);
347
            when "10" => irb_dout := BRAM1_DO(15 downto  0);
348
            when "01" => irb_dout := BRAM0_DO(31 downto 16);
349
            when "00" => irb_dout := BRAM0_DO(15 downto  0);
350
            when others => null;
351
          end case;
352
        when others => null;
353
      end case;
354
    end if;
355
 
356
    -- rbus monitor 
357
    --   a rbus transaction are captured if the address is in alim window
358
    --   and the access is not refering to rbd_rbmon itself
359
 
360
    rbtake := '0';
361
    if RB_MREQ.aval='1' and irbena='1' then              -- aval and (re or we)
362 28 wfjm
      if unsigned(RB_MREQ.addr)>=unsigned(r.lolim) and   -- and in addr window
363
         unsigned(RB_MREQ.addr)<=unsigned(r.hilim) and
364 10 wfjm
         r.rbsel='0' then                                -- and not self
365
        rbtake := '1';
366
      end if;
367
    end if;
368
    if RB_MREQ.init = '1' then                           -- also take init's
369
      rbtake := '1';
370
    end if;
371
 
372
    if rbtake = '1' then                -- if capture active
373 28 wfjm
      n.rbaddr := RB_MREQ.addr;           -- keep track of some state
374 10 wfjm
      n.rbinit := RB_MREQ.init;
375
      n.rbwe   := RB_MREQ.we;
376
      if RB_MREQ.init='1' or RB_MREQ.we='1' then  -- for write/init of din
377
        n.rbdata := RB_MREQ.din;
378
      else                                        -- for read of dout
379
        n.rbdata := RB_SRES_SUM.dout;
380
      end if;
381
 
382
      if r.rbtake_1 = '0' then            -- if initial cycle of a transaction
383
        n.rback  := RB_SRES_SUM.ack;
384
        n.rbbusy := RB_SRES_SUM.busy;
385
        n.rberr  := RB_SRES_SUM.err;
386
        n.rbnbusy := (others=>'0');
387
      else                                -- if non-initial cycles
388
        if RB_SRES_SUM.err = '1' then       -- keep track of err flags
389
          n.rberr := '1';
390
        end if;
391
        if r.rbnbusy /= rbnbusylast then      -- and count  
392 13 wfjm
          n.rbnbusy := slv(unsigned(r.rbnbusy) + 1);
393 10 wfjm
        end if;
394
      end if;
395
      n.rbnak  := not RB_SRES_SUM.ack;
396
      n.rbtout := RB_SRES_SUM.busy;
397
 
398
    else                                -- if capture not active
399
      if r.go='1' and r.rbtake_1='1' then -- active and transaction just ended
400
        ibramen := '1';
401
        ibramwe := '1';
402
        laddr_inc := '1';
403 28 wfjm
        n.rbburst := '1';                   -- assume burst
404 10 wfjm
      end if;
405
      if r.rbtake_1 = '1' then            -- rbus transaction just ended
406
        n.rbndly := (others=>'0');          -- clear delay counter
407
      else                                -- just idle
408
        if r.rbndly /= rbndlylast then      -- count cycles
409 13 wfjm
          n.rbndly := slv(unsigned(r.rbndly) + 1);
410 10 wfjm
        end if;
411
      end if;
412
    end if;
413
 
414 28 wfjm
    if RB_MREQ.aval = '0' then          -- if aval gone
415
      n.rbburst := '0';                   -- clear burst flag
416
    end if;
417
 
418 10 wfjm
    if laddr_inc = '1' then
419 13 wfjm
      n.laddr := slv(unsigned(r.laddr) + 1);
420 10 wfjm
      if r.go='1' and r.laddr=laddrlast then
421 28 wfjm
        if r.wena = '1' then
422
          n.wrap := '1';
423
        else
424
          n.go   := '0';
425
        end if;
426 10 wfjm
      end if;
427
    end if;
428
 
429
    idat3 := (others=>'0');
430 28 wfjm
    idat3(dat3_rbf_burst)  := r.rbburst;
431
    idat3(dat3_rbf_tout)   := r.rbtout;
432
    idat3(dat3_rbf_nak)    := r.rbnak;
433
    idat3(dat3_rbf_ack)    := r.rback;
434
    idat3(dat3_rbf_busy)   := r.rbbusy;
435
    idat3(dat3_rbf_err)    := r.rberr;
436
    idat3(dat3_rbf_we)     := r.rbwe;
437
    idat3(dat3_rbf_init)   := r.rbinit;
438
    idat3(dat3_rbf_ndlymsb):= r.rbndly(13 downto 6);
439
    idat2(dat2_rbf_ndlylsb):= r.rbndly( 5 downto 0);
440
    idat2(dat2_rbf_nbusy)  := r.rbnbusy;
441
    idat1 := r.rbdata;
442
    idat0 := r.rbaddr;
443 10 wfjm
 
444
    n.rbtake_1 := rbtake;
445
 
446
    N_REGS <= n;
447
 
448
    BRAM_EN <= ibramen;
449
    BRAM_WE <= ibramwe;
450
 
451
    BRAM1_DI <= idat3 & idat2;
452
    BRAM0_DI <= idat1 & idat0;
453
 
454
    RB_SRES.dout <= irb_dout;
455
    RB_SRES.ack  <= irb_ack;
456
    RB_SRES.err  <= irb_err;
457
    RB_SRES.busy <= irb_busy;
458
 
459
  end process proc_next;
460
 
461
end syn;

powered by: WebSVN 2.1.0

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