OpenCores
URL https://opencores.org/ocsvn/manchesteruart/manchesteruart/trunk

Subversion Repositories manchesteruart

[/] [manchesteruart/] [trunk/] [rtl/] [vhdl/] [encode.vhd] - Rev 2

Compare with Previous | Blame | View Log

--*************************************************************************
--*                                                                       *
--* Copyright (C) 2014 William B Hunter - LGPL                            *
--*                                                                       *
--* This source file may be used and distributed without                  *
--* restriction provided that this copyright statement is not             *
--* removed from the file and that any derivative work contains           *
--* the original copyright notice and the associated disclaimer.          *
--*                                                                       *
--* This source file is free software; you can redistribute it            *
--* and/or modify it under the terms of the GNU Lesser General            *
--* Public License as published by the Free Software Foundation;          *
--* either version 2.1 of the License, or (at your option) any            *
--* later version.                                                        *
--*                                                                       *
--* This source is distributed in the hope that it will be                *
--* useful, but WITHout ANY WARRANTY; without even the implied            *
--* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR               *
--* PURPOSE.  See the GNU Lesser General Public License for more          *
--* details.                                                              *
--*                                                                       *
--* You should have received a copy of the GNU Lesser General             *
--* Public License along with this source; if not, download it            *
--* from http://www.opencores.org/lgpl.shtml                              *
--*                                                                       *
--*************************************************************************
--
-- Engineer: William B Hunter
-- Create Date: 08/08/2014
-- Project: Manchester Uart
-- File: encode.vhd
-- Description: This encoder sends out short bursts of 16 bit data words encoded with as manchester data.
--   Because this is not a stream encoder, it has no sync pattern or packet alignment typical of manchester encoders.
--   It therefor uses start and stop bits much like a UART. Both the start and stop bits are always ones. The idle 
--   state is always high, and the ones are a low to high transition in the middle of the bit period, and a zero is a 
--   high to low transition in the middle of the bit period. A high for 3 bit periods is a reset/resync.
----------------------------------------------------------------------------------
 
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity encode is
  Port (
    clk16x : in STD_LOGIC;
    srst : in STD_LOGIC;
    tx_data : in STD_LOGIC_VECTOR (15 downto 0);
    tx_stb : in STD_LOGIC;
    txd : out STD_LOGIC;
    or_err : out STD_LOGIC;
    tx_idle : out STD_LOGIC
  );
end encode;
 
architecture rtl of encode is
  signal shifter : std_logic_vector(15 downto 0);
  signal tick_cnt : integer range 0 to 15 := 0;
  signal bit_cnt : integer range 0 to 15 := 0;
  signal txd_int : std_logic := '1';
  signal err_int : std_logic := '0';
 
  type txr_state_type is (SM_IDLE, SM_START, SM_SEND, SM_STOP);
  signal txr_state : txr_state_type := SM_IDLE;
 
begin
 
  p_transmitter: process(clk16x)
  begin
    if rising_edge(clk16x) then
      if srst = '1' then
         txr_state <= SM_IDLE;
         tick_cnt <= 0;
         bit_cnt <= 0;
      else
        case txr_state is
          --wait for a tx strobe to start a transmission
          when SM_IDLE =>
            tick_cnt <=  0;
            bit_cnt <=  0;
            if tx_stb = '1' then
              txr_state <= SM_START;
              shifter <= tx_data;
            end if;
          --the start is a one, which is 8 ticks low followed by 8 ticks high
          when SM_START =>
            if tick_cnt < 8 then
              txd_int <= '0';
              tick_cnt <= tick_cnt + 1;
            elsif  tick_cnt < 15 then
              txd_int <= '1';
              tick_cnt <= tick_cnt + 1;
            else
              txd_int <= '1';
              tick_cnt <= 0;
              bit_cnt <= 0;
              txr_state <= SM_SEND;
            end if;
          when SM_SEND =>
            --for each bit, a one is 8 ticks low followed by 8 ticks high, and a zero is 8 ticks high followed by 8 ticks low
            if tick_cnt < 8 then
              txd_int <= not shifter(15);
              tick_cnt <= tick_cnt + 1;
            elsif  tick_cnt < 15 then
              txd_int <= shifter(15);
              tick_cnt <= tick_cnt + 1;
            else
              txd_int <= shifter(15);
              tick_cnt <= 0;
              shifter <= shifter(14 downto 0) & '1';
              --at end of this bit check to see if we have more bits or if it's time for the stop bit
              if bit_cnt < 15 then
                bit_cnt <= bit_cnt + 1;
              else
                bit_cnt <=0;
                txr_state <= SM_STOP;
              end if;
            end if;    
          when SM_STOP =>
            --stop bits are always ones, which are 8 ticks low followed by 8 ticks high
            if tick_cnt < 8 then
              txd_int <= '0';
              tick_cnt <= tick_cnt + 1;
            elsif  tick_cnt < 15 then
              txd_int <= '1';
              tick_cnt <= tick_cnt + 1;
            else
              txd_int <= '1';
              tick_cnt <= 0;
              txr_state <= SM_IDLE;
            end if;
          --we should never get to the iothers state.
          when others =>
            tick_cnt <= 4;
            bit_cnt <= 0;
            txr_state <= SM_IDLE;
        end case;
      end if; --srst
    end if;  --clk16x
  end process;
 
 
  --An overrun error occurs when the transmit strobe is triggered and we are not finished with the previous state.
  -- The error is cleared when the transmitter goes back to idle
  p_or_err: process(clk16x)
  begin
    if rising_edge(clk16x) then
      if srst = '1' then
        err_int <='0';
      elsif tx_stb = '1' and txr_state /= SM_IDLE then
        err_int <= '1';
      elsif txr_state = SM_IDLE then
        err_int <= '0';
      end if;
    end if;
  end process;
 
  txd <= txd_int;
  or_err <= err_int;
  tx_idle <= '1' when txr_state = SM_IDLE else '0';
 
end rtl;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.