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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [rtl/] [vlib/] [rbus/] [rbd_eyemon.vhd] - Blame information for rev 12

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

Line No. Rev Author Line
1 12 wfjm
-- $Id: rbd_eyemon.vhd 406 2011-08-14 21:06:44Z 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_eyemon - syn
16
-- Description:    rbus dev: eye monitor for serport's
17
--
18
-- Dependencies:   memlib/ram_2swsr_wfirst_gen
19
--
20
-- Test bench:     -
21
--
22
-- Target Devices: generic
23
-- Tool versions:  xst 12.1; ghdl 0.29
24
--
25
-- Synthesized (xst):
26
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
27
-- 2011-04-02   374 12.1    M53d xc3s1000-4    46  154    -  109 s  8.7
28
-- 2010-12-27   349 12.1    M53d xc3s1000-4    45  147    -  106 s  8.9
29
--
30
-- Revision History: 
31
-- Date         Rev Version  Comment
32
-- 2011-04-02   375   1.0.2  handle back-to-back chars properly (in sim..)
33
-- 2010-12-31   352   1.0.1  simplify irb_ack logic
34
-- 2010-12-27   349   1.0    Initial version 
35
------------------------------------------------------------------------------
36
--
37
-- rbus registers:
38
--
39
-- Address   Bits Name        r/w/f  Function
40
-- bbbbbb00       cntl        r/w/-  Control register
41
--             03   ena01     r/w/-    track 0->1 rxsd transitions
42
--             02   ena10     r/w/-    track 1->0 rxsd transitions
43
--             01   clr       r/-/f    w: writing a 1 starts memory clear
44
--                                     r: 1 indicates clr in progress (512 cyc)
45
--             00   go        r/w/-    enables monitor
46
-- bbbbbb01  7:00 rdiv        r/w/-  Sample rate divider
47
-- bbbbbb10       addr        r/w/-  Address register
48
--           9:01   laddr     r/w/     line address
49
--             00   waddr     r/w/     word address
50
-- bbbbbb11 15:00 data        r/-/-  Data register
51
--
52
--     data format:
53
--     word 1  counter msb's
54
--     word 0  counter lsb's
55
-- 
56
 
57
library ieee;
58
use ieee.std_logic_1164.all;
59
use ieee.std_logic_arith.all;
60
 
61
use work.slvtypes.all;
62
use work.memlib.all;
63
use work.rblib.all;
64
 
