OpenCores
URL https://opencores.org/ocsvn/am9080_cpu_based_on_microcoded_am29xx_bit-slices/am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk

Subversion Repositories am9080_cpu_based_on_microcoded_am29xx_bit-slices

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/example/uart_loopback.vhd
0,0 → 1,67
--------------------------------------------------------------------------------
-- PROJECT: SIMPLE UART FOR FPGA
--------------------------------------------------------------------------------
-- MODULE: UART LOOPBACK EXAMPLE TOP MODULE
-- AUTHORS: Jakub Cabal <jakubcabal@gmail.com>
-- LICENSE: The MIT License (MIT), please read LICENSE file
-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga
--------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
-- UART FOR FPGA REQUIRES: 1 START BIT, 8 DATA BITS, 1 STOP BIT!!!
-- OTHER PARAMETERS CAN BE SET USING GENERICS.
 
entity UART_LOOPBACK is
Generic (
CLK_FREQ : integer := 50e6; -- set system clock frequency in Hz
BAUD_RATE : integer := 115200; -- baud rate value
PARITY_BIT : string := "none" -- legal values: "none", "even", "odd", "mark", "space"
);
Port (
CLK : in std_logic; -- system clock
RST_N : in std_logic; -- low active synchronous reset
-- UART INTERFACE
UART_TXD : out std_logic;
UART_RXD : in std_logic;
-- DEBUG INTERFACE
BUSY : out std_logic;
FRAME_ERR : out std_logic
);
end UART_LOOPBACK;
 
architecture FULL of UART_LOOPBACK is
 
signal data : std_logic_vector(7 downto 0);
signal valid : std_logic;
signal reset : std_logic;
 
begin
 
reset <= not RST_N;
 
uart_i: entity work.UART
generic map (
CLK_FREQ => CLK_FREQ,
BAUD_RATE => BAUD_RATE,
PARITY_BIT => PARITY_BIT
)
port map (
CLK => CLK,
RST => reset,
-- UART INTERFACE
UART_TXD => UART_TXD,
UART_RXD => UART_RXD,
-- USER DATA OUTPUT INTERFACE
DATA_OUT => data,
DATA_VLD => valid,
FRAME_ERROR => FRAME_ERR,
-- USER DATA INPUT INTERFACE
DATA_IN => data,
DATA_SEND => valid,
BUSY => BUSY
);
 
