@@ -30,6 +30,7 @@ use IEEE.MATH_REAL.ALL;
3030-- Version 1.2 -
3131 -- Added double FF for safe CDC.
3232 -- Fixed fake received transaction after FPGA boot without reset.
33+ -- Added more precisely clock dividers, dividing with rounding.
3334
3435entity UART is
3536 Generic (
@@ -58,12 +59,11 @@ end entity;
5859
5960architecture RTL of UART is
6061
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))));
6464
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 ;
6767 signal uart_rxd_meta_n : std_logic ;
6868 signal uart_rxd_synced_n : std_logic ;
6969 signal uart_rxd_debounced_n : std_logic ;
@@ -72,25 +72,25 @@ architecture RTL of UART is
7272begin
7373
7474 -- -------------------------------------------------------------------------
75- -- UART OVERSAMPLING (16X) CLOCK COUNTER AND CLOCK ENABLE FLAG
75+ -- UART OVERSAMPLING (16X) CLOCK DIVIDER AND CLOCK ENABLE FLAG
7676 -- -------------------------------------------------------------------------
7777
78- oversampling_clk_cnt_p : process (CLK)
78+ os_clk_div_cnt_p : process (CLK)
7979 begin
8080 if (rising_edge (CLK)) then
8181 if (RST = '1' ) then
82- oversampling_clk_cnt <= (others => '0' );
82+ os_clk_div_cnt <= (others => '0' );
8383 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' );
8686 else
87- oversampling_clk_cnt <= oversampling_clk_cnt + 1 ;
87+ os_clk_div_cnt <= os_clk_div_cnt + 1 ;
8888 end if ;
8989 end if ;
9090 end if ;
9191 end process ;
9292
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' ;
9494
9595 -- -------------------------------------------------------------------------
9696 -- UART RXD CROSS DOMAIN CROSSING
@@ -132,13 +132,15 @@ begin
132132
133133 uart_rx_i: entity work.UART_RX
134134 generic map (
135- PARITY_BIT => PARITY_BIT
135+ CLK_FREQ => CLK_FREQ,
136+ BAUD_RATE => BAUD_RATE,
137+ PARITY_BIT => PARITY_BIT
136138 )
137139 port map (
138140 CLK => CLK,
139141 RST => RST,
140142 -- UART INTERFACE
141- UART_CLK_EN => oversampling_clk_en ,
143+ UART_CLK_EN => os_clk_div_cnt_max ,
142144 UART_RXD => uart_rxd_debounced,
143145 -- USER DATA OUTPUT INTERFACE
144146 DOUT => DOUT,
@@ -153,13 +155,15 @@ begin
153155
154156 uart_tx_i: entity work.UART_TX
155157 generic map (
156- PARITY_BIT => PARITY_BIT
158+ CLK_FREQ => CLK_FREQ,
159+ BAUD_RATE => BAUD_RATE,
160+ PARITY_BIT => PARITY_BIT
157161 )
158162 port map (
159163 CLK => CLK,
160164 RST => RST,
161165 -- UART INTERFACE
162- UART_CLK_EN => oversampling_clk_en ,
166+ UART_CLK_EN => os_clk_div_cnt_max ,
163167 UART_TXD => UART_TXD,
164168 -- USER DATA INPUT INTERFACE
165169 DIN => DIN,
0 commit comments