You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.7 KiB

  1. -- Copyright (c) 2022 by Torsten Meissner
  2. --
  3. -- Licensed under the Apache License, Version 2.0 (the "License");
  4. -- you may not use this file except in compliance with the License.
  5. -- You may obtain a copy of the License at
  6. --
  7. -- https://www.apache.org/licenses/LICENSE-2.0
  8. --
  9. -- Unless required by applicable law or agreed to in writing, software
  10. -- distributed under the License is distributed on an "AS IS" BASIS,
  11. -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. -- See the License for the specific language governing permissions and
  13. -- limitations under the License.
  14. library ieee;
  15. use ieee.std_logic_1164.all;
  16. use ieee.numeric_std.all;
  17. entity uart_tx is
  18. generic (
  19. CLK_DIV : natural := 10
  20. );
  21. port (
  22. -- globals
  23. rst_n_i : in std_logic;
  24. clk_i : in std_logic;
  25. -- axis user interface
  26. tdata_i : in std_logic_vector(7 downto 0);
  27. tvalid_i : in std_logic;
  28. tready_o : out std_logic;
  29. -- uart interface
  30. tx_o : out std_logic
  31. );
  32. end entity uart_tx;
  33. architecture rtl of uart_tx is
  34. type t_uart_state is (IDLE, SEND);
  35. signal s_uart_state : t_uart_state;
  36. signal s_data : std_logic_vector(tdata_i'length+1 downto 0);
  37. signal s_clk_cnt : natural range 0 to CLK_DIV-1;
  38. signal s_clk_en : std_logic;
  39. signal s_bit_cnt : natural range 0 to s_data'length-1;
  40. begin
  41. ClkDivP : process (clk_i, rst_n_i) is
  42. begin
  43. if (not rst_n_i) then
  44. s_clk_cnt <= CLK_DIV-1;
  45. elsif (rising_edge(clk_i)) then
  46. if (s_uart_state = IDLE) then
  47. s_clk_cnt <= CLK_DIV-2;
  48. elsif (s_uart_state = SEND) then
  49. if (s_clk_cnt = 0) then
  50. s_clk_cnt <= CLK_DIV-1;
  51. else
  52. s_clk_cnt <= s_clk_cnt - 1;
  53. end if;
  54. end if;
  55. end if;
  56. end process ClkDivP;
  57. s_clk_en <= '1' when s_uart_state = SEND and s_clk_cnt = 0 else '0';
  58. TxP : process (clk_i, rst_n_i) is
  59. begin
  60. if (not rst_n_i) then
  61. s_uart_state <= IDLE;
  62. s_data <= (0 => '1', others => '0');
  63. s_bit_cnt <= 0;
  64. elsif (rising_edge(clk_i)) then
  65. FsmL : case s_uart_state is
  66. when IDLE =>
  67. s_bit_cnt <= s_data'length-1;
  68. if (tvalid_i) then
  69. s_data <= '1' & tdata_i & '0';
  70. s_uart_state <= SEND;
  71. end if;
  72. when SEND =>
  73. if (s_clk_en) then
  74. s_data <= '1' & s_data(s_data'length-1 downto 1);
  75. if (s_bit_cnt = 0) then
  76. s_uart_state <= IDLE;
  77. else
  78. s_bit_cnt <= s_bit_cnt - 1;
  79. end if;
  80. end if;
  81. end case;
  82. end if;
  83. end process TxP;
  84. tready_o <= '1' when s_uart_state = IDLE else '0';
  85. tx_o <= s_data(0);
  86. end architecture rtl;