From a8dc43023e724bb1ad7ec721ed981070f270eda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 21 Nov 2017 22:48:05 +0100 Subject: [PATCH] added synchronizer ip for UART, wrote reset detection --- synchronizer.vhd | 31 ++++++++++++++++++ top.vhd | 81 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 3 deletions(-) create mode 100644 synchronizer.vhd diff --git a/synchronizer.vhd b/synchronizer.vhd new file mode 100644 index 0000000..3630ae0 --- /dev/null +++ b/synchronizer.vhd @@ -0,0 +1,31 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity synchronizer is + generic(COUNT : integer := 1); + port( + clk : in std_logic; + rst : in std_logic; + dIn : in std_logic_vector(COUNT - 1 downto 0); + dOut : out std_logic_vector(COUNT - 1 downto 0) + ); +end entity synchronizer; + +architecture RTL of synchronizer is + signal temp : std_logic_vector(COUNT - 1 downto 0); +begin + synch : process(rst, clk) is + begin + for i in 0 to COUNT - 1 loop + if rst = '1' then + temp(i) <= '0'; + dOut(i) <= '0'; + elsif rising_edge(clk) then + temp(i) <= dIn(i); + dOut(i) <= temp(i); + end if; + end loop; + end process synch; + +end architecture RTL; diff --git a/top.vhd b/top.vhd index ba3ec0b..478a1b2 100644 --- a/top.vhd +++ b/top.vhd @@ -23,11 +23,12 @@ use ieee.numeric_std.all; entity config_top is generic ( - BAUD_RATE : integer := 9600); + CLKDIV : integer := 10); port ( clk : in std_logic; -- input clock 12 MHz dts : in std_logic; -- DTS Strobe signal + rst_out : out std_logic; uart_tx : out std_logic; -- UART TX uart_rx : in std_logic); -- UART RX @@ -35,11 +36,85 @@ end entity config_top; architecture RTL of config_top is + ----------------- RESET LOGIC ------------------------------ + signal dts_sync : std_logic_vector(2 downto 0) := (others => '0'); + signal rst : std_logic; -- reset (high active) + ----------------- UART RX ---------------------------------- + signal data_rx : std_logic_vector(7 downto 0); + signal byte_ready_rx : std_logic; + signal error_rx : std_logic; + ----------------- UART TX ---------------------------------- + signal data_tx : std_logic_vector(7 downto 0); + signal byte_ready_tx : std_logic; + signal busy_tx : std_logic; + + + signal config_busy : std_logic := '1'; -- indicates that the core is in configuration/waiting mode + -- and the user logic has to stay in reset begin -- architecture RTL - - + uart_rx_1 : entity work.uart_rx + port map ( + clk => clk, + rst => rst, + data => data_rx, + byte_ready => byte_ready_rx, + error => error_rx, + ckDiv => CLKDIV, + parityEnable => '1', + parityOdd => '0', + twoStopBits => '0', + rx => uart_rx); + + uart_tx_1 : entity work.uart_tx + port map ( + clk => clk, + rst => rst, + data => data_tx, + byte_ready => byte_ready_tx, + busy => busy_tx, + ckDiv => CLKDIV, + parityEnable => '1', + parityOdd => '0', + twoStopBits => '0', + tx => uart_tx); + + + timeout_counter_gen : process(clk) is + variable cnt : integer range 0 to 40000; + begin + -- TODO: implement timeout counter + end process timeout_counter_gen; + + + -- Generate reset pulse on rising edge of dts input + reset_gen : process(clk) is + begin + if rising_edge(clk) then + rst <= '0'; + dts_sync <= dts_sync(1 downto 0) & dts; -- Shif register (sync and edge detect) + if (dts_sync(2 downto 1) = "01") then -- rising edge of DTS + rst <= '1'; + end if; + end if; + end process reset_gen; + + + -- hold user logic in reset until config finished or timeout + user_logic_reset_gen : process(clk, rst) is + begin + if rst = '1' then + rst_out <= '1'; + elsif rising_edge(clk) then + if config_busy = '0' then + rst_out <= '0'; + end if; + end if; + end process user_logic_reset_gen; + + + ------ Asynchronous output assignments --------------- end architecture RTL;