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