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 13

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

Line No. Rev Author Line
1 13 wfjm
-- $Id: rbd_rbmon.vhd 427 2011-11-19 21:04:11Z mueller $
2 10 wfjm
--
3
-- Copyright 2010-2011 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:    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 13 wfjm
-- Tool versions:  xst 12.1, 13.1; ghdl 0.29
24 10 wfjm
--
25
-- Synthesized (xst):
26
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
27
-- 2010-12-27   349 12.1    M53d xc3s1000-4    95  228    -  154 s 10.4
28
--
29
-- Revision History: 
30
-- Date         Rev Version  Comment
31 13 wfjm
-- 2011-11-19   427   1.0.3  now numeric_std clean
32 10 wfjm
-- 2011-03-27   374   1.0.2  rename ncyc -> nbusy because it counts busy cycles
33
-- 2010-12-31   352   1.0.1  simplify irb_ack logic
34
-- 2010-12-27   349   1.0    Initial version 
35
------------------------------------------------------------------------------
36
--
37 12 wfjm
-- Address   Bits Name        r/w/f  Function
38
-- bbbbbb00       cntl        r/w/f  Control register
39
--             00   go        r/w/f    writing 1 clears add
40
-- bbbbbb01       alim        r/w/-  Address limit register
41
--          15:08   hilim     r/w/-    upper address limit (def: ff)
42
--          07:00   lolim     r/w/-    lower address limit (def: 00)
43
-- bbbbbb10       addr        r/w/-  Address register
44
--             15   wrap      r/0/-    line address wrapped (cleared on write)
45
--           *:02   laddr     r/w/-    line address
46
--          01:00   waddr     r/w/-    word address
47
-- bbbbbb11       data        r/w/-  Data register
48 10 wfjm
--
49
--     data format:
50
--     word 3     15 : ack
51
--                14 : busy
52
--                13 : err
53
--                12 : nak
54
--                11 : tout
55
--                09 : init
56
--                08 : we
57
--             07:00 : addr
58
--     word 2          data
59
--     word 1  15:00 : delay to prev (lsb's)
60
--     word 0  15:12 : delay to prev (msb's)
61
--             11:00 : number of busy cycles
62
-- 
63
 
64
 
65
library ieee;
66
use ieee.std_logic_1164.all;
67 13 wfjm
use ieee.numeric_std.all;
68 10 wfjm
 
69
use work.slvtypes.all;
70
use work.memlib.all;
71
use work.rblib.all;
72
 
73
entity rbd_rbmon is                     -- rbus dev: rbus monitor
74
  generic (
75 13 wfjm
    RB_ADDR : slv8 := slv(to_unsigned(2#11111100#,8));
76 10 wfjm
    AWIDTH : positive := 9);
77
  port (
78
    CLK  : in slbit;                    -- clock
79
    RESET : in slbit;                   -- reset
80
    RB_MREQ : in rb_mreq_type;          -- rbus: request
81
    RB_SRES : out rb_sres_type;         -- rbus: response
82
    RB_SRES_SUM : in rb_sres_type       -- rbus: response (sum for monitor)
83
  );
84
end entity rbd_rbmon;
85
 
86
 
87
architecture syn of rbd_rbmon is
88
 
89
  constant rbaddr_cntl : slv2 := "00";   -- cntl address offset
90
  constant rbaddr_alim : slv2 := "01";   -- alim address offset
91
  constant rbaddr_addr : slv2 := "10";   -- addr address offset
92
  constant rbaddr_data : slv2 := "11";   -- data address offset
93
 
94
  constant cntl_rbf_go       : integer :=     0;
95
  subtype  alim_rbf_hilim   is integer range 15 downto  8;
96
  subtype  alim_rbf_lolim   is integer range  7 downto  0;
97
  constant addr_rbf_wrap     : integer :=    15;
98
  subtype  addr_rbf_laddr   is integer range 2+AWIDTH-1 downto  2;
99
  subtype  addr_rbf_waddr   is integer range  1 downto  0;
100
 
101
  constant dat3_rbf_ack      : integer :=    15;
102
  constant dat3_rbf_busy     : integer :=    14;
103
  constant dat3_rbf_err      : integer :=    13;
104
  constant dat3_rbf_nak      : integer :=    12;
105
  constant dat3_rbf_tout     : integer :=    11;
106
  constant dat3_rbf_init     : integer :=     9;
107
  constant dat3_rbf_we       : integer :=     8;
108
  subtype  dat3_rbf_addr    is integer range  7 downto  0;
109
  subtype  dat0_rbf_ndlymsb is integer range 15 downto 12;
110
  subtype  dat0_rbf_nbusy   is integer range 11 downto  0;
111
 
112
  type regs_type is record              -- state registers
113
    rbsel : slbit;                      -- rbus select
114
    go : slbit;                         -- go flag
115
    hilim : slv8;                       -- upper address limit
116
    lolim : slv8;                       -- lower address limit
117
    wrap : slbit;                       -- laddr wrap flag
118
    laddr : slv(AWIDTH-1 downto 0);     -- line address
119
    waddr : slv2;                       -- word address
120
    rbtake_1 : slbit;                   -- rb capture active in last cycle
121
    rbaddr  : slv8;                     -- rbus trace: addr
122
    rbinit  : slbit;                    -- rbus trace: init
123
    rbwe    : slbit;                    -- rbus trace: we
124
    rback   : slbit;                    -- rbus trace: ack  seen
125
    rbbusy  : slbit;                    -- rbus trace: busy seen
126
    rberr   : slbit;                    -- rbus trace: err  seen
127
    rbnak   : slbit;                    -- rbus trace: nak  detected
128
    rbtout  : slbit;                    -- rbus trace: tout detected
129
    rbdata  : slv16;                    -- rbus trace: data
130
    rbnbusy : slv12;                    -- rbus number of busy cycles
131
    rbndly  : slv20;                    -- rbus delay to prev. access
132
  end record regs_type;
133
 
134
  constant laddrzero : slv(AWIDTH-1 downto 0) := (others=>'0');
135
  constant laddrlast : slv(AWIDTH-1 downto 0) := (others=>'1');
136
 
137
  constant regs_init : regs_type := (
138
    '0',                                -- rbsel
139
    '0',                                -- go    (default is off)
140
    (others=>'1'),                      -- hilim (def: ff)
141
    (others=>'0'),                      -- lolim (def: 00)
142
    '0',                                -- wrap
143
    laddrzero,                          -- laddr
144
    "00",                               -- waddr
145
    '0',                                -- rbtake_1
146
    (others=>'0'),                      -- rbaddr
147
    '0','0','0','0','0',                -- rbinit,rbwe,rback,rbbusy,rberr
148
    '0','0',                            -- rbnak,rbtout
149
    (others=>'0'),                      -- rbdata
150
    (others=>'0'),                      -- rbnbusy
151
    (others=>'0')                       -- rbndly
152
  );
153
 
154
  constant rbnbusylast : slv12 := (others=>'1');
155
  constant rbndlylast  : slv20 := (others=>'1');
156
 
157
  signal R_REGS : regs_type := regs_init;
158
  signal N_REGS : regs_type := regs_init;
159
 
160
  signal BRAM_EN : slbit := '0';
161
  signal BRAM_WE : slbit := '0';
162
  signal BRAM0_DI : slv32 := (others=>'0');
163
  signal BRAM1_DI : slv32 := (others=>'0');
164
  signal BRAM0_DO : slv32 := (others=>'0');
165
  signal BRAM1_DO : slv32 := (others=>'0');
166
 
167
begin
168
 
169
  assert AWIDTH<=13
170
    report "assert(AWIDTH<=13): max address width supported"
171
    severity failure;
172
 
173
  BRAM1 : ram_1swsr_wfirst_gen
174
    generic map (
175
      AWIDTH => AWIDTH,
176
      DWIDTH => 32)
177
    port map (
178
      CLK   => CLK,
179
      EN    => BRAM_EN,
180
      WE    => BRAM_WE,
181
      ADDR  => R_REGS.laddr,
182
      DI    => BRAM1_DI,
183
      DO    => BRAM1_DO
184
    );
185
 
186
  BRAM0 : ram_1swsr_wfirst_gen
187
    generic map (
188
      AWIDTH => AWIDTH,
189
      DWIDTH => 32)
190
    port map (
191
      CLK   => CLK,
192
      EN    => BRAM_EN,
193
      WE    => BRAM_WE,
194
      ADDR  => R_REGS.laddr,
195
      DI    => BRAM0_DI,
196
      DO    => BRAM0_DO
197
    );
198
 
199
  proc_regs: process (CLK)
200
  begin
201 13 wfjm
    if rising_edge(CLK) then
202 10 wfjm
      if RESET = '1' then
203
        R_REGS <= regs_init;
204
      else
205
        R_REGS <= N_REGS;
206
      end if;
207
    end if;
208
  end process proc_regs;
209
 
210
  proc_next : process (R_REGS, RB_MREQ, RB_SRES_SUM, BRAM0_DO, BRAM1_DO)
211
    variable r : regs_type := regs_init;
212
    variable n : regs_type := regs_init;
213
    variable irb_ack  : slbit := '0';
214
    variable irb_busy : slbit := '0';
215
    variable irb_err  : slbit := '0';
216
    variable irb_dout  : slv16 := (others=>'0');
217
    variable irbena  : slbit := '0';
218
    variable ibramen : slbit := '0';
219
    variable ibramwe : slbit := '0';
220
    variable rbtake : slbit := '0';
221
    variable laddr_inc : slbit := '0';
222
    variable idat0 : slv16 := (others=>'0');
223
    variable idat1 : slv16 := (others=>'0');
224
    variable idat2 : slv16 := (others=>'0');
225
    variable idat3 : slv16 := (others=>'0');
226
  begin
227
 
228
    r := R_REGS;
229
    n := R_REGS;
230
 
231
    irb_ack  := '0';
232
    irb_busy := '0';
233
    irb_err  := '0';
234
    irb_dout := (others=>'0');
235
 
236
    irbena  := RB_MREQ.re or RB_MREQ.we;
237
 
238
    ibramen := '0';
239
    ibramwe := '0';
240
 
241
    laddr_inc := '0';
242
 
243
    -- rbus address decoder
244
    n.rbsel := '0';
245
    if RB_MREQ.aval='1' and RB_MREQ.addr(7 downto 2)=RB_ADDR(7 downto 2) then
246
      n.rbsel := '1';
247
      ibramen := '1';
248
    end if;
249
 
250
    -- rbus transactions
251
    if r.rbsel = '1' then
252
 
253
      irb_ack := irbena;                  -- ack all accesses
254
 
255
      case RB_MREQ.addr(1 downto 0) is
256
 
257
        when rbaddr_cntl =>
258
          if RB_MREQ.we = '1' then
259
            n.go  := RB_MREQ.din(cntl_rbf_go);
260
            if RB_MREQ.din(cntl_rbf_go)='1' then
261
              n.wrap  := '0';
262
              n.laddr := laddrzero;
263
              n.waddr := "00";
264
            end if;
265
          end if;
266
 
267
        when rbaddr_alim =>
268
          if RB_MREQ.we = '1' then
269
            n.hilim := RB_MREQ.din(alim_rbf_hilim);
270
            n.lolim := RB_MREQ.din(alim_rbf_lolim);
271
          end if;
272
 
273
        when rbaddr_addr =>
274
          if RB_MREQ.we = '1' then
275
            n.go    := '0';
276
            n.wrap  := '0';
277
            n.laddr := RB_MREQ.din(addr_rbf_laddr);
278
            n.waddr := RB_MREQ.din(addr_rbf_waddr);
279
          end if;
280
 
281
        when rbaddr_data =>
282
          if r.go='1' or RB_MREQ.we='1' then
283
            irb_err := '1';
284
          end if;
285
          if RB_MREQ.re = '1' then
286 13 wfjm
            n.waddr := slv(unsigned(r.waddr) + 1);
287 10 wfjm
            if r.waddr = "11" then
288
              laddr_inc := '1';
289
            end if;
290
          end if;
291
 
292
        when others => null;
293
      end case;
294
    end if;
295
 
296
    -- rbus output driver
297
    if r.rbsel = '1' then
298
      case RB_MREQ.addr(1 downto 0) is
299
        when rbaddr_cntl =>
300
          irb_dout(cntl_rbf_go)    := r.go;
301
        when rbaddr_alim =>
302
          irb_dout(alim_rbf_hilim) := r.hilim;
303
          irb_dout(alim_rbf_lolim) := r.lolim;
304
        when rbaddr_addr =>
305
          irb_dout(addr_rbf_wrap)  := r.wrap;
306
          irb_dout(addr_rbf_laddr) := r.laddr;
307
          irb_dout(addr_rbf_waddr) := r.waddr;
308
        when rbaddr_data =>
309
          case r.waddr is
310
            when "11" => irb_dout := BRAM1_DO(31 downto 16);
311
            when "10" => irb_dout := BRAM1_DO(15 downto  0);
312
            when "01" => irb_dout := BRAM0_DO(31 downto 16);
313
            when "00" => irb_dout := BRAM0_DO(15 downto  0);
314
            when others => null;
315
          end case;
316
        when others => null;
317
      end case;
318
    end if;
319
 
320
    -- rbus monitor 
321
    --   a rbus transaction are captured if the address is in alim window
322
    --   and the access is not refering to rbd_rbmon itself
323
 
324
    rbtake := '0';
325
    if RB_MREQ.aval='1' and irbena='1' then              -- aval and (re or we)
326
      if unsigned(RB_MREQ.addr)>=unsigned(r.lolim) and   -- and in addr window
327
         unsigned(RB_MREQ.addr)<=unsigned(r.hilim) and
328
         r.rbsel='0' then                                -- and not self
329
        rbtake := '1';
330
      end if;
331
    end if;
332
    if RB_MREQ.init = '1' then                           -- also take init's
333
      rbtake := '1';
334
    end if;
335
 
336
    if rbtake = '1' then                -- if capture active
337
      n.rbaddr := RB_MREQ.addr;           -- keep track of some state
338
      n.rbinit := RB_MREQ.init;
339
      n.rbwe   := RB_MREQ.we;
340
      if RB_MREQ.init='1' or RB_MREQ.we='1' then  -- for write/init of din
341
        n.rbdata := RB_MREQ.din;
342
      else                                        -- for read of dout
343
        n.rbdata := RB_SRES_SUM.dout;
344
      end if;
345
 
346
      if r.rbtake_1 = '0' then            -- if initial cycle of a transaction
347
        n.rback  := RB_SRES_SUM.ack;
348
        n.rbbusy := RB_SRES_SUM.busy;
349
        n.rberr  := RB_SRES_SUM.err;
350
        n.rbnbusy := (others=>'0');
351
      else                                -- if non-initial cycles
352
        if RB_SRES_SUM.err = '1' then       -- keep track of err flags
353
          n.rberr := '1';
354
        end if;
355
        if r.rbnbusy /= rbnbusylast then      -- and count  
356 13 wfjm
          n.rbnbusy := slv(unsigned(r.rbnbusy) + 1);
357 10 wfjm
        end if;
358
      end if;
359
      n.rbnak  := not RB_SRES_SUM.ack;
360
      n.rbtout := RB_SRES_SUM.busy;
361
 
362
    else                                -- if capture not active
363
      if r.go='1' and r.rbtake_1='1' then -- active and transaction just ended
364
        ibramen := '1';
365
        ibramwe := '1';
366
        laddr_inc := '1';
367
      end if;
368
      if r.rbtake_1 = '1' then            -- rbus transaction just ended
369
        n.rbndly := (others=>'0');          -- clear delay counter
370
      else                                -- just idle
371
        if r.rbndly /= rbndlylast then      -- count cycles
372 13 wfjm
          n.rbndly := slv(unsigned(r.rbndly) + 1);
373 10 wfjm
        end if;
374
      end if;
375
    end if;
376
 
377
    if laddr_inc = '1' then
378 13 wfjm
      n.laddr := slv(unsigned(r.laddr) + 1);
379 10 wfjm
      if r.go='1' and r.laddr=laddrlast then
380
        n.wrap := '1';
381
      end if;
382
    end if;
383
 
384
    idat3 := (others=>'0');
385
    idat3(dat3_rbf_ack)  := r.rback;
386
    idat3(dat3_rbf_busy) := r.rbbusy;
387
    idat3(dat3_rbf_err)  := r.rberr;
388
    idat3(dat3_rbf_nak)  := r.rbnak;
389
    idat3(dat3_rbf_tout) := r.rbtout;
390
    idat3(dat3_rbf_init) := r.rbinit;
391
    idat3(dat3_rbf_we)   := r.rbwe;
392
    idat3(dat3_rbf_addr) := r.rbaddr;
393
    idat2 := r.rbdata;
394
    idat1 := r.rbndly(15 downto 0);
395
    idat0(dat0_rbf_ndlymsb) := r.rbndly(19 downto 16);
396
    idat0(dat0_rbf_nbusy)   := r.rbnbusy;
397
 
398
    n.rbtake_1 := rbtake;
399
 
400
    N_REGS <= n;
401
 
402
    BRAM_EN <= ibramen;
403
    BRAM_WE <= ibramwe;
404
 
405
    BRAM1_DI <= idat3 & idat2;
406
    BRAM0_DI <= idat1 & idat0;
407
 
408
    RB_SRES.dout <= irb_dout;
409
    RB_SRES.ack  <= irb_ack;
410
    RB_SRES.err  <= irb_err;
411
    RB_SRES.busy <= irb_busy;
412
 
413
  end process proc_next;
414
 
415
end syn;

powered by: WebSVN 2.1.0

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