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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [rtl/] [vlib/] [serport/] [serport_2clock.vhd] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 wfjm
-- $Id: serport_2clock.vhd 476 2013-01-26 22:23:53Z mueller $
2 16 wfjm
--
3
-- Copyright 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:    serport_2clock - syn
16
-- Description:    serial port: serial port module, 2 clock domain
17
--
18
-- Dependencies:   genlib/cdc_pulse
19
--                 serport_uart_rxtx_ab
20
--                 serport_xonrx
21
--                 serport_xontx
22
--                 memlib/fifo_2c_dram
23
-- Test bench:     -
24
-- Target Devices: generic
25
-- Tool versions:  xst 13.1; ghdl 0.29
26
--
27
-- Synthesized (xst):
28
-- Date         Rev  ise         Target      flop lutl lutm slic t peri
29
-- 2011-11-13   424 13.1    O40d xc3s1000-4   224  362   64  295 s  8.6/10.1
30
--
31
-- Revision History: 
32
-- Date         Rev Version  Comment
33
-- 2011-12-10   438   1.0.2  internal reset on abact
34
-- 2011-12-09   437   1.0.1  rename stat->moni port
35
-- 2011-11-13   424   1.0    Initial version
36
-- 2011-11-07   421   0.5    First draft
37
------------------------------------------------------------------------------
38
 
39
library ieee;
40
use ieee.std_logic_1164.all;
41
use ieee.numeric_std.all;
42
 
43
use work.slvtypes.all;
44 19 wfjm
use work.serportlib.all;
45 16 wfjm
use work.genlib.all;
46
use work.memlib.all;
47
 
48
entity serport_2clock is                -- serial port module, 2 clock domain
49
  generic (
50
    CDWIDTH : positive := 13;           -- clk divider width
51
    CDINIT : natural   := 15;           -- clk divider initial/reset setting
52
    RXFAWIDTH : natural :=  5;          -- rx fifo address width
53
    TXFAWIDTH : natural :=  5);         -- tx fifo address width
54
  port (
55
    CLKU : in slbit;                    -- clock (backend:user)
56
    RESET : in slbit;                   -- reset
57
    CLKS : in slbit;                    -- clock (frontend:serial)
58
    CES_MSEC : in slbit;                -- S|1 msec clock enable
59
    ENAXON : in slbit;                  -- U|enable xon/xoff handling
60
    ENAESC : in slbit;                  -- U|enable xon/xoff escaping
61
    RXDATA : out slv8;                  -- U|receiver data out
62
    RXVAL : out slbit;                  -- U|receiver data valid
63
    RXHOLD : in slbit;                  -- U|receiver data hold
64
    TXDATA : in slv8;                   -- U|transmit data in
65
    TXENA : in slbit;                   -- U|transmit data enable
66
    TXBUSY : out slbit;                 -- U|transmit busy
67
    MONI : out serport_moni_type;       -- U|serport monitor port
68
    RXSD : in slbit;                    -- S|receive serial data (uart view)
69
    TXSD : out slbit;                   -- S|transmit serial data (uart view)
70
    RXRTS_N : out slbit;                -- S|receive rts (uart view, act.low)
71
    TXCTS_N : in slbit                  -- S|transmit cts (uart view, act.low)
72
  );
73
end serport_2clock;
74
 
75
 
76
architecture syn of serport_2clock is
77
 
78
  type synu_type is record
79
    rxact_c : slbit;                    -- rxact (capt from CLKS->CLKU)
80
    rxact_s : slbit;                    -- rxact (sync in CLKU)
81
    txact_c : slbit;                    -- txact (capt from CLKS->CLKU)
82
    txact_s : slbit;                    -- txact (sync in CLKU)
83
    abact_c : slbit;                    -- abact (capt from CLKS->CLKU)
84
    abact_s : slbit;                    -- abact (sync in CLKU)
85
    rxok_c : slbit;                     -- rxok (capt from CLKS->CLKU)
86
    rxok_s : slbit;                     -- rxok (sync in CLKU)
87
    txok_c : slbit;                     -- txok (capt from CLKS->CLKU)
88
    txok_s : slbit;                     -- txok (sync in CLKU)
89
    abclkdiv_c : slv(CDWIDTH-1 downto 0); -- abclkdiv (capt from CLKS->CLKU)
