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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [vlib/] [serport/] [serport_2clock2.vhd] - Blame information for rev 38

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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