|
@@ -0,0 +1,131 @@
|
|
|
|
|
+library ieee;
|
|
|
|
|
+use ieee.std_logic_1164.all;
|
|
|
|
|
+use ieee.numeric_std.all;
|
|
|
|
|
+
|
|
|
|
|
+entity async_8n1_tx is
|
|
|
|
|
+ port
|
|
|
|
|
+ (
|
|
|
|
|
+ clk : in std_logic;
|
|
|
|
|
+ rst : in std_logic;
|
|
|
|
|
+ en : in std_logic;
|
|
|
|
|
+ wr : in std_logic;
|
|
|
|
|
+ data_in : in unsigned (7 downto 0);
|
|
|
|
|
+ data_out : out std_logic
|
|
|
|
|
+ );
|
|
|
|
|
+end entity;
|
|
|
|
|
+
|
|
|
|
|
+architecture beh of async_8n1_tx is
|
|
|
|
|
+ component generic_counter is
|
|
|
|
|
+ generic (
|
|
|
|
|
+ counter_bits : integer := 4
|
|
|
|
|
+ );
|
|
|
|
|
+ port(
|
|
|
|
|
+ clk : in std_logic;
|
|
|
|
|
+ rst : in std_logic;
|
|
|
|
|
+ en : in std_logic;
|
|
|
|
|
+ cnt : out unsigned (counter_bits -1 downto 0)
|
|
|
|
|
+ );
|
|
|
|
|
+ end component;
|
|
|
|
|
+
|
|
|
|
|
+ type t_output_state is (mark, space, data);
|
|
|
|
|
+ type t_tx_state is (idle, send_start, send_data, send_stop);
|
|
|
|
|
+
|
|
|
|
|
+ signal i_data_out : std_logic;
|
|
|
|
|
+ signal i_data_reg : unsigned(7 downto 0);
|
|
|
|
|
+ signal i_next_data : std_logic;
|
|
|
|
|
+ signal i_output_mux : t_output_state;
|
|
|
|
|
+ signal i_current_state : t_tx_state;
|
|
|
|
|
+ signal i_next_state : t_tx_state;
|
|
|
|
|
+ signal i_cnt : unsigned(3 downto 0);
|
|
|
|
|
+ signal i_clear_counter : std_logic;
|
|
|
|
|
+
|
|
|
|
|
+ signal tmp_current_state : integer;
|
|
|
|
|
+ signal tmp_next_state : integer;
|
|
|
|
|
+ signal tmp_output_mux : integer;
|
|
|
|
|
+begin
|
|
|
|
|
+
|
|
|
|
|
+ tmp_current_state <= t_tx_state'pos(i_current_state);
|
|
|
|
|
+ tmp_next_state <= t_tx_state'pos(i_next_state);
|
|
|
|
|
+ tmp_output_mux <= t_output_state'pos(i_output_mux);
|
|
|
|
|
+
|
|
|
|
|
+ data_out <= i_data_out;
|
|
|
|
|
+
|
|
|
|
|
+ with i_output_mux select
|
|
|
|
|
+ i_data_out <= '1' when mark,
|
|
|
|
|
+ '0' when space,
|
|
|
|
|
+ i_next_data when data;
|
|
|
|
|
+
|
|
|
|
|
+ i_next_data <= i_data_reg(0);
|
|
|
|
|
+
|
|
|
|
|
+ i_clear_counter <= '1' when i_current_state = idle or rst = '1'
|
|
|
|
|
+ else '0';
|
|
|
|
|
+
|
|
|
|
|
+ i_counter : generic_counter
|
|
|
|
|
+ port map(
|
|
|
|
|
+ clk => clk,
|
|
|
|
|
+ rst => i_clear_counter,
|
|
|
|
|
+ en => en,
|
|
|
|
|
+ cnt => i_cnt);
|
|
|
|
|
+
|
|
|
|
|
+ with i_current_state select
|
|
|
|
|
+ i_output_mux <= mark when idle,
|
|
|
|
|
+ space when send_start,
|
|
|
|
|
+ data when send_data,
|
|
|
|
|
+ mark when send_stop;
|
|
|
|
|
+
|
|
|
|
|
+ -- Concurrent process
|
|
|
|
|
+ process(i_current_state, wr, i_cnt) is
|
|
|
|
|
+ begin
|
|
|
|
|
+ if i_current_state = idle then
|
|
|
|
|
+ if wr = '1' then
|
|
|
|
|
+ i_next_state <= send_start;
|
|
|
|
|
+ else
|
|
|
|
|
+ i_next_state <= i_current_state;
|
|
|
|
|
+ end if;
|
|
|
|
|
+
|
|
|
|
|
+ elsif i_current_state = send_start then
|
|
|
|
|
+ i_next_state <= send_data;
|
|
|
|
|
+
|
|
|
|
|
+ elsif i_current_state = send_data then
|
|
|
|
|
+ if i_cnt = to_unsigned(7, 4) then
|
|
|
|
|
+ i_next_state <= send_stop;
|
|
|
|
|
+ else
|
|
|
|
|
+ i_next_state <= i_current_state;
|
|
|
|
|
+ end if;
|
|
|
|
|
+
|
|
|
|
|
+ elsif i_current_state = send_stop then
|
|
|
|
|
+ i_next_state <= idle;
|
|
|
|
|
+ else
|
|
|
|
|
+ i_next_state <= i_current_state;
|
|
|
|
|
+ end if;
|
|
|
|
|
+ end process;
|
|
|
|
|
+
|
|
|
|
|
+ -- Shift register
|
|
|
|
|
+ process(clk) is
|
|
|
|
|
+ begin
|
|
|
|
|
+ if rising_edge(clk) then
|
|
|
|
|
+ if rst = '1' then
|
|
|
|
|
+ i_data_reg <= (others => '0');
|
|
|
|
|
+ elsif en = '1' and i_current_state = send_data then
|
|
|
|
|
+ i_data_reg <= '1' & i_data_reg(7 downto 1);
|
|
|
|
|
+ elsif en = '1' and i_current_state = idle and wr = '1' then
|
|
|
|
|
+ i_data_reg <= data_in;
|
|
|
|
|
+ else
|
|
|
|
|
+ i_data_reg <= i_data_reg;
|
|
|
|
|
+ end if;
|
|
|
|
|
+ end if;
|
|
|
|
|
+ end process;
|
|
|
|
|
+
|
|
|
|
|
+ -- State machine
|
|
|
|
|
+ process(clk) is
|
|
|
|
|
+ begin
|
|
|
|
|
+ if rising_edge(clk) then
|
|
|
|
|
+ if rst = '1' then
|
|
|
|
|
+ i_current_state <= idle;
|
|
|
|
|
+ elsif en = '1' then
|
|
|
|
|
+ i_current_state <= i_next_state;
|
|
|
|
|
+ end if;
|
|
|
|
|
+ end if;
|
|
|
|
|
+ end process;
|
|
|
|
|
+
|
|
|
|
|
+end architecture;
|