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

Subversion Repositories manchesterwireless

[/] [manchesterwireless/] [trunk/] [decode/] [decode.vhd] - Rev 3

Compare with Previous | Blame | View Log

-----------------------------------------------------------------------------
--	Copyright (C) 2009 Sam Green
--
-- This code 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 code 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.
--
-- Decodes manchester encoded data
-- 
-----------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
use work.globals.all;
 
entity decode is
 
  port (
    clk_i     : in  std_logic;
    rst_i     : in  std_logic;
    nd_i      : in  std_logic;
    encoded_i : in  std_logic_vector(3 downto 0);
    decoded_o : out std_logic_vector(WORD_LENGTH-1 downto 0);
    nd_o      : out std_logic
  );
 
end;
 
architecture behavioral of decode is
 
  type state_type is (reset, pause, one_0, one_1, two_0, two_1);
  signal state, next_state : state_type;
 
  -- *2 comes from each bit in the word is manchester encoded.
  -- +2 comes from protocol transmitting -------_ to initiate
  -- a transmission; +1 from the ------- and +1 from the _
  constant STRING_LENGTH : integer := WORD_LENGTH*2+2;
  -- the range -1 comes from the state machine which will
  -- update index_n while the protocol finishes transmission
  signal index, index_n   : integer range -1 to STRING_LENGTH-1;
  signal str_buffer : std_logic_vector(STRING_LENGTH-3 downto 0);
  signal insert : std_logic_vector(1 downto 0);
  signal nd_o_buff : std_logic;
begin
 
  controller : process(nd_i, rst_i)
  begin
    if rst_i = '1' then
 
      index <= STRING_LENGTH-1;
      state <= reset;
      str_buffer <= (others => '0');
      nd_o_buff <= '0';
 
    elsif rising_edge(nd_i) then
      -- index is initalized at STRING_LENGTH-1
      -- the protocol initializes with two bits
      -- which are trashed, hence we wait until the first
      -- trashed bits have been passed
      -- 
      -- processing stops when the WORD_LENGTH bits have arrived (nd_o_buff = '1')
      if STRING_LENGTH - index >= 3 and nd_o_buff = '0' then
        -- Adding a single/double zero/one?
        if index - index_n = 2 then -- update 2
          str_buffer(index downto index-1) <= insert; -- insert double
        else -- update 1
          str_buffer(index) <= insert(1); -- insert single
        end if;
      end if;
 
      -- finished?
      if index = 0 then
        nd_o_buff <= '1';
        state <= reset;
      else
        index <= index_n;
        state <= next_state;
      end if;
    end if;
  end process;
 
  output_decode: process(state, index, nd_i)
  begin
    case state is  
 
      when one_1 =>
        insert <= "10";
        if (index > -1) then
          index_n <= index - 1;
        else
          index_n <= 0; -- error
        end if;
 
      when one_0 =>
        insert <= "00";
        if (index > -1) then
          index_n <= index - 1;
        else
          index_n <= 0; -- error
        end if;
 
      when two_1 =>
        insert <= "11";
 
        if (index > 0) then
          index_n <= index - 2;
        else
          index_n <= 0; -- error
        end if;        
 
      when two_0 =>
        insert <= "00";
 
        if (index > 0) then
          index_n <= index - 2; 
        else
          index_n <= 0; -- error
        end if;        
 
      when others =>
        insert <= "00";
        index_n <= index;
 
    end case;
  end process;
 
  -- For encoded_i:
  --
  -- 0000 = null
  -- 0001 = single one
  -- 0010 = double one
  -- 0100 = single zero
  -- 1000 = double zero  
 
  next_state_decode: process(state, encoded_i)
  begin
    next_state <= state;
    case(state) is
      when reset =>
 
        next_state <= pause;
 
      when pause =>
 
        next_state <= one_1; -- only if we came from reset. The long
        -- initialization string of ones --------- is considered a 
        -- single one.
 
      when one_0 =>
 
        case(encoded_i) is
          when "0100" => next_state <= one_0; -- remain here until change
          when "0001" => next_state <= one_1; -- because of the protocol, a 
          -- single 0 can only be followed by a single one.        
          when others => next_state <= reset; -- only on error
        end case;
 
      when one_1 =>
 
        case(encoded_i) is
          when "0001" => next_state <= one_1; -- remain here until change                                              
          when "0100" => next_state <= one_0;
          when "1000" => next_state <= two_0;
          when others => next_state <= reset; -- only on error
        end case;
 
      when two_0 =>
 
        case(encoded_i) is
          when "1000" => next_state <= two_0; -- remain here until change
          when "0001" => next_state <= one_1;
          when "0010" => next_state <= two_1;
          when others => next_state <= reset; -- only on error
        end case;
 
      when two_1 =>
 
        case(encoded_i) is
          when "0010" => next_state <= two_1; -- remain here until change
          when "0100" => next_state <= one_0;
          when "1000" => next_state <= two_0;
          when others => next_state <= reset; -- only on error
        end case;
 
      when others =>
        next_state <= reset;  -- only on error
 
    end case;
  end process;
 
  -- decoded!
  rearrange : process(clk_i, rst_i)
  begin
    if rst_i = '1' then
      decoded_o <= (others => '0');
      nd_o <= '0';
    elsif rising_edge(clk_i) then
      if nd_o_buff = '1' then
        for i in 0 to WORD_LENGTH-1 loop
          -- the bits are ror when transmitted, thus the left-most
          -- bit in decoded_buffer (excluding the xmitter protocol bits)
          -- describe the right-most bit in the original data word. 
          -- The following line of code turns 01 to 1 and 10 to 0 and it converts
          -- the big endian decoded_buffer to little endian decoded_o.        
          if str_buffer(str_buffer'left-2*i downto str_buffer'left-1-2*i) = "01" then
            decoded_o(i) <= '1';
          else
            decoded_o(i) <= '0';
          end if;
        end loop;
 
        nd_o <= '1';
      end if;
    end if;
  end process;
 
end;
 
 

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.