90
    abclkdiv_s : slv(CDWIDTH-1 downto 0); -- abclkdiv (sync in CLKU)
91
  end record synu_type;
92
 
93
  constant synu_init : synu_type := (
94
    '0','0',                            -- rxact_c,_s
95
    '0','0',                            -- txact_c,_s
96
    '0','0',                            -- abact_c,_s
97
    '0','0',                            -- rxok_c,_s
98
    '0','0',                            -- txok_c,_s
99
    slv(to_unsigned(0,CDWIDTH)),        -- abclkdiv_c
100
    slv(to_unsigned(0,CDWIDTH))         -- abclkdiv_s
101
  );
102
 
103
  type syns_type is record
104
    enaxon_c : slbit;                   -- enaxon (capt from CLKU->CLKS)
105
    enaxon_s : slbit;                   -- enaxon (sync in CLKS)
106
    enaesc_c : slbit;                   -- enaesc (capt from CLKU->CLKS)
107
    enaesc_s : slbit;                   -- enaesc (sync in CLKS)
108
  end record syns_type;
109
 
110
  constant syns_init : syns_type := (
111
    '0','0',                            -- enaxon_c,_s
112
    '0','0'                             -- enaxon_c,_s
113
  );
114
 
115
  signal R_SYNU : synu_type := synu_init;  -- sync registers (clku)
116
  signal R_SYNS : syns_type := syns_init;  -- sync registers (clks)
117
 
118
  signal R_RXOK : slbit := '1';
119
 
120
  signal RESET_INT : slbit := '0';
121
  signal RESET_CLKS : slbit := '0';
122
 
123
  signal UART_RXDATA : slv8 := (others=>'0');
124
  signal UART_RXVAL : slbit := '0';
125
  signal UART_TXDATA : slv8 := (others=>'0');
126
  signal UART_TXENA : slbit := '0';
127
  signal UART_TXBUSY : slbit := '0';
128
 
129
  signal XONTX_TXENA : slbit := '0';
130
  signal XONTX_TXBUSY : slbit := '0';
131
 
132
  signal RXFIFO_DI : slv8 := (others=>'0');
133
  signal RXFIFO_ENA : slbit := '0';
134
  signal RXFIFO_BUSY : slbit := '0';
135
  signal RXFIFO_SIZEW : slv(RXFAWIDTH-1 downto 0) := (others=>'0');
136
  signal TXFIFO_DO : slv8 := (others=>'0');
137
  signal TXFIFO_VAL : slbit := '0';
138
  signal TXFIFO_HOLD : slbit := '0';
139
 
140
  signal RXERR  : slbit := '0';
141
  signal RXOVR  : slbit := '0';
142
  signal RXACT  : slbit := '0';
143
  signal ABACT  : slbit := '0';
144
  signal ABDONE : slbit := '0';
145
  signal ABCLKDIV : slv(CDWIDTH-1 downto 0) := (others=>'0');
146
 
147
  signal TXOK : slbit := '0';
148
  signal RXOK : slbit := '0';
149
 
150
  signal RXERR_CLKU  : slbit := '0';
151
  signal RXOVR_CLKU  : slbit := '0';
152
  signal ABDONE_CLKU : slbit := '0';
153
 
154
begin
155
 
156
  assert CDWIDTH<=16
157
    report "assert(CDWIDTH<=16): max width of UART clock divider"
158
    severity failure;
159
 
160
  CDC_RESET : cdc_pulse
161
  generic map (
162
    POUT_SINGLE => false,
163
    BUSY_WACK   => false)
164
  port map (
165
    CLKM     => CLKU,
166
    RESET    => '0',
167
    CLKS     => CLKS,
168
    PIN      => RESET,
169
    BUSY     => open,
170
    POUT     => RESET_CLKS
171
  );
172
 
173
  UART : serport_uart_rxtx_ab           -- uart, rx+tx+autobauder combo
174
  generic map (
175
    CDWIDTH => CDWIDTH,
176
    CDINIT  => CDINIT)
177
  port map (
178
    CLK      => CLKS,
179
    CE_MSEC  => CES_MSEC,
180
    RESET    => RESET_CLKS,
181
    RXSD     => RXSD,
182
    RXDATA   => UART_RXDATA,
183
    RXVAL    => UART_RXVAL,
184
    RXERR    => RXERR,
185
    RXACT    => RXACT,
186
    TXSD     => TXSD,
187
    TXDATA   => UART_TXDATA,
188
    TXENA    => UART_TXENA,
189
    TXBUSY   => UART_TXBUSY,
190
    ABACT    => ABACT,
191
    ABDONE   => ABDONE,
192
    ABCLKDIV => ABCLKDIV
193
  );
