async_8n1_tx.vhd 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.numeric_std.all;
  4. entity async_8n1_tx is
  5. port
  6. (
  7. clk : in std_logic;
  8. rst : in std_logic;
  9. en : in std_logic;
  10. wr : in std_logic;
  11. data_in : in unsigned (7 downto 0);
  12. data_out : out std_logic
  13. );
  14. end entity;
  15. architecture beh of async_8n1_tx is
  16. component generic_counter is
  17. generic (
  18. counter_bits : integer := 4
  19. );
  20. port(
  21. clk : in std_logic;
  22. rst : in std_logic;
  23. en : in std_logic;
  24. cnt : out unsigned (counter_bits -1 downto 0)
  25. );
  26. end component;
  27. type t_output_state is (mark, space, data);
  28. type t_tx_state is (idle, send_start, send_data, send_stop);
  29. signal i_data_out : std_logic;
  30. signal i_data_reg : unsigned(7 downto 0);
  31. signal i_next_data : std_logic;
  32. signal i_output_mux : t_output_state;
  33. signal i_current_state : t_tx_state;
  34. signal i_next_state : t_tx_state;
  35. signal i_cnt : unsigned(3 downto 0);
  36. signal i_clear_counter : std_logic;
  37. signal tmp_current_state : integer;
  38. signal tmp_next_state : integer;
  39. signal tmp_output_mux : integer;
  40. begin
  41. tmp_current_state <= t_tx_state'pos(i_current_state);
  42. tmp_next_state <= t_tx_state'pos(i_next_state);
  43. tmp_output_mux <= t_output_state'pos(i_output_mux);
  44. data_out <= i_data_out;
  45. with i_output_mux select
  46. i_data_out <= '1' when mark,
  47. '0' when space,
  48. i_next_data when data;
  49. i_next_data <= i_data_reg(0);
  50. i_clear_counter <= '1' when i_current_state = idle or rst = '1'
  51. else '0';
  52. i_counter : generic_counter
  53. port map(
  54. clk => clk,
  55. rst => i_clear_counter,
  56. en => en,
  57. cnt => i_cnt);
  58. with i_current_state select
  59. i_output_mux <= mark when idle,
  60. space when send_start,
  61. data when send_data,
  62. mark when send_stop;
  63. -- Concurrent process
  64. process(i_current_state, wr, i_cnt) is
  65. begin
  66. if i_current_state = idle then
  67. if wr = '1' then
  68. i_next_state <= send_start;
  69. else
  70. i_next_state <= i_current_state;
  71. end if;
  72. elsif i_current_state = send_start then
  73. i_next_state <= send_data;
  74. elsif i_current_state = send_data then
  75. if i_cnt = to_unsigned(7, 4) then
  76. i_next_state <= send_stop;
  77. else
  78. i_next_state <= i_current_state;
  79. end if;
  80. elsif i_current_state = send_stop then
  81. i_next_state <= idle;
  82. else
  83. i_next_state <= i_current_state;
  84. end if;
  85. end process;
  86. -- Shift register
  87. process(clk) is
  88. begin
  89. if rising_edge(clk) then
  90. if rst = '1' then
  91. i_data_reg <= (others => '0');
  92. elsif en = '1' and i_current_state = send_data then
  93. i_data_reg <= '1' & i_data_reg(7 downto 1);
  94. elsif en = '1' and i_current_state = idle and wr = '1' then
  95. i_data_reg <= data_in;
  96. else
  97. i_data_reg <= i_data_reg;
  98. end if;
  99. end if;
  100. end process;
  101. -- State machine
  102. process(clk) is
  103. begin
  104. if rising_edge(clk) then
  105. if rst = '1' then
  106. i_current_state <= idle;
  107. elsif en = '1' then
  108. i_current_state <= i_next_state;
  109. end if;
  110. end if;
  111. end process;
  112. end architecture;