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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [rtl/] [vlib/] [rbus/] [rbd_tester.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_tester.vhd 427 2011-11-19 21:04:11Z mueller $
2 9 wfjm
--
3 13 wfjm
-- Copyright 2010-2011 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 9 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_tester - syn
16
-- Description:    rbus dev: rbus tester
17
--
18
-- Dependencies:   memlib/fifo_1c_dram_raw
19
--
20
-- Test bench:     rlink/tb/tb_rlink (used as test target)
21
--
22
-- Target Devices: generic
23 13 wfjm
-- Tool versions:  xst 12.1, 13.1; ghdl 0.29
24 9 wfjm
--
25
-- Synthesized (xst):
26
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
27
-- 2010-12-12   344 12.1    M53d xc3s1000-4    78  204   32  133 s  8.0
28
-- 2010-12-04   343 12.1    M53d xc3s1000-4    75  214   32  136 s  9.3
29
--
30
-- Revision History: 
31
-- Date         Rev Version  Comment
32 13 wfjm
-- 2011-11-19   427   1.0.4  now numeric_std clean
33 9 wfjm
-- 2010-12-31   352   1.0.3  simplify irb_ack logic
34
-- 2010-12-29   351   1.0.2  default addr 111101xx->111100xx
35
-- 2010-12-12   344   1.0.1  send 0101.. on busy or err; fix init and busy logic
36
-- 2010-12-04   343   1.0    Initial version 
37
------------------------------------------------------------------------------
38
--
39
-- rbus registers:
40
--
41
-- Address   Bits Name        r/w/f  Function
42
-- bbbbbb00       cntl        r/w/-  Control register
43
--             15   nofifo    r/w/-    a 1 disables fifo, to test delayed aborts
44
--          14:12   stat      r/w/-    echo'ed on RB_STAT
45
--          11:00   nbusy     r/w/-    busy cycles (for data and fifo access)
46
-- bbbbbb01 15:00 data        r/w/-  Data register (just w/r reg, no function)
47
-- bbbbbb10 15:00 fifo        r/w/-  Fifo interface register
48
-- bbbbbb11       attn        r/w/-  Attn/Length register
49
--          15:00                    w: ping RB_LAM lines
50
--           9:00                    r: return cycle length of last access
51
-- 
52
 
53
library ieee;
54
use ieee.std_logic_1164.all;
55 13 wfjm
use ieee.numeric_std.all;
56 9 wfjm
 
57
use work.slvtypes.all;
58
use work.memlib.all;
59
use work.rblib.all;
60
 
61
entity rbd_tester is                    -- rbus dev: rbus tester
62
                                        -- complete rrirp_aif interface
63
  generic (
64 13 wfjm
    RB_ADDR : slv8 := slv(to_unsigned(2#11110000#,8)));
65 9 wfjm
  port (
66
    CLK  : in slbit;                    -- clock
67
    RESET : in slbit;                   -- reset
68
    RB_MREQ : in rb_mreq_type;          -- rbus: request
69
    RB_SRES : out rb_sres_type;         -- rbus: response
70
    RB_LAM : out slv16;                 -- rbus: look at me
71
    RB_STAT : out slv3                  -- rbus: status flags
72
  );
73
end entity rbd_tester;
74
 
75
 
76
architecture syn of rbd_tester is
77
 
78
  constant awidth : positive := 4;      -- fifo address width
79
 
80
  constant rbaddr_cntl : slv2 := "00";  -- cntl address offset
81
  constant rbaddr_data : slv2 := "01";  -- data address offset
82
  constant rbaddr_fifo : slv2 := "10";  -- fifo address offset
83
  constant rbaddr_attn : slv2 := "11";  -- attn address offset
84
 
85
  constant cntl_rbf_nofifo  : integer := 15;
86
  subtype  cntl_rbf_stat    is integer range 14 downto 12;
87
  subtype  cntl_rbf_nbusy   is integer range  9 downto  0;
88
 
89
  constant init_rbf_cntl  : integer :=  0;
90
  constant init_rbf_data  : integer :=  1;
91
  constant init_rbf_fifo  : integer :=  2;
92
 
93
  type regs_type is record              -- state registers
94
    rbsel : slbit;                      -- rbus select
95
    nofifo : slbit;                     -- disable fifo flag
96
    stat : slv3;                        -- stat setting
97
    nbusy : slv10;                      -- nbusy setting
98
    data : slv16;                       -- data register
99
    act_1 : slbit;                      -- rbsel and (re or we) in last cycle
100
    ncyc : slv10;                       -- cycle length of last access
101
    cntbusy : slv10;                    -- busy timer
102
    cntcyc : slv10;                     -- cycle length counter
103
  end record regs_type;
104
 
105
  constant regs_init : regs_type := (
106
    '0',                                -- rbsel
107
    '0',                                -- nofifo
108
    (others=>'0'),                      -- stat
109
    (others=>'0'),                      -- nbusy
110
    (others=>'0'),                      -- data
111
    '0',                                -- act_1
112
    (others=>'0'),                      -- ncyc
113
    (others=>'0'),                      -- cntbusy
114
    (others=>'0')                       -- cntcyc
115
  );
116
 
117
  constant cntcyc_max : slv(regs_init.cntcyc'range) := (others=>'1');
118
 
119
  signal R_REGS : regs_type := regs_init;
120
  signal N_REGS : regs_type := regs_init;
121
 
122
  signal FIFO_RESET : slbit := '0';
123
  signal FIFO_RE : slbit := '0';
124
  signal FIFO_WE : slbit := '0';
125
  signal FIFO_EMPTY : slbit := '0';
126
  signal FIFO_FULL : slbit := '0';
127
  signal FIFO_SIZE : slv(awidth-1 downto 0) := (others=>'0');
128
  signal FIFO_DO : slv16 := (others=>'0');
129
 
130
begin
131
 
132
  FIFO : fifo_1c_dram_raw
133
    generic map (
134
      AWIDTH => awidth,
135
      DWIDTH => 16)
136
    port map (
137
      CLK   => CLK,
138
      RESET => FIFO_RESET,
139
      RE    => FIFO_RE,
140
      WE    => FIFO_WE,
141
      DI    => RB_MREQ.din,
142
      DO    => FIFO_DO,
143
      SIZE  => FIFO_SIZE,
144
      EMPTY => FIFO_EMPTY,
145
      FULL  => FIFO_FULL
146
    );
147
 
148
  proc_regs: process (CLK)
149
  begin
150 13 wfjm
    if rising_edge(CLK) then
151 9 wfjm
      if RESET = '1' then
152
        R_REGS <= regs_init;
153
      else
154
        R_REGS <= N_REGS;
155
      end if;
156
    end if;
157
  end process proc_regs;
158
 
159
  proc_next : process (R_REGS, RB_MREQ, FIFO_EMPTY, FIFO_FULL, FIFO_DO)
160
    variable r : regs_type := regs_init;
161
    variable n : regs_type := regs_init;
162
    variable irb_ack  : slbit := '0';
163
    variable irb_busy : slbit := '0';
164
    variable irb_err  : slbit := '0';
165
    variable irb_dout : slv16 := (others=>'0');
166
    variable irbena : slbit := '0';
167
    variable irblam : slv16 := (others=>'0');
168
    variable ififo_re : slbit := '0';
169
    variable ififo_we : slbit := '0';
170
    variable ififo_reset : slbit := '0';
171
    variable isbusy : slbit := '0';
172
  begin
173
 
174
    r := R_REGS;
175
    n := R_REGS;
176
 
177
    irb_ack  := '0';
178
    irb_busy := '0';
179
    irb_err  := '0';
180
    irb_dout := (others=>'0');
181
    irblam   := (others=>'0');
182
 
183
    irbena  := RB_MREQ.re or RB_MREQ.we;
184
 
185
    ififo_re := '0';
186
    ififo_we := '0';
187
    ififo_reset := '0';
188
 
189
    isbusy := '0';
190
    if unsigned(r.cntbusy) /= 0 then
191
      isbusy := '1';
192
    end if;
193
 
194
    -- rbus address decoder
195
    n.rbsel := '0';
196
    if RB_MREQ.aval='1' and RB_MREQ.addr(7 downto 2)=RB_ADDR(7 downto 2) then
197
 
198
      n.rbsel := '1';
199
 
200
      if irbena = '0' then              -- addr valid and selected, but no req
201
        n.cntbusy := r.nbusy;             -- preset busy timer
202
        n.cntcyc  := (others=>'0');       -- clear cycle length counter
203
      end if;
204
 
205
    end if;
206
 
207
    -- rbus transactions
208
    if r.rbsel = '1' then
209
 
210
      if irbena = '1' then              -- if request active
211
        if unsigned(r.cntbusy) /= 0 then  -- if busy timer > 0
212 13 wfjm
          n.cntbusy := slv(unsigned(r.cntbusy) - 1); -- decrement busy timer
213 9 wfjm
        end if;
214
        if r.cntcyc /= cntcyc_max then    -- if cycle counter < max
215 13 wfjm
          n.cntcyc  := slv(unsigned(r.cntcyc) + 1);  -- increment cycle counter
216 9 wfjm
        end if;
217
      end if;
218
 
219
      irb_ack := irbena;                  -- ack all (some rejects later)
220
 
221
      case RB_MREQ.addr(1 downto 0) is
222
 
223
        when rbaddr_cntl =>
224
          if RB_MREQ.we='1' then
225
            n.nofifo := RB_MREQ.din(cntl_rbf_nofifo);
226
            n.stat   := RB_MREQ.din(cntl_rbf_stat);
227
            n.nbusy  := RB_MREQ.din(cntl_rbf_nbusy);
228
            if r.nofifo='1' and RB_MREQ.din(cntl_rbf_nofifo)='0' then
229
              ififo_reset := '1';
230
            end if;
231
          end if;
232
 
233
        when rbaddr_data =>
234
          irb_busy := irbena and isbusy;
235
          if RB_MREQ.we='1' and isbusy='0' then
236
            n.data := RB_MREQ.din;
237
          end if;
238
 
239
        when rbaddr_fifo =>
240
          if r.nofifo = '0' then            -- if fifo enabled
241
            irb_busy := irbena and isbusy;
242
            if RB_MREQ.re='1' and isbusy='0' then
243
              if FIFO_EMPTY = '1' then
244
                irb_err := '1';
245
              else
246
                ififo_re := '1';
247
              end if;
248
            end if;
249
            if RB_MREQ.we='1' and isbusy='0' then
250
              if FIFO_FULL = '1' then
251
                irb_err := '1';
252
              else
253
                ififo_we := '1';
254
              end if;
255
            end if;
256
 
257
          else                              -- else: if fifo disabled
258
            irb_ack := '0';                   -- nak it
259
            if isbusy = '1' then              -- or do a delayed nak
260
              irb_ack  := irbena;
261
              irb_busy := irbena;
262
            end if;
263
          end if;
264
 
265
        when rbaddr_attn =>
266
          if RB_MREQ.we = '1' then
267
            irblam := RB_MREQ.din;
268
          end if;
269
 
270
        when others => null;
271
      end case;
272
    end if;
273
 
274
    -- rbus output driver
275
    --   send a '0101...' pattern when selected and busy or err
276
    --   send data only when busy=0 and err=0
277
    --   this extra logic allows to debug rlink state machine
278
    if r.rbsel = '1' then
279
      if RB_MREQ.re='1' and irb_busy='0' and irb_err='0' then
280
        case RB_MREQ.addr(1 downto 0) is
281
          when rbaddr_cntl =>
282
            irb_dout(cntl_rbf_stat)   := r.stat;
283
            irb_dout(cntl_rbf_nofifo) := r.nofifo;
284
            irb_dout(cntl_rbf_nbusy)  := r.nbusy;
285
          when rbaddr_data =>
286
            irb_dout := r.data;
287
          when rbaddr_fifo =>
288
            if r.nofifo='0' and FIFO_EMPTY = '0' then
289
              irb_dout := FIFO_DO;
290
            end if;
291
          when rbaddr_attn =>
292
            irb_dout(r.cntcyc'range) := r.ncyc;
293
          when others => null;
294
        end case;
295
      else
296
        irb_dout := "0101010101010101";
297
      end if;
298
    end if;
299
 
300
    -- init transactions
301
    if RB_MREQ.init='1' and RB_MREQ.we='1' and RB_MREQ.addr=RB_ADDR then
302
      if RB_MREQ.din(init_rbf_cntl) = '1' then
303
        n.nofifo := '0';
304
        n.stat   := (others=>'0');
305
        n.nbusy  := (others=>'0');
306
      end if;
307
      if RB_MREQ.din(init_rbf_data) = '1' then
308
        n.data   := (others=>'0');
309
      end if;
310
      if RB_MREQ.din(init_rbf_fifo) = '1' then
311
        ififo_reset := '1';
312
      end if;
313
    end if;
314
 
315
    -- other transactions
316
    if irbena='0' and r.act_1='1' then
317
      n.ncyc := r.cntcyc;
318
    end if;
319
    n.act_1 := irbena;
320
 
321
    N_REGS <= n;
322
 
323
    FIFO_RE    <= ififo_re;
324
    FIFO_WE    <= ififo_we;
325
    FIFO_RESET <= ififo_reset;
326
 
327
    RB_SRES.dout <= irb_dout;
328
    RB_SRES.ack  <= irb_ack;
329
    RB_SRES.err  <= irb_err;
330
    RB_SRES.busy <= irb_busy;
331
 
332
    RB_LAM  <= irblam;
333
    RB_STAT <= r.stat;
334
 
335
  end process proc_next;
336
 
337
end syn;

powered by: WebSVN 2.1.0

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