Advertisement
uas_arduino

VHDL Serial Fixed (RX Only)

Sep 21st, 2014
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 6.28 KB | None | 0 0
  1. library ieee;
  2.  
  3. use ieee.std_logic_1164.all;
  4. use ieee.numeric_std.all;
  5.  
  6. --
  7. -- There is an odd thing that happens in this module
  8. --   Since rx going low is the signal to start processing,
  9. --   having rx_buffer default to '0' is a problem.  This
  10. --   causes processing to kick off at the wrong time.  It's
  11. --   only really a problem for the first byte of data.  To
  12. --   solve this issue, the rx_buffer signal is inverted so that
  13. --   resetting to '0' is not an issue.
  14.  
  15. -- This design is meant to work with a 100 MHz clock (clk) and
  16. -- 115,200 bauds per second serial transmissions using 8N1
  17. -- (8 data bits, no parity, 1 stop bit)
  18.  
  19. -- Any changes to the clock rate or baud rate will require a change
  20. -- to the signal counter_max.  Use this equation to assign counter_max:
  21. --      (clock_rate_in_hz / baud_rate_in_hz) - 1
  22. -- Ex: for a 100 MHz clock, and 115,200 bauds per second:
  23. --      (100,000,000 / 115,200) - 1 = approx 867
  24. entity serial_rx is
  25.     port(clk  : in  std_logic;  -- input clock
  26.           rst  : in  std_logic;  -- reset
  27.           rx   : in  std_logic;  -- serial rx line (tx from the other device)
  28.           leds : out std_logic_vector(7 downto 0)); -- LEDs to show data with
  29. end serial_rx;
  30.  
  31. architecture behave of serial_rx is
  32.     -- main state machine type.  4 stages
  33.     type state_t is (IDLE, START_BIT, HANDLE_DATA, STOP_BIT);
  34.     -- keeps track of the current state
  35.     signal rx_state : state_t := IDLE;
  36.    
  37.     -- Holds the max value of the counter for the baud rate
  38.     -- that was calculated with "(clock_rate_in_hz / baud_rate) - 1"
  39.     constant counter_max : unsigned(9 downto 0) := to_unsigned(867, 10);
  40.     -- Holds the current counter value that is used to tell when to
  41.     -- sample the rx pin data
  42.     signal rx_counter : unsigned(counter_max'range) := (others => '0');
  43.    
  44.     -- Current data bit that is being looked at
  45.     signal rx_bit_pos : unsigned(2 downto 0) := (others => '0');
  46.     -- Stores all 8 data bits
  47.     signal rx_data_buffer : std_logic_vector(7 downto 0) := (others => '0');
  48.    
  49.     -- Needed since the rx line is idle high ('1').  See the note at the
  50.     -- top of this file for details
  51.     signal rx_buffer_n : std_logic := '0';
  52. begin
  53.    
  54.     -- The only process.
  55.     process(clk, rst)
  56.     begin
  57.         -- Async reset.  Resets all signals touched by this process
  58.         if (rst = '1') then
  59.             rx_state <= IDLE;
  60.             rx_counter <= (others => '0');
  61.             leds <= (others => '0');
  62.             rx_bit_pos <= (others => '0');
  63.             rx_data_buffer <= (others => '0');
  64.         -- What to do on a rising clock edge
  65.         elsif (rising_edge(clk)) then
  66.             -- Store the inverse value of rx in rx_buffer_n.  This is
  67.             -- done to help aviod metastability problems.  Without bufferin
  68.             -- rx, you would get random errors in the data bits.  See notes
  69.             -- at the top for why rx is inverted.
  70.             rx_buffer_n <= not rx;
  71.            
  72.             -- Always increment the counter.  If the counter needs to be
  73.             -- reset, the reset will happen after this line and since
  74.             -- rx_counter is a signal, it will take the last value. Only
  75.             -- put here because it aviods having to put it in several
  76.             -- places.
  77.             rx_counter <= rx_counter + 1;
  78.            
  79.             -- State machine
  80.             case rx_state is
  81.                 -- IDLE's job is to sit and wait for the rx line to go low
  82.                 -- which is a '1' on rx_buffer_n.  Once rx_buffer_n is '1',
  83.                 -- the state changes to START_BIT and all of the required
  84.                 -- signals are reset.
  85.                 when IDLE =>
  86.                     -- Don't waste energy incrementing the counter
  87.                     -- This overwrites the above rx_counter < rx_counter + 1
  88.                     rx_counter <= rx_counter;
  89.                    
  90.                     -- Check to see if rx_buffer_n is '1' (data is coming)
  91.                     if (rx_buffer_n = '1') then
  92.                         -- Change to the START_BIT state
  93.                         rx_state <= START_BIT;
  94.                        
  95.                         -- Reset all of the required signals to a known state
  96.                         -- before moving on
  97.                         rx_data_buffer <= (others => '0');
  98.                         rx_bit_pos <= (others => '0');
  99.                         rx_counter <= (others => '0');
  100.                     end if;
  101.                 -- START_BIT just kills one bit (baud) time and then moves
  102.                 -- on to HANDLE_DATA
  103.                 when START_BIT =>
  104.                     -- Check to see if rx_counter has reached it's max value
  105.                     -- Remember that rx_counter is being incremented automatically
  106.                     -- at the top of the process.  The counter_max - 1 is done
  107.                     -- because we missed one clock cycle from the START_BIT state
  108.                     if(rx_counter = counter_max - 1) then
  109.                         rx_counter <= (others => '0');
  110.                         rx_state <= HANDLE_DATA;
  111.                     end if;
  112.                 -- HANDLE_DATA is the state where the data bits are sampled and
  113.                 -- stored.  Bits are sampled at the halfway point instead of the
  114.                 -- edge.  This is done to give the best chance of getting the bit
  115.                 when HANDLE_DATA =>
  116.                     -- Check to see if the counter is at the half way point
  117.                     if (rx_counter = counter_max / 2) then
  118.                         -- Grab the current bit and assign it to the rx_data_buffer.
  119.                         -- Make sure to notice that the bit from rx_buffer_n is
  120.                         -- inverted before being assigned to rx_data_buffer!!  This
  121.                         -- gets the data bit back to what it was originally on the rx
  122.                         -- line.
  123.                         rx_data_buffer(to_integer(rx_bit_pos)) <= not rx_buffer_n;
  124.                     -- Check to see if the counter has maxed out.  This means that it's
  125.                     -- time to either increment rx_bit_pos, or change states
  126.                     elsif (rx_counter = counter_max) then
  127.                         -- Reset rx_counter (overrides the assignment at the top)
  128.                         rx_counter <= (others => '0');
  129.                        
  130.                         -- Check to see if the last bit read was number 7.
  131.                         -- If so, it's time to change state (all bits have been read)
  132.                         if(rx_bit_pos = 7) then
  133.                             -- Change to the STOP_BIT state
  134.                             rx_state <= STOP_BIT;
  135.                             -- Use the LEDs to show the byte that was just read
  136.                             leds <= rx_data_buffer;
  137.                            
  138.                         -- rx_bit_pos was not 7, so there are more bits to read
  139.                         else
  140.                             -- Increment rx_bit_pos and wait for the next bit
  141.                             rx_bit_pos <= rx_bit_pos + 1;
  142.                         end if;
  143.                     end if;
  144.                 -- STOP_BIT just kills one bit (baud) time.  The actual bit sent
  145.                 -- at this point is not important
  146.                 when STOP_BIT =>
  147.                     -- Check to see if the counter has maxed out.  This means that
  148.                     -- one bit (baud) time has elapsed
  149.                     if(rx_counter = counter_max) then
  150.                         -- Change state to IDLE
  151.                         rx_state <= IDLE;
  152.                         -- Reset the counter
  153.                         rx_counter <= (others => '0');
  154.                     end if;
  155.             end case;
  156.         end if;
  157.     end process;
  158.  
  159. end behave;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement