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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.7/] [rtl/] [vlib/] [rbus/] [rbd_tester.vhd] - Blame information for rev 33

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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