@@ -30,6 +30,7 @@ use IEEE.MATH_REAL.ALL;
30
30
-- Version 1.2 -
31
31
-- Added double FF for safe CDC.
32
32
-- Fixed fake received transaction after FPGA boot without reset.
33
+ -- Added more precisely clock dividers, dividing with rounding.
33
34
34
35
entity UART is
35
36
Generic (
@@ -58,12 +59,11 @@ end entity;
58
59
59
60
architecture RTL of UART is
60
61
61
- constant DIVIDER_VALUE : integer := CLK_FREQ/ (16 * BAUD_RATE);
62
- constant CLK_CNT_WIDTH : integer := integer (ceil (log2 (real (DIVIDER_VALUE))));
63
- constant CLK_CNT_MAX : unsigned := to_unsigned (DIVIDER_VALUE- 1 , CLK_CNT_WIDTH);
62
+ constant OS_CLK_DIV_VAL : integer := integer (real (CLK_FREQ)/ real (16 * BAUD_RATE));
63
+ constant OS_CLK_DIV_WIDTH : integer := integer (ceil (log2 (real (OS_CLK_DIV_VAL))));
64
64
65
- signal oversampling_clk_cnt : unsigned (CLK_CNT_WIDTH - 1 downto 0 );
66
- signal oversampling_clk_en : std_logic ;
65
+ signal os_clk_div_cnt : unsigned (OS_CLK_DIV_WIDTH - 1 downto 0 );
66
+ signal os_clk_div_cnt_max : std_logic ;
67
67
signal uart_rxd_meta_n : std_logic ;
68
68
signal uart_rxd_synced_n : std_logic ;
69
69
signal uart_rxd_debounced_n : std_logic ;
@@ -72,25 +72,25 @@ architecture RTL of UART is
72
72
begin
73
73
74
74
-- -------------------------------------------------------------------------
75
- -- UART OVERSAMPLING (16X) CLOCK COUNTER AND CLOCK ENABLE FLAG
75
+ -- UART OVERSAMPLING (16X) CLOCK DIVIDER AND CLOCK ENABLE FLAG
76
76
-- -------------------------------------------------------------------------
77
77
78
- oversampling_clk_cnt_p : process (CLK)
78
+ os_clk_div_cnt_p : process (CLK)
79
79
begin
80
80
if (rising_edge (CLK)) then
81
81
if (RST = '1' ) then
82
- oversampling_clk_cnt <= (others => '0' );
82
+ os_clk_div_cnt <= (others => '0' );
83
83
else
84
- if (oversampling_clk_en = '1' ) then
85
- oversampling_clk_cnt <= (others => '0' );
84
+ if (os_clk_div_cnt_max = '1' ) then
85
+ os_clk_div_cnt <= (others => '0' );
86
86
else
87
- oversampling_clk_cnt <= oversampling_clk_cnt + 1 ;
87
+ os_clk_div_cnt <= os_clk_div_cnt + 1 ;
88
88
end if ;
89
89
end if ;
90
90
end if ;
91
91
end process ;
92
92
93
- oversampling_clk_en <= '1' when (oversampling_clk_cnt = CLK_CNT_MAX ) else '0' ;
93
+ os_clk_div_cnt_max <= '1' when (os_clk_div_cnt = OS_CLK_DIV_VAL - 1 ) else '0' ;
94
94
95
95
-- -------------------------------------------------------------------------
96
96
-- UART RXD CROSS DOMAIN CROSSING
@@ -132,13 +132,15 @@ begin
132
132
133
133
uart_rx_i : entity work .UART_RX
134
134
generic map (
135
- PARITY_BIT => PARITY_BIT
135
+ CLK_FREQ => CLK_FREQ,
136
+ BAUD_RATE => BAUD_RATE,
137
+ PARITY_BIT => PARITY_BIT
136
138
)
137
139
port map (
138
140
CLK => CLK,
139
141
RST => RST,
140
142
-- UART INTERFACE
141
- UART_CLK_EN => oversampling_clk_en ,
143
+ UART_CLK_EN => os_clk_div_cnt_max ,
142
144
UART_RXD => uart_rxd_debounced,
143
145
-- USER DATA OUTPUT INTERFACE
144
146
DOUT => DOUT,
@@ -153,13 +155,15 @@ begin
153
155
154
156
uart_tx_i : entity work .UART_TX
155
157
generic map (
156
- PARITY_BIT => PARITY_BIT
158
+ CLK_FREQ => CLK_FREQ,
159
+ BAUD_RATE => BAUD_RATE,
160
+ PARITY_BIT => PARITY_BIT
157
161
)
158
162
port map (
159
163
CLK => CLK,
160
164
RST => RST,
161
165
-- UART INTERFACE
162
- UART_CLK_EN => oversampling_clk_en ,
166
+ UART_CLK_EN => os_clk_div_cnt_max ,
163
167
UART_TXD => UART_TXD,
164
168
-- USER DATA INPUT INTERFACE
165
169
DIN => DIN,
0 commit comments