Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

182 řádky
6.9KB

  1. ---------------------------------------------------------------------
  2. -- TITLE: UART
  3. -- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
  4. -- DATE CREATED: 5/29/02
  5. -- FILENAME: uart.vhd
  6. -- PROJECT: Plasma CPU core
  7. -- COPYRIGHT: Software placed into the public domain by the author.
  8. -- Software 'as is' without warranty. Author liable for nothing.
  9. -- DESCRIPTION:
  10. -- Implements the UART.
  11. ---------------------------------------------------------------------
  12. library ieee;
  13. use ieee.std_logic_1164.all;
  14. use ieee.std_logic_misc.all;
  15. use ieee.std_logic_arith.all;
  16. use ieee.std_logic_textio.all;
  17. use ieee.std_logic_unsigned.all;
  18. use std.textio.all;
  19. use work.mlite_pack.all;
  20. entity uart is
  21. generic(log_file : string := "UNUSED");
  22. port(clk : in std_logic;
  23. reset : in std_logic;
  24. enable_read : in std_logic;
  25. enable_write : in std_logic;
  26. data_in : in std_logic_vector(7 downto 0);
  27. data_out : out std_logic_vector(7 downto 0);
  28. uart_read : in std_logic;
  29. uart_write : out std_logic;
  30. busy_write : out std_logic;
  31. data_avail : out std_logic);
  32. end; --entity uart
  33. architecture logic of uart is
  34. signal delay_write_reg : std_logic_vector(9 downto 0);
  35. signal bits_write_reg : std_logic_vector(3 downto 0);
  36. signal data_write_reg : std_logic_vector(8 downto 0);
  37. signal delay_read_reg : std_logic_vector(9 downto 0);
  38. signal bits_read_reg : std_logic_vector(3 downto 0);
  39. signal data_read_reg : std_logic_vector(7 downto 0);
  40. signal data_save_reg : std_logic_vector(17 downto 0);
  41. signal busy_write_sig : std_logic;
  42. signal read_value_reg : std_logic_vector(6 downto 0);
  43. signal uart_read2 : std_logic;
  44. begin
  45. uart_proc: process(clk, reset, enable_read, enable_write, data_in,
  46. data_write_reg, bits_write_reg, delay_write_reg,
  47. data_read_reg, bits_read_reg, delay_read_reg,
  48. data_save_reg, read_value_reg, uart_read2,
  49. busy_write_sig, uart_read)
  50. constant COUNT_VALUE : std_logic_vector(9 downto 0) :=
  51. "0100011110"; --33MHz/2/57600Hz = 0x11e
  52. -- "1101100100"; --50MHz/57600Hz = 0x364
  53. -- "0110110010"; --25MHz/57600Hz = 0x1b2 -- Plasma IF uses div2
  54. -- "0011011001"; --12.5MHz/57600Hz = 0xd9
  55. -- "0000000100"; --for debug (shorten read_value_reg)
  56. begin
  57. uart_read2 <= read_value_reg(read_value_reg'length - 1);
  58. if reset = '1' then
  59. data_write_reg <= ZERO(8 downto 1) & '1';
  60. bits_write_reg <= "0000";
  61. delay_write_reg <= ZERO(9 downto 0);
  62. read_value_reg <= ONES(read_value_reg'length-1 downto 0);
  63. data_read_reg <= ZERO(7 downto 0);
  64. bits_read_reg <= "0000";
  65. delay_read_reg <= ZERO(9 downto 0);
  66. data_save_reg <= ZERO(17 downto 0);
  67. elsif rising_edge(clk) then
  68. --Write UART
  69. if bits_write_reg = "0000" then --nothing left to write?
  70. if enable_write = '1' then
  71. delay_write_reg <= ZERO(9 downto 0); --delay before next bit
  72. bits_write_reg <= "1010"; --number of bits to write
  73. data_write_reg <= data_in & '0'; --remember data & start bit
  74. end if;
  75. else
  76. if delay_write_reg /= COUNT_VALUE then
  77. delay_write_reg <= delay_write_reg + 1; --delay before next bit
  78. else
  79. delay_write_reg <= ZERO(9 downto 0); --reset delay
  80. bits_write_reg <= bits_write_reg - 1; --bits left to write
  81. data_write_reg <= '1' & data_write_reg(8 downto 1);
  82. end if;
  83. end if;
  84. --Average uart_read signal
  85. if uart_read = '1' then
  86. if read_value_reg /= ONES(read_value_reg'length - 1 downto 0) then
  87. read_value_reg <= read_value_reg + 1;
  88. end if;
  89. else
  90. if read_value_reg /= ZERO(read_value_reg'length - 1 downto 0) then
  91. read_value_reg <= read_value_reg - 1;
  92. end if;
  93. end if;
  94. --Read UART
  95. if delay_read_reg = ZERO(9 downto 0) then --done delay for read?
  96. if bits_read_reg = "0000" then --nothing left to read?
  97. if uart_read2 = '0' then --wait for start bit
  98. delay_read_reg <= '0' & COUNT_VALUE(9 downto 1); --half period
  99. bits_read_reg <= "1001"; --bits left to read
  100. end if;
  101. else
  102. delay_read_reg <= COUNT_VALUE; --initialize delay
  103. bits_read_reg <= bits_read_reg - 1; --bits left to read
  104. data_read_reg <= uart_read2 & data_read_reg(7 downto 1);
  105. end if;
  106. else
  107. delay_read_reg <= delay_read_reg - 1; --delay
  108. end if;
  109. --Control character buffer
  110. if bits_read_reg = "0000" and delay_read_reg = COUNT_VALUE then
  111. if data_save_reg(8) = '0' or
  112. (enable_read = '1' and data_save_reg(17) = '0') then
  113. --Empty buffer
  114. data_save_reg(8 downto 0) <= '1' & data_read_reg;
  115. else
  116. --Second character in buffer
  117. data_save_reg(17 downto 9) <= '1' & data_read_reg;
  118. if enable_read = '1' then
  119. data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
  120. end if;
  121. end if;
  122. elsif enable_read = '1' then
  123. data_save_reg(17) <= '0'; --data_available
  124. data_save_reg(8 downto 0) <= data_save_reg(17 downto 9);
  125. end if;
  126. end if; --rising_edge(clk)
  127. uart_write <= data_write_reg(0);
  128. if bits_write_reg /= "0000"
  129. -- Comment out the following line for full UART simulation (much slower)
  130. and log_file = "UNUSED"
  131. then
  132. busy_write_sig <= '1';
  133. else
  134. busy_write_sig <= '0';
  135. end if;
  136. busy_write <= busy_write_sig;
  137. data_avail <= data_save_reg(8);
  138. data_out <= data_save_reg(7 downto 0);
  139. end process; --uart_proc
  140. -- synthesis_off
  141. uart_logger:
  142. if log_file /= "UNUSED" generate
  143. uart_proc: process(clk, enable_write, data_in)
  144. file store_file : text open write_mode is log_file;
  145. variable hex_file_line : line;
  146. variable c : character;
  147. variable index : natural;
  148. variable line_length : natural := 0;
  149. begin
  150. if rising_edge(clk) and busy_write_sig = '0' then
  151. if enable_write = '1' then
  152. index := conv_integer(data_in(6 downto 0));
  153. if index /= 10 then
  154. c := character'val(index);
  155. write(hex_file_line, c);
  156. line_length := line_length + 1;
  157. end if;
  158. if index = 10 or line_length >= 72 then
  159. --The following line may have to be commented out for synthesis
  160. writeline(store_file, hex_file_line);
  161. line_length := 0;
  162. end if;
  163. end if; --uart_sel
  164. end if; --rising_edge(clk)
  165. end process; --uart_proc
  166. end generate; --uart_logger
  167. -- synthesis_on
  168. end; --architecture logic