65
entity rbd_eyemon is                    -- rbus dev: eye monitor for serport's
66
  generic (
67
    RB_ADDR : slv8 := conv_std_logic_vector(2#11111000#,8);
68
    RDIV : slv8 := conv_std_logic_vector(0,8));
69
  port (
70
    CLK  : in slbit;                    -- clock
71
    RESET : in slbit;                   -- reset
72
    RB_MREQ : in rb_mreq_type;          -- rbus: request
73
    RB_SRES : out rb_sres_type;         -- rbus: response
74
    RXSD : in slbit;                    -- rx: serial data
75
    RXACT : in slbit                    -- rx: active (start seen)
76
  );
77
end entity rbd_eyemon;
78
 
79
 
80
architecture syn of rbd_eyemon is
81
 
82
  constant rbaddr_cntl : slv2 := "00";   -- cntl address offset
83
  constant rbaddr_rdiv : slv2 := "01";   -- rdiv address offset
84
  constant rbaddr_addr : slv2 := "10";   -- addr address offset
85
  constant rbaddr_data : slv2 := "11";   -- data address offset
86
 
87
  constant cntl_rbf_ena01    : integer :=     3;
88
  constant cntl_rbf_ena10    : integer :=     2;
89
  constant cntl_rbf_clr      : integer :=     1;
90
  constant cntl_rbf_go       : integer :=     0;
91
  subtype  addr_rbf_laddr   is integer range  9 downto  1;
92
  constant addr_rbf_waddr    : integer :=     0;
93
 
94
  type state_type is (
95
    s_idle,                             -- s_idle: wait for char or clr
96
    s_char,                             -- s_char: processing a char
97
    s_clr                               -- s_clr: clear memory
98
  );
99
 
100
  type regs_type is record              -- state registers
101
    state : state_type;                 -- state
102
    rbsel : slbit;                      -- rbus select
103
    go : slbit;                         -- go flag
104
    clr : slbit;                        -- clear pending
105
    ena10 : slbit;                      -- enable 1->0
106
    ena01 : slbit;                      -- enable 0->1
107
    rdiv : slv8;                        -- rate divider
108
    laddr : slv9;                       -- line address
109
    waddr : slbit;                      -- word address
110
    laddr_1 : slv9;                     -- line address last cycle
111
    rxsd_1 : slbit;                     -- rxsd last cycle
112
    memwe : slbit;                      -- write bram (clr or inc)
113
    memclr : slbit;                     -- write zero into bram
114
    rdivcnt : slv8;                     -- rate divider counter
115
  end record regs_type;
116
 
117
  constant regs_init : regs_type := (
118
    s_idle,                             -- state
119
    '0',                                -- rbsel
120
    '0',                                -- go    (default is off)
121
    '0','0','0',                        -- clr,ena01,ena10
122
    (others=>'0'),                      -- rdiv
123
    (others=>'0'),                      -- laddr
124
    '0',                                -- waddr
125
    (others=>'0'),                      -- laddr_1
126
    '0','0','0',                        -- rxsd_1,memwe,memclr
127
    (others=>'0')                       -- rdivcnt
128
  );
129
 
130
  signal R_REGS : regs_type := regs_init;
131
  signal N_REGS : regs_type := regs_init;
132
 
133
  signal BRAM_ENA : slbit := '0';
134
  signal BRAM_DIA : slv32 := (others=>'0');
135
  signal BRAM_DIB : slv32 := (others=>'0');
136
  signal BRAM_DOA : slv32 := (others=>'0');
137
 
138
begin
139
 
140 12 wfjm
  BRAM_DIA <= (others=>'0');            -- always 0, no writes on this port
141
 
142 10 wfjm
  BRAM : ram_2swsr_wfirst_gen
143
    generic map (
144
      AWIDTH =>  9,
145
      DWIDTH => 32)
146
    port map (
147
      CLKA   => CLK,
148
      CLKB   => CLK,
149
      ENA    => BRAM_ENA,
150
      ENB    => R_REGS.memwe,
151
      WEA    => '0',
152
      WEB    => R_REGS.memwe,
153
      ADDRA  => R_REGS.laddr,
154
      ADDRB  => R_REGS.laddr_1,
155
      DIA    => BRAM_DIA,
156
      DIB    => BRAM_DIB,
157
      DOA    => BRAM_DOA,
158
      DOB    => open
159
    );
160
 
161
  proc_regs: process (CLK)
162
  begin
163
    if CLK'event and CLK='1' then
164
      if RESET = '1' then
165
        R_REGS <= regs_init;
166
      else
167
        R_REGS <= N_REGS;
168
      end if;
169
    end if;
170
  end process proc_regs;
171
 
172
  proc_next : process (R_REGS, RB_MREQ, RXSD, RXACT, BRAM_DOA)
173
    variable r : regs_type := regs_init;
174
    variable n : regs_type := regs_init;
175
    variable irb_ack  : slbit := '0';
176
    variable irb_busy : slbit := '0';
177
    variable irb_err  : slbit := '0';
178
    variable irb_dout  : slv16 := (others=>'0');
179
    variable irbena  : slbit := '0';
180
    variable ibramen : slbit := '0';
181
    variable ibramdi : slv32 := (others=>'0');
182
    variable laddr_we : slbit := '0';
183
    variable laddr_clr : slbit := '0';
184
    variable laddr_inc : slbit := '0';
185
  begin
186
 
187
    r := R_REGS;
188
    n := R_REGS;
189
 
190
    irb_ack  := '0';
191
    irb_busy := '0';
192
    irb_err  := '0';
193
    irb_dout := (others=>'0');
194
 
195
    irbena  := RB_MREQ.re or RB_MREQ.we;
196
 
197
    ibramen := '0';
198
 
199
    laddr_we  := '0';
200
    laddr_clr := '0';
201
    laddr_inc := '0';
202
 
203
    -- rbus address decoder
204
    n.rbsel := '0';
205
    if RB_MREQ.aval='1' and RB_MREQ.addr(7 downto 2)=RB_ADDR(7 downto 2) then
206
      n.rbsel := '1';
207
      ibramen := '1';
208
    end if;
209
 
210
    -- rbus transactions
211
    if r.rbsel = '1' then
212
 
213
      irb_ack := irbena;                  -- ack all accesses
214
 
215
      case RB_MREQ.addr(1 downto 0) is
216
 
217
        when rbaddr_cntl =>
218
          if RB_MREQ.we = '1' then
219
            n.ena01 := RB_MREQ.din(cntl_rbf_ena01);
220
            n.ena10 := RB_MREQ.din(cntl_rbf_ena10);
221
            if RB_MREQ.din(cntl_rbf_clr) = '1' then
222
              n.clr := '1';
223
            end if;
224
            n.go    := RB_MREQ.din(cntl_rbf_go);
225
          end if;
226
 
227
        when rbaddr_rdiv =>
228
          if RB_MREQ.we = '1' then
229
            n.rdiv := RB_MREQ.din(n.rdiv'range);
230
          end if;
231
 
232
        when rbaddr_addr =>
233
          if RB_MREQ.we = '1' then
234
            laddr_we := '1';
235
            n.waddr := RB_MREQ.din(addr_rbf_waddr);
236
          end if;
237
 
238
        when rbaddr_data =>
239
          if RB_MREQ.we='1' then
240
            irb_err := '1';
241
          end if;
242
          if RB_MREQ.re = '1' then
243
            if r.go='0' and r.clr='0' and r.state=s_idle then
244
              n.waddr := not r.waddr;
245
              if r.waddr = '1' then
246
                laddr_inc := '1';
247
              end if;
248
            else
249
              irb_err := '1';
250
            end if;
251
          end if;
252
 
253
        when others => null;
254
      end case;
255
    end if;
256
 
257
    -- rbus output driver
258
    if r.rbsel = '1' then
259
      case RB_MREQ.addr(1 downto 0) is
260
        when rbaddr_cntl =>
261
          irb_dout(cntl_rbf_ena01) := r.ena01;
262
          irb_dout(cntl_rbf_ena10) := r.ena10;
263
          irb_dout(cntl_rbf_clr)   := r.clr;
264
          irb_dout(cntl_rbf_go)    := r.go;
265
        when rbaddr_rdiv =>
266
          irb_dout(r.rdiv'range)   := r.rdiv;
267
        when rbaddr_addr =>
268
          irb_dout(addr_rbf_laddr) := r.laddr;
269
          irb_dout(addr_rbf_waddr) := r.waddr;
270
        when rbaddr_data =>
271
          case r.waddr is
272
            when '1' => irb_dout := BRAM_DOA(31 downto 16);
273
            when '0' => irb_dout := BRAM_DOA(15 downto  0);
274
            when others => null;
275
          end case;
276
        when others => null;
277
      end case;
278
    end if;
279
 
280
    -- eye monitor
281
    n.memwe  := '0';
282
    n.memclr := '0';
283
 
284
    case r.state is
285
      when s_idle =>                    -- s_idle: wait for char or clr ------
286
        if r.clr = '1' then
287
          laddr_clr := '1';
288
          n.state := s_clr;
289
        elsif r.go = '1' and RXSD='0' then
290
          laddr_clr := '1';
291
          n.rdivcnt := r.rdiv;
292
          n.state := s_char;
293
        end if;
294
 
295
      when s_char =>                    -- s_char: processing a char ---------
296
        if RXACT = '0' then               -- uart went unactive
297
          if RXSD = '1' then                -- line idle -> to s_idle
298
            n.state := s_idle;
299
          else                              -- already next start bit seen 
300
            laddr_clr := '1';                 -- clear and restart
301
            n.rdivcnt := r.rdiv;              -- happens only in simulation...
302
          end if;
303
        else
304
          if (r.ena01='1' and r.rxsd_1='0' and RXSD='1') or
305
             (r.ena10='1' and r.rxsd_1='1' and RXSD='0') then
306
            n.memwe := '1';
307
            ibramen := '1';
308
          end if;
309
        end if;
310
        if unsigned(r.rdiv)=0 or unsigned(r.rdivcnt)=0 then
311
          n.rdivcnt := r.rdiv;
312
          if unsigned(r.laddr) /= (2**r.laddr'length)-1 then
313
            laddr_inc := '1';
314
          end if;
315
        else
316
          n.rdivcnt := unsigned(r.rdivcnt) - 1;
317
        end if;
318
 
319
      when s_clr =>                     -- s_clr: clear memory ---------------
320
        laddr_inc := '1';
321
        n.memwe  := '1';
322
        n.memclr := '1';
323
        if unsigned(r.laddr) = (2**r.laddr'length)-1 then
324
          n.clr   := '0';
325
          n.state := s_idle;
326
        end if;
327
 
328
      when others => null;
329
    end case;
330
 
331
    if laddr_we = '1' then
332
      n.laddr := RB_MREQ.din(addr_rbf_laddr);
333
    elsif laddr_clr = '1' then
334
      n.laddr := (others=>'0');
335
    elsif laddr_inc = '1' then
336
      n.laddr := unsigned(r.laddr) + 1;
337
    end if;
338
 
339
    n.laddr_1 := r.laddr;
340
    n.rxsd_1  := RXSD;
341
 
342
    ibramdi := (others=>'0');
343
    if r.memclr = '0' then
344
      ibramdi := unsigned(BRAM_DOA) + 1;
345
    end if;
346
 
347
    N_REGS <= n;
348
 
349
    BRAM_ENA <= ibramen;
350
    BRAM_DIB <= ibramdi;
351
 
352
    RB_SRES.dout <= irb_dout;
353
    RB_SRES.ack  <= irb_ack;
354
    RB_SRES.err  <= irb_err;
355
    RB_SRES.busy <= irb_busy;
356
 
357
  end process proc_next;
358
 
359
end syn;

powered by: WebSVN 2.1.0

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