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