end FULL;
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/example/uart_loopback.vhd Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/example/uart_loopback_tb.vhd =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/example/uart_loopback_tb.vhd (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/example/uart_loopback_tb.vhd (revision 2) @@ -0,0 +1,115 @@ +-------------------------------------------------------------------------------- +-- PROJECT: SIMPLE UART FOR FPGA +-------------------------------------------------------------------------------- +-- MODULE: TESTBANCH OF UART LOOPBACK EXAMPLE TOP MODULE +-- AUTHORS: Jakub Cabal +-- LICENSE: The MIT License (MIT), please read LICENSE file +-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga +-------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity UART_LOOPBACK_TB is +end UART_LOOPBACK_TB; + +architecture FULL of UART_LOOPBACK_TB is + + signal CLK : std_logic := '0'; + signal RST_N : std_logic := '0'; + signal tx_uart : std_logic; + signal rx_uart : std_logic := '1'; + signal busy : std_logic; + signal frame_error : std_logic; + + constant clk_period : time := 20 ns; + constant uart_period : time := 8680.56 ns; + constant data_value : std_logic_vector(7 downto 0) := "10100111"; + constant data_value2 : std_logic_vector(7 downto 0) := "00110110"; + +begin + + utt: entity work.UART_LOOPBACK + generic map ( + CLK_FREQ => 50e6, + BAUD_RATE => 115200, + PARITY_BIT => "none" + ) + port map ( + CLK => CLK, + RST_N => RST_N, + -- UART INTERFACE + UART_TXD => tx_uart, + UART_RXD => rx_uart, + -- DEBUG INTERFACE + BUSY => busy, + FRAME_ERR => frame_error + ); + + clk_process : process + begin + CLK <= '0'; + wait for clk_period/2; + CLK <= '1'; + wait for clk_period/2; + end process; + + test_rx_uart : process + begin + rx_uart <= '1'; + RST_N <= '0'; + wait for 100 ns; + RST_N <= '1'; + + wait for uart_period; + + rx_uart <= '0'; -- start bit + wait for uart_period; + + for i in 0 to (data_value'LENGTH-1) loop + rx_uart <= data_value(i); -- data bits + wait for uart_period; + end loop; + + rx_uart <= '1'; -- stop bit + wait for uart_period; + + rx_uart <= '0'; -- start bit + wait for uart_period; + + for i in 0 to (data_value2'LENGTH-1) loop + rx_uart <= data_value2(i); -- data bits + wait for uart_period; + end loop; + + rx_uart <= '1'; -- stop bit + wait for uart_period; + + rx_uart <= '0'; -- start bit + wait for uart_period; + + for i in 0 to (data_value'LENGTH-1) loop + rx_uart <= data_value(i); -- data bits + wait for uart_period; + end loop; + + rx_uart <= '1'; -- stop bit + wait for uart_period; + + rx_uart <= '0'; -- start bit + wait for uart_period; + + for i in 0 to (data_value2'LENGTH-1) loop + rx_uart <= data_value2(i); -- data bits + wait for uart_period; + end loop; + + rx_uart <= '1'; -- stop bit + wait for uart_period; + + wait; + + end process; + +end FULL;
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/example/uart_loopback_tb.vhd Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_parity.vhd =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_parity.vhd (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_parity.vhd (revision 2) @@ -0,0 +1,73 @@ +-------------------------------------------------------------------------------- +-- PROJECT: SIMPLE UART FOR FPGA +-------------------------------------------------------------------------------- +-- MODULE: UART PARITY BIT GENERATOR +-- AUTHORS: Jakub Cabal +-- LICENSE: The MIT License (MIT), please read LICENSE file +-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga +-------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity UART_PARITY is + Generic ( + DATA_WIDTH : integer := 8; + PARITY_TYPE : string := "none" -- legal values: "none", "even", "odd", "mark", "space" + ); + Port ( + DATA_IN : in std_logic_vector(DATA_WIDTH-1 downto 0); + PARITY_OUT : out std_logic + ); +end UART_PARITY; + +architecture FULL of UART_PARITY is + +begin + + -- ------------------------------------------------------------------------- + -- PARITY BIT GENERATOR + -- ------------------------------------------------------------------------- + + even_parity_g : if (PARITY_TYPE = "even") generate + + process (DATA_IN) + variable parity_temp : std_logic; + begin + parity_temp := '0'; + for i in DATA_IN'range loop + parity_temp := parity_temp XOR DATA_IN(i); + end loop; + PARITY_OUT <= parity_temp; + end process; + + end generate; + + odd_parity_g : if (PARITY_TYPE = "odd") generate + + process (DATA_IN) + variable parity_temp : std_logic; + begin + parity_temp := '1'; + for i in DATA_IN'range loop + parity_temp := parity_temp XOR DATA_IN(i); + end loop; + PARITY_OUT <= parity_temp; + end process; + + end generate; + + mark_parity_g : if (PARITY_TYPE = "mark") generate + + PARITY_OUT <= '1'; + + end generate; + + space_parity_g : if (PARITY_TYPE = "space") generate + + PARITY_OUT <= '0'; + + end generate; + +end FULL;
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_parity.vhd Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_rx.vhd =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_rx.vhd (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_rx.vhd (revision 2) @@ -0,0 +1,270 @@ +-------------------------------------------------------------------------------- +-- PROJECT: SIMPLE UART FOR FPGA +-------------------------------------------------------------------------------- +-- MODULE: UART RECEIVER +-- AUTHORS: Jakub Cabal +-- LICENSE: The MIT License (MIT), please read LICENSE file +-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga +-------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity UART_RX is + Generic ( + PARITY_BIT : string := "none" -- type of parity: "none", "even", "odd", "mark", "space" + ); + Port ( + CLK : in std_logic; -- system clock + RST : in std_logic; -- high active synchronous reset + -- UART INTERFACE + UART_CLK_EN : in std_logic; -- oversampling (16x) UART clock enable + UART_RXD : in std_logic; -- serial receive data + -- USER DATA OUTPUT INTERFACE + DATA_OUT : out std_logic_vector(7 downto 0); -- output data + DATA_VLD : out std_logic; -- when DATA_VLD = 1, output data are valid + FRAME_ERROR : out std_logic -- when FRAME_ERROR = 1, stop bit was invalid + ); +end UART_RX; + +architecture FULL of UART_RX is + + signal rx_clk_en : std_logic; + signal rx_ticks : unsigned(3 downto 0); + signal rx_clk_divider_en : std_logic; + signal rx_data : std_logic_vector(7 downto 0); + signal rx_bit_count : unsigned(2 downto 0); + signal rx_receiving_data : std_logic; + signal rx_parity_bit : std_logic; + signal rx_parity_error : std_logic; + signal rx_parity_check_en : std_logic; + signal rx_output_reg_en : std_logic; + + type state is (idle, startbit, databits, paritybit, stopbit); + signal rx_pstate : state; + signal rx_nstate : state; + +begin + + -- ------------------------------------------------------------------------- + -- UART RECEIVER CLOCK DIVIDER AND CLOCK ENABLE FLAG + -- ------------------------------------------------------------------------- + + uart_rx_clk_divider_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (rx_clk_divider_en = '1') then + if (uart_clk_en = '1') then + if (rx_ticks = "1111") then + rx_ticks <= (others => '0'); + else + rx_ticks <= rx_ticks + 1; + end if; + else + rx_ticks <= rx_ticks; + end if; + else + rx_ticks <= (others => '0'); + end if; + end if; + end process; + + uart_rx_clk_en_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + rx_clk_en <= '0'; + elsif (uart_clk_en = '1' AND rx_ticks = "0111") then + rx_clk_en <= '1'; + else + rx_clk_en <= '0'; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART RECEIVER BIT COUNTER + -- ------------------------------------------------------------------------- + + uart_rx_bit_counter_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + rx_bit_count <= (others => '0'); + elsif (rx_clk_en = '1' AND rx_receiving_data = '1') then + if (rx_bit_count = "111") then + rx_bit_count <= (others => '0'); + else + rx_bit_count <= rx_bit_count + 1; + end if; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART RECEIVER DATA SHIFT REGISTER + -- ------------------------------------------------------------------------- + + uart_rx_data_shift_reg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + rx_data <= (others => '0'); + elsif (rx_clk_en = '1' AND rx_receiving_data = '1') then + rx_data <= UART_RXD & rx_data(7 downto 1); + end if; + end if; + end process; + + DATA_OUT <= rx_data; + + -- ------------------------------------------------------------------------- + -- UART RECEIVER PARITY GENERATOR AND CHECK + -- ------------------------------------------------------------------------- + + uart_rx_parity_g : if (PARITY_BIT /= "none") generate + uart_rx_parity_gen_i: entity work.UART_PARITY + generic map ( + DATA_WIDTH => 8, + PARITY_TYPE => PARITY_BIT + ) + port map ( + DATA_IN => rx_data, + PARITY_OUT => rx_parity_bit + ); + + uart_rx_parity_check_reg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + rx_parity_error <= '0'; + elsif (rx_parity_check_en = '1') then + rx_parity_error <= rx_parity_bit XOR UART_RXD; + end if; + end if; + end process; + end generate; + + uart_rx_noparity_g : if (PARITY_BIT = "none") generate + rx_parity_error <= '0'; + end generate; + + -- ------------------------------------------------------------------------- + -- UART RECEIVER OUTPUT REGISTER + -- ------------------------------------------------------------------------- + + uart_rx_output_reg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + DATA_VLD <= '0'; + FRAME_ERROR <= '0'; + else + if (rx_clk_en = '1' AND rx_output_reg_en = '1') then + DATA_VLD <= NOT rx_parity_error AND UART_RXD; + FRAME_ERROR <= NOT UART_RXD; + else + DATA_VLD <= '0'; + FRAME_ERROR <= '0'; + end if; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART RECEIVER FSM + -- ------------------------------------------------------------------------- + + -- PRESENT STATE REGISTER + process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + rx_pstate <= idle; + else + rx_pstate <= rx_nstate; + end if; + end if; + end process; + + -- NEXT STATE AND OUTPUTS LOGIC + process (rx_pstate, UART_RXD, rx_clk_en, rx_bit_count) + begin + case rx_pstate is + + when idle => + rx_output_reg_en <= '0'; + rx_receiving_data <= '0'; + rx_clk_divider_en <= '0'; + rx_parity_check_en <= '0'; + + if (UART_RXD = '0') then + rx_nstate <= startbit; + else + rx_nstate <= idle; + end if; + + when startbit => + rx_output_reg_en <= '0'; + rx_receiving_data <= '0'; + rx_clk_divider_en <= '1'; + rx_parity_check_en <= '0'; + + if (rx_clk_en = '1') then + rx_nstate <= databits; + else + rx_nstate <= startbit; + end if; + + when databits => + rx_output_reg_en <= '0'; + rx_receiving_data <= '1'; + rx_clk_divider_en <= '1'; + rx_parity_check_en <= '0'; + + if ((rx_clk_en = '1') AND (rx_bit_count = "111")) then + if (PARITY_BIT = "none") then + rx_nstate <= stopbit; + else + rx_nstate <= paritybit; + end if ; + else + rx_nstate <= databits; + end if; + + when paritybit => + rx_output_reg_en <= '0'; + rx_receiving_data <= '0'; + rx_clk_divider_en <= '1'; + rx_parity_check_en <= '1'; + + if (rx_clk_en = '1') then + rx_nstate <= stopbit; + else + rx_nstate <= paritybit; + end if; + + when stopbit => + rx_receiving_data <= '0'; + rx_clk_divider_en <= '1'; + rx_parity_check_en <= '0'; + rx_output_reg_en <= '1'; + + if (rx_clk_en = '1') then + rx_nstate <= idle; + else + rx_nstate <= stopbit; + end if; + + when others => + rx_output_reg_en <= '0'; + rx_receiving_data <= '0'; + rx_clk_divider_en <= '0'; + rx_parity_check_en <= '0'; + rx_nstate <= idle; + + end case; + end process; + +end FULL;
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_rx.vhd Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_tx.vhd =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_tx.vhd (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_tx.vhd (revision 2) @@ -0,0 +1,275 @@ +-------------------------------------------------------------------------------- +-- PROJECT: SIMPLE UART FOR FPGA +-------------------------------------------------------------------------------- +-- MODULE: UART TRANSMITTER +-- AUTHORS: Jakub Cabal +-- LICENSE: The MIT License (MIT), please read LICENSE file +-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga +-------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity UART_TX is + Generic ( + PARITY_BIT : string := "none" -- type of parity: "none", "even", "odd", "mark", "space" + ); + Port ( + CLK : in std_logic; -- system clock + RST : in std_logic; -- high active synchronous reset + -- UART INTERFACE + UART_CLK_EN : in std_logic; -- oversampling (16x) UART clock enable + UART_TXD : out std_logic; -- serial transmit data + -- USER DATA INPUT INTERFACE + DATA_IN : in std_logic_vector(7 downto 0); -- input data + DATA_SEND : in std_logic; -- when DATA_SEND = 1, input data are valid and will be transmit + BUSY : out std_logic -- when BUSY = 1, transmitter is busy and you must not set DATA_SEND to 1 + ); +end UART_TX; + +architecture FULL of UART_TX is + + signal tx_clk_en : std_logic; + signal tx_clk_divider_en : std_logic; + signal tx_ticks : unsigned(3 downto 0); + signal tx_data : std_logic_vector(7 downto 0); + signal tx_bit_count : unsigned(2 downto 0); + signal tx_bit_count_en : std_logic; + signal tx_busy : std_logic; + signal tx_parity_bit : std_logic; + signal tx_data_out_sel : std_logic_vector(1 downto 0); + + type state is (idle, txsync, startbit, databits, paritybit, stopbit); + signal tx_pstate : state; + signal tx_nstate : state; + +begin + + BUSY <= tx_busy; + + -- ------------------------------------------------------------------------- + -- UART TRANSMITTER CLOCK DIVIDER + -- ------------------------------------------------------------------------- + + uart_tx_clk_divider_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (tx_clk_divider_en = '1') then + if (uart_clk_en = '1') then + if (tx_ticks = "1111") then + tx_ticks <= (others => '0'); + else + tx_ticks <= tx_ticks + 1; + end if; + else + tx_ticks <= tx_ticks; + end if; + else + tx_ticks <= (others => '0'); + end if; + end if; + end process; + + uart_tx_clk_en_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + tx_clk_en <= '0'; + elsif (uart_clk_en = '1' AND tx_ticks = "0001") then + tx_clk_en <= '1'; + else + tx_clk_en <= '0'; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART TRANSMITTER INPUT DATA REGISTER + -- ------------------------------------------------------------------------- + + uart_tx_input_data_reg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + tx_data <= (others => '0'); + elsif (DATA_SEND = '1' AND tx_busy = '0') then + tx_data <= DATA_IN; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART TRANSMITTER BIT COUNTER + -- ------------------------------------------------------------------------- + + uart_tx_bit_counter_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + tx_bit_count <= (others => '0'); + elsif (tx_bit_count_en = '1' AND tx_clk_en = '1') then + if (tx_bit_count = "111") then + tx_bit_count <= (others => '0'); + else + tx_bit_count <= tx_bit_count + 1; + end if; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART TRANSMITTER PARITY GENERATOR + -- ------------------------------------------------------------------------- + + uart_tx_parity_g : if (PARITY_BIT /= "none") generate + uart_tx_parity_gen_i: entity work.UART_PARITY + generic map ( + DATA_WIDTH => 8, + PARITY_TYPE => PARITY_BIT + ) + port map ( + DATA_IN => tx_data, + PARITY_OUT => tx_parity_bit + ); + end generate; + + uart_tx_noparity_g : if (PARITY_BIT = "none") generate + tx_parity_bit <= 'Z'; + end generate; + + -- ------------------------------------------------------------------------- + -- UART TRANSMITTER OUTPUT DATA REGISTER + -- ------------------------------------------------------------------------- + + uart_tx_output_data_reg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + UART_TXD <= '1'; + else + case tx_data_out_sel is + when "01" => -- START BIT + UART_TXD <= '0'; + when "10" => -- DATA BITS + UART_TXD <= tx_data(to_integer(tx_bit_count)); + when "11" => -- PARITY BIT + UART_TXD <= tx_parity_bit; + when others => -- STOP BIT OR IDLE + UART_TXD <= '1'; + end case; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART TRANSMITTER FSM + -- ------------------------------------------------------------------------- + + -- PRESENT STATE REGISTER + process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + tx_pstate <= idle; + else + tx_pstate <= tx_nstate; + end if; + end if; + end process; + + -- NEXT STATE AND OUTPUTS LOGIC + process (tx_pstate, DATA_SEND, tx_clk_en, tx_bit_count) + begin + + case tx_pstate is + + when idle => + tx_busy <= '0'; + tx_data_out_sel <= "00"; + tx_bit_count_en <= '0'; + tx_clk_divider_en <= '0'; + + if (DATA_SEND = '1') then + tx_nstate <= txsync; + else + tx_nstate <= idle; + end if; + + when txsync => + tx_busy <= '1'; + tx_data_out_sel <= "00"; + tx_bit_count_en <= '0'; + tx_clk_divider_en <= '1'; + + if (tx_clk_en = '1') then + tx_nstate <= startbit; + else + tx_nstate <= txsync; + end if; + + when startbit => + tx_busy <= '1'; + tx_data_out_sel <= "01"; + tx_bit_count_en <= '0'; + tx_clk_divider_en <= '1'; + + if (tx_clk_en = '1') then + tx_nstate <= databits; + else + tx_nstate <= startbit; + end if; + + when databits => + tx_busy <= '1'; + tx_data_out_sel <= "10"; + tx_bit_count_en <= '1'; + tx_clk_divider_en <= '1'; + + if ((tx_clk_en = '1') AND (tx_bit_count = "111")) then + if (PARITY_BIT = "none") then + tx_nstate <= stopbit; + else + tx_nstate <= paritybit; + end if ; + else + tx_nstate <= databits; + end if; + + when paritybit => + tx_busy <= '1'; + tx_data_out_sel <= "11"; + tx_bit_count_en <= '0'; + tx_clk_divider_en <= '1'; + + if (tx_clk_en = '1') then + tx_nstate <= stopbit; + else + tx_nstate <= paritybit; + end if; + + when stopbit => + tx_busy <= '0'; + tx_data_out_sel <= "00"; + tx_bit_count_en <= '0'; + tx_clk_divider_en <= '1'; + + if (DATA_SEND = '1') then + tx_nstate <= txsync; + elsif (tx_clk_en = '1') then + tx_nstate <= idle; + else + tx_nstate <= stopbit; + end if; + + when others => + tx_busy <= '1'; + tx_data_out_sel <= "00"; + tx_bit_count_en <= '0'; + tx_clk_divider_en <= '0'; + tx_nstate <= idle; + + end case; + end process; + +end FULL;
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/comp/uart_tx.vhd Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart.vhd =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart.vhd (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart.vhd (revision 2) @@ -0,0 +1,162 @@ +-------------------------------------------------------------------------------- +-- PROJECT: SIMPLE UART FOR FPGA +-------------------------------------------------------------------------------- +-- MODULE: UART TOP MODULE +-- AUTHORS: Jakub Cabal +-- LICENSE: The MIT License (MIT), please read LICENSE file +-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga +-------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use IEEE.MATH_REAL.ALL; + +-- UART FOR FPGA REQUIRES: 1 START BIT, 8 DATA BITS, 1 STOP BIT!!! +-- OTHER PARAMETERS CAN BE SET USING GENERICS. + +entity UART is + Generic ( + CLK_FREQ : integer := 50e6; -- system clock frequency in Hz + BAUD_RATE : integer := 115200; -- baud rate value + PARITY_BIT : string := "none"; -- type of parity: "none", "even", "odd", "mark", "space" + USE_DEBOUNCER : boolean := True -- enable/disable debouncer + ); + Port ( + CLK : in std_logic; -- system clock + RST : in std_logic; -- high active synchronous reset + -- UART INTERFACE + UART_TXD : out std_logic; -- serial transmit data + UART_RXD : in std_logic; -- serial receive data + -- USER DATA INPUT INTERFACE + DATA_IN : in std_logic_vector(7 downto 0); -- input data + DATA_SEND : in std_logic; -- when DATA_SEND = 1, input data are valid and will be transmit + BUSY : out std_logic; -- when BUSY = 1, transmitter is busy and you must not set DATA_SEND to 1 + -- USER DATA OUTPUT INTERFACE + DATA_OUT : out std_logic_vector(7 downto 0); -- output data + DATA_VLD : out std_logic; -- when DATA_VLD = 1, output data are valid + FRAME_ERROR : out std_logic -- when FRAME_ERROR = 1, stop bit was invalid + ); +end UART; + +architecture FULL of UART is + + constant DIVIDER_VALUE : integer := CLK_FREQ/(16*BAUD_RATE); + constant CLK_CNT_WIDTH : integer := integer(ceil(log2(real(DIVIDER_VALUE)))); + constant CLK_CNT_MAX : unsigned := to_unsigned(DIVIDER_VALUE-1, CLK_CNT_WIDTH); + + signal uart_clk_cnt : unsigned(CLK_CNT_WIDTH-1 downto 0); + signal uart_clk_en : std_logic; + signal uart_rxd_shreg : std_logic_vector(3 downto 0); + signal uart_rxd_debounced : std_logic; + +begin + + -- ------------------------------------------------------------------------- + -- UART CLOCK COUNTER AND CLOCK ENABLE FLAG + -- ------------------------------------------------------------------------- + + uart_clk_cnt_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + uart_clk_cnt <= (others => '0'); + else + if (uart_clk_cnt = CLK_CNT_MAX) then + uart_clk_cnt <= (others => '0'); + else + uart_clk_cnt <= uart_clk_cnt + 1; + end if; + end if; + end if; + end process; + + uart_clk_en_reg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + uart_clk_en <= '0'; + elsif (uart_clk_cnt = CLK_CNT_MAX) then + uart_clk_en <= '1'; + else + uart_clk_en <= '0'; + end if; + end if; + end process; + + -- ------------------------------------------------------------------------- + -- UART RXD SHIFT REGISTER AND DEBAUNCER + -- ------------------------------------------------------------------------- + + use_debouncer_g : if (USE_DEBOUNCER = True) generate + uart_rxd_shreg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + uart_rxd_shreg <= (others => '1'); + else + uart_rxd_shreg <= UART_RXD & uart_rxd_shreg(3 downto 1); + end if; + end if; + end process; + + uart_rxd_debounced_reg_p : process (CLK) + begin + if (rising_edge(CLK)) then + if (RST = '1') then + uart_rxd_debounced <= '1'; + else + uart_rxd_debounced <= uart_rxd_shreg(0) OR + uart_rxd_shreg(1) OR + uart_rxd_shreg(2) OR + uart_rxd_shreg(3); + end if; + end if; + end process; + end generate; + + not_use_debouncer_g : if (USE_DEBOUNCER = False) generate + uart_rxd_debounced <= UART_RXD; + end generate; + + -- ------------------------------------------------------------------------- + -- UART TRANSMITTER + -- ------------------------------------------------------------------------- + + uart_tx_i: entity work.UART_TX + generic map ( + PARITY_BIT => PARITY_BIT + ) + port map ( + CLK => CLK, + RST => RST, + -- UART INTERFACE + UART_CLK_EN => uart_clk_en, + UART_TXD => UART_TXD, + -- USER DATA INPUT INTERFACE + DATA_IN => DATA_IN, + DATA_SEND => DATA_SEND, + BUSY => BUSY + ); + + -- ------------------------------------------------------------------------- + -- UART RECEIVER + -- ------------------------------------------------------------------------- + + uart_rx_i: entity work.UART_RX + generic map ( + PARITY_BIT => PARITY_BIT + ) + port map ( + CLK => CLK, + RST => RST, + -- UART INTERFACE + UART_CLK_EN => uart_clk_en, + UART_RXD => uart_rxd_debounced, + -- USER DATA OUTPUT INTERFACE + DATA_OUT => DATA_OUT, + DATA_VLD => DATA_VLD, + FRAME_ERROR => FRAME_ERROR + ); + +end FULL;
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart.vhd Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart_tb.vhd =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart_tb.vhd (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart_tb.vhd (revision 2) @@ -0,0 +1,136 @@ +-------------------------------------------------------------------------------- +-- PROJECT: SIMPLE UART FOR FPGA +-------------------------------------------------------------------------------- +-- MODULE: TESTBANCH OF UART TOP MODULE +-- AUTHORS: Jakub Cabal +-- LICENSE: The MIT License (MIT), please read LICENSE file +-- WEBSITE: https://github.com/jakubcabal/uart_for_fpga +-------------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity UART_TB is +end UART_TB; + +architecture FULL of UART_TB is + + signal CLK : std_logic := '0'; + signal RST : std_logic := '0'; + signal tx_uart : std_logic; + signal rx_uart : std_logic := '1'; + signal data_vld : std_logic; + signal data_out : std_logic_vector(7 downto 0); + signal frame_error : std_logic; + signal data_send : std_logic; + signal busy : std_logic; + signal data_in : std_logic_vector(7 downto 0); + + constant clk_period : time := 20 ns; + constant uart_period : time := 8680.56 ns; + constant data_value : std_logic_vector(7 downto 0) := "10100111"; + constant data_value2 : std_logic_vector(7 downto 0) := "00110110"; + +begin + + utt: entity work.UART + generic map ( + CLK_FREQ => 50e6, + BAUD_RATE => 115200, + PARITY_BIT => "none" + ) + port map ( + CLK => CLK, + RST => RST, + -- UART INTERFACE + UART_TXD => tx_uart, + UART_RXD => rx_uart, + -- USER DATA INPUT INTERFACE + DATA_OUT => data_out, + DATA_VLD => data_vld, + FRAME_ERROR => frame_error, + -- USER DATA OUTPUT INTERFACE + DATA_IN => data_in, + DATA_SEND => data_send, + BUSY => busy + ); + + clk_process : process + begin + CLK <= '0'; + wait for clk_period/2; + CLK <= '1'; + wait for clk_period/2; + end process; + + test_rx_uart : process + begin + rx_uart <= '1'; + RST <= '1'; + wait for 100 ns; + RST <= '0'; + + wait until rising_edge(CLK); + + rx_uart <= '0'; -- start bit + wait for uart_period; + + for i in 0 to (data_value'LENGTH-1) loop + rx_uart <= data_value(i); -- data bits + wait for uart_period; + end loop; + + rx_uart <= '1'; -- stop bit + wait for uart_period; + + rx_uart <= '0'; -- start bit + wait for uart_period; + + for i in 0 to (data_value2'LENGTH-1) loop + rx_uart <= data_value2(i); -- data bits + wait for uart_period; + end loop; + + rx_uart <= '1'; -- stop bit + wait for uart_period; + + wait; + + end process; + + test_tx_uart : process + begin + data_send <= '0'; + RST <= '1'; + wait for 100 ns; + RST <= '0'; + + wait until rising_edge(CLK); + + data_send <= '1'; + data_in <= data_value; + + wait until rising_edge(CLK); + + data_send <= '0'; + + wait until rising_edge(CLK); + + wait for 80 us; + wait until rising_edge(CLK); + + data_send <= '1'; + data_in <= data_value2; + + wait until rising_edge(CLK); + + data_send <= '0'; + + wait until rising_edge(CLK); + + wait; + + end process; + +end FULL;
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/source/uart_tb.vhd Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/LICENSE =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/LICENSE (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/LICENSE (revision 2) @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jakub Cabal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/LICENSE Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/README.md =================================================================== --- am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/README.md (nonexistent) +++ am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/README.md (revision 2) @@ -0,0 +1,48 @@ +# Simple UART for FPGA + +Simple UART for FPGA is UART (Universal Asynchronous Receiver & Transmitter) controller for serial communication with an FPGA. The UART controller was implemented using VHDL 93 and is applicable to any FPGA. + +**Simple UART for FPGA requires: 1 start bit, 8 data bits, 1 stop bit!** + +The UART controller was simulated and tested in hardware. + +# Table of inputs and outputs ports: + +Port name | IN/OUT | Width | Port description +---|:---:|:---:|--- +CLK | IN | 1b | System clock. +RST | IN | 1b | High active synchronous reset. +UART_TXD | OUT | 1b | Serial transmit data. +UART_RXD | IN | 1b | Serial receive data. +DATA_IN | IN | 8b | Data byte for transmit. +DATA_SEND | IN | 1b | Send data byte for transmit. +BUSY | OUT | 1b | Transmitter is busy, can not send next data. +DATA_OUT | OUT | 8b | Received data byte. +DATA_VLD | OUT | 1b | Received data byte is valid. +FRAME_ERROR | OUT | 1b | Stop bit is invalid, data may be corrupted. + +# Table of generics: + +Generic name | Type | Default value | Generic description +---|:---:|:---:|:--- +CLK_FREQ | integer | 50e6 | System clock. +BAUD_RATE | integer | 115200 | Baud rate value. +PARITY_BIT | string | "none" | Type of parity: "none", "even", "odd", "mark", "space". +USE_DEBOUNCER | boolean | True | Use debounce? + +# Table of resource usage summary: + +Use debouncer | Parity type | LE (LUT+FF) | LUT | FF | BRAM | Fmax +:---:|:---:|:---:|:---:|:---:|:---:|:---: +True | none | 77 | 64 | 55 | 0 | 202.2 MHz +True | even/odd | 82 | 75 | 58 | 0 | 162.5 MHz +True | mark/space | 80 | 68 | 58 | 0 | 184.5 MHz +False | none | 72 | 59 | 50 | 0 | 182.7 MHz +False | even/odd | 77 | 70 | 53 | 0 | 155.6 MHz +False | mark/space | 75 | 62 | 53 | 0 | 200.8 MHz + +*Synthesis was performed using Quartus II 64-Bit Version 13.0.1 for FPGA Altera Cyclone II with enable force use of synchronous clear. Setting of some generics: BAUD_RATE = 115200, CLK_FREQ = 50e6.* + +# License: + +This UART controller is available under the MIT license (MIT). Please read [LICENSE file](LICENSE).
am9080_cpu_based_on_microcoded_am29xx_bit-slices/trunk/uart-for-fpga-master/README.md Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.