|
|
@@ -10,6 +10,7 @@ entity async_8n1_tx is
|
|
|
en : in std_logic;
|
|
|
wr : in std_logic;
|
|
|
data_in : in unsigned (7 downto 0);
|
|
|
+ rdy : out std_logic;
|
|
|
data_out : out std_logic
|
|
|
);
|
|
|
end entity;
|
|
|
@@ -27,13 +28,11 @@ architecture beh of async_8n1_tx is
|
|
|
);
|
|
|
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_rdy : 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);
|
|
|
@@ -41,63 +40,71 @@ architecture beh of async_8n1_tx is
|
|
|
|
|
|
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;
|
|
|
+ rdy <= i_rdy;
|
|
|
|
|
|
- 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);
|
|
|
+
|
|
|
+ -- Concurrent process, determine output
|
|
|
+ process(i_current_state, i_data_reg(0)) is
|
|
|
+ begin
|
|
|
+ case i_current_state is
|
|
|
+ when idle =>
|
|
|
+ i_data_out <= '1';
|
|
|
+ i_rdy <= '1';
|
|
|
+ i_clear_counter <= '1';
|
|
|
+ when send_start =>
|
|
|
+ i_data_out <= '0';
|
|
|
+ i_rdy <= '0';
|
|
|
+ i_clear_counter <= '1';
|
|
|
+ when send_data =>
|
|
|
+ i_data_out <= i_data_reg(0);
|
|
|
+ i_rdy <= '0';
|
|
|
+ i_clear_counter <= '0';
|
|
|
+ when send_stop =>
|
|
|
+ i_data_out <= '1';
|
|
|
+ i_rdy <= '1';
|
|
|
+ i_clear_counter <= '1';
|
|
|
+ end case;
|
|
|
+ end process;
|
|
|
|
|
|
- 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
|
|
|
+ -- Concurrent process, determine next state
|
|
|
process(i_current_state, wr, i_cnt) is
|
|
|
begin
|
|
|
- if i_current_state = idle then
|
|
|
+ case i_current_state is
|
|
|
+ when idle =>
|
|
|
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
|
|
|
+ when send_start =>
|
|
|
i_next_state <= send_data;
|
|
|
-
|
|
|
- elsif i_current_state = send_data then
|
|
|
+ when send_data =>
|
|
|
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;
|
|
|
+ when send_stop =>
|
|
|
+ if wr = '1' then
|
|
|
+ i_next_state <= send_start;
|
|
|
+ else
|
|
|
+ i_next_state <= idle;
|
|
|
+ end if;
|
|
|
+ end case;
|
|
|
+
|
|
|
end process;
|
|
|
|
|
|
-- Shift register
|