194
 
195
  RESET_INT <= RESET_CLKS or ABACT;
196
 
197
  XONRX : serport_xonrx                 --  xon/xoff logic rx path
198
  port map (
199
    CLK         => CLKS,
200
    RESET       => RESET_INT,
201
    ENAXON      => R_SYNS.enaxon_s,
202
    ENAESC      => R_SYNS.enaesc_s,
203
    UART_RXDATA => UART_RXDATA,
204
    UART_RXVAL  => UART_RXVAL,
205
    RXDATA      => RXFIFO_DI,
206
    RXVAL       => RXFIFO_ENA,
207
    RXHOLD      => RXFIFO_BUSY,
208
    RXOVR       => RXOVR,
209
    TXOK        => TXOK
210
  );
211
 
212
  XONTX : serport_xontx                 --  xon/xoff logic tx path
213
  port map (
214
    CLK         => CLKS,
215
    RESET       => RESET_INT,
216
    ENAXON      => R_SYNS.enaxon_s,
217
    ENAESC      => R_SYNS.enaesc_s,
218
    UART_TXDATA => UART_TXDATA,
219
    UART_TXENA  => XONTX_TXENA,
220
    UART_TXBUSY => XONTX_TXBUSY,
221
    TXDATA      => TXFIFO_DO,
222
    TXENA       => TXFIFO_VAL,
223
    TXBUSY      => TXFIFO_HOLD,
224
    RXOK        => RXOK,
225
    TXOK        => TXOK
226
  );
227
 
228
  RXFIFO : fifo_2c_dram                 -- input fifo, 2 clock, dram based
229
  generic map (
230
    AWIDTH => RXFAWIDTH,
231
    DWIDTH => 8)
232
  port map (
233
    CLKW   => CLKS,
234
    CLKR   => CLKU,
235
    RESETW => ABACT,                    -- clear fifo on abact
236
    RESETR => RESET,
237
    DI     => RXFIFO_DI,
238
    ENA    => RXFIFO_ENA,
239
    BUSY   => RXFIFO_BUSY,
240
    DO     => RXDATA,
241
    VAL    => RXVAL,
242
    HOLD   => RXHOLD,
243
    SIZEW  => RXFIFO_SIZEW,
244
    SIZER  => open
245
  );
246
 
247
  TXFIFO : fifo_2c_dram                 -- output fifo, 2 clock, dram based
248
  generic map (
249
    AWIDTH => TXFAWIDTH,
250
    DWIDTH => 8)
251
  port map (
252
    CLKW   => CLKU,
253
    CLKR   => CLKS,
254
    RESETW => RESET,
255
    RESETR => ABACT,                    -- clear fifo on abact
256
    DI     => TXDATA,
257
    ENA    => TXENA,
258
    BUSY   => TXBUSY,
259
    DO     => TXFIFO_DO,
260
    VAL    => TXFIFO_VAL,
261
    HOLD   => TXFIFO_HOLD,
262
    SIZEW  => open,
263
    SIZER  => open
264
  );
265
 
266
  -- receive back preasure
267
  --    on if fifo more than 3/4 full (less than 1/4 free)
268
  --   off if fifo less than 1/2 full (more than 1/2 free)
269
  proc_rxok: process (CLKS)
270
    constant rxsize_rxok_off : slv2 := "01";
271
    constant rxsize_rxok_on  : slv2 := "10";
272
    variable rxsize_msb : slv2 := "00";
273
  begin
274
    if rising_edge(CLKS) then
275
      if RESET_INT = '1' then
276
        R_RXOK <= '1';
277
      else
278
        rxsize_msb := RXFIFO_SIZEW(RXFAWIDTH-1 downto RXFAWIDTH-2);
279
        if unsigned(rxsize_msb) <  unsigned(rxsize_rxok_off) then
280
          R_RXOK <= '0';
281
        elsif unsigned(RXSIZE_MSB) >=  unsigned(rxsize_rxok_on) then
282
          R_RXOK <= '1';
283
        end if;
