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