284
      end if;
285
    end if;
286
  end process proc_rxok;
287
 
288
  RXOK    <= R_RXOK;
289
  RXRTS_N <= not R_RXOK;
290
 
291
  proc_cts: process (TXCTS_N, XONTX_TXENA, UART_TXBUSY)
292
  begin
293
    if TXCTS_N = '0' then               -- transmit cts asserted
294
      UART_TXENA   <= XONTX_TXENA;
295
      XONTX_TXBUSY <= UART_TXBUSY;
296
    else                                -- transmit cts not asserted
297
      UART_TXENA   <= '0';
298
      XONTX_TXBUSY <= '1';
299
    end if;
300
  end process proc_cts;
301
 
302
  proc_synu: process (CLKU)
303
  begin
304
    if rising_edge(CLKU) then
305
      R_SYNU.rxact_c    <= RXACT;
306
      R_SYNU.rxact_s    <= R_SYNU.rxact_c;
307
      R_SYNU.txact_c    <= UART_TXBUSY;
308
      R_SYNU.txact_s    <= R_SYNU.txact_c;
309
      R_SYNU.abact_c    <= ABACT;
310
      R_SYNU.abact_s    <= R_SYNU.abact_c;
311
      R_SYNU.rxok_c     <= RXOK;
312
      R_SYNU.rxok_s     <= R_SYNU.rxok_c;
313
      R_SYNU.txok_c     <= TXOK;
314
      R_SYNU.txok_s     <= R_SYNU.txok_c;
315
      R_SYNU.abclkdiv_c <= ABCLKDIV;
316
      R_SYNU.abclkdiv_s <= R_SYNU.abclkdiv_c;
317
    end if;
318
  end process proc_synu;
319
 
320
  proc_syns: process (CLKS)
321
  begin
322
    if rising_edge(CLKS) then
323
      R_SYNS.enaxon_c <= ENAXON;
324
      R_SYNS.enaxon_s <= R_SYNS.enaxon_c;
325
      R_SYNS.enaesc_c <= ENAESC;
326
      R_SYNS.enaesc_s <= R_SYNS.enaesc_c;
327
    end if;
328
  end process proc_syns;
329
 
330
  CDC_RXERR : cdc_pulse
331
  generic map (
332
    POUT_SINGLE => true,
333
    BUSY_WACK   => false)
334
  port map (
335
    CLKM     => CLKS,
336
    RESET    => '0',
337
    CLKS     => CLKU,
338
    PIN      => RXERR,
339
    BUSY     => open,
340
    POUT     => RXERR_CLKU
341
  );
342
 
343
  CDC_RXOVR : cdc_pulse
344
  generic map (
345
    POUT_SINGLE => true,
346
    BUSY_WACK   => false)
347
  port map (
348
    CLKM     => CLKS,
349
    RESET    => '0',
350
    CLKS     => CLKU,
351
    PIN      => RXOVR,
352
    BUSY     => open,
353
    POUT     => RXOVR_CLKU
354
  );
355
 
356
  CDC_ABDONE : cdc_pulse
357
  generic map (
358
    POUT_SINGLE => true,
359
    BUSY_WACK   => false)
360
  port map (
361
    CLKM     => CLKS,
362
    RESET    => '0',
363
    CLKS     => CLKU,
364
    PIN      => ABDONE,
365
    BUSY     => open,
366
    POUT     => ABDONE_CLKU
367
  );
368
 
369
  MONI.rxerr  <= RXERR_CLKU;
370
  MONI.rxovr  <= RXOVR_CLKU;
371
  MONI.rxact  <= R_SYNU.rxact_s;
372
  MONI.txact  <= R_SYNU.txact_s;
373
  MONI.abact  <= R_SYNU.abact_s;
374
  MONI.abdone <= ABDONE_CLKU;
375
  MONI.rxok   <= R_SYNU.rxok_s;
376
  MONI.txok   <= R_SYNU.txok_s;
377
 
378
  proc_abclkdiv: process (R_SYNU.abclkdiv_s)
379
  begin
380
    MONI.abclkdiv <= (others=>'0');
381
    MONI.abclkdiv(R_SYNU.abclkdiv_s'range) <= R_SYNU.abclkdiv_s;
382
  end process proc_abclkdiv;
383
 
384
end syn;

powered by: WebSVN 2.1.0

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