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

Subversion Repositories manchesterwireless

[/] [manchesterwireless/] [branches/] [singledouble/] [singleDouble/] [singleDouble.vhd] - Rev 10

Go to most recent revision | Compare with Previous | Blame | View Log

-----------------------------------------------------------------------------
--	Copyright (C) 2009 José Rodríguez-Navarro
--
-- 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.
--
--  Identify single/double ones/zeros based on length 
--  of time data_i is high/low
--
--  Revision  Date        Author                Comment
--  --------  ----------  --------------------  ----------------
--  1.0       20/02/09    J. Rodriguez-Navarro  Initial revision
--  1.1       21/06/09    M. Thiagarajan        Modified with FSM
--  1.2       25/06/09    M. Thiagarajan        Modified Nxt State Logic
--                                              to avoid inferring latch
--  Future revisions tracked in Subversion at OpenCores.org
--  under the manchesterwireless project
-----------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.globals.all;
 
--------------------------------------------------------------------------------
 
entity singleDouble is
  port (
    clk_i   :  in  std_logic;
    ce_i    :  in  std_logic;    
    rst_i   :  in  std_logic;
    data_i  :  in  std_logic;
    q_o     :  out std_logic_vector(3 downto 0);
    ready_o :  out std_logic
  );
end;
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
 
architecture behavioral of singleDouble is
 
  signal single_one:      std_logic;
  signal double_one:      std_logic;
  signal single_zero:     std_logic;
  signal double_zero:     std_logic;
  signal count_ones    : integer range 0 to INTERVAL_MAX_DOUBLE;
  signal count_zeros   : integer range 0 to INTERVAL_MAX_DOUBLE;
 
  signal data_i_d  :         std_logic;
  signal data_i_d2 :         std_logic;
 
  signal    ct_state, nxt_state  : bit_vector(2 downto 0);
  signal    ce_i_RT, data_i_RT, data_i_FT : std_logic;
  signal    ce_i_d, ce_i_d2               : std_logic;
  signal    count_zeros_en, count_ones_en : std_logic;
  constant  IDLE: bit_vector(2 downto 0) := "001";
  constant  CNT0: bit_vector(2 downto 0) := "010";
  constant  CNT1: bit_vector(2 downto 0) := "100";
 
  begin
    process (clk_i,rst_i)
    begin
      if (rst_i = '1') then
        ce_i_d  <= '0';
        ce_i_d2 <= '0';
      elsif (clk_i'event and clk_i = '1') then
        ce_i_d    <= ce_i;
        ce_i_d2  <= ce_i_d;
      end if;
    end process;
    ce_i_RT   <= ce_i_d and (not(ce_i_d2));  --CE rising edge
 
    process (clk_i,rst_i)
    begin
      if (rst_i = '1') then
        data_i_d  <= '0';
        data_i_d2 <= '0';
      elsif (clk_i'event and clk_i = '1') then
        data_i_d  <= data_i;
        data_i_d2  <= data_i_d;
      end if;
    end process;
    data_i_RT   <= data_i_d and (not(data_i_d2));  --Data rising edge
    data_i_FT   <= (not data_i_d) and data_i_d2;  --Data falling edge
 
    ready_o     <= ((data_i_RT or data_i_FT) and ce_i) or ce_i_RT;
 
    process (clk_i,rst_i)  --State register
    begin
      if (rst_i = '1') then
        ct_state <= IDLE;
      elsif (clk_i'event and clk_i = '1') then
        ct_state <= nxt_state;
      end if;
    end process;
 
    process (ct_state,ce_i_RT,data_i,ce_i,data_i_FT,data_i_RT)  --Next State logic
    begin
      case ct_state is
          when IDLE   =>
            if ((ce_i_RT = '1') and (data_i = '0'))then
              nxt_State <= CNT0;
            elsif ((ce_i_RT = '1') and (data_i = '1')) then
              nxt_state <= CNT1;
            else
              nxt_state <= IDLE;
            end if;
 
          when CNT0   =>
            if (ce_i = '0') then
              nxt_state <= IDLE;
            elsif (data_i_RT = '1') then
              nxt_state <= CNT1;
            else
              nxt_state <= CNT0;
            end if;
 
          when CNT1   =>
            if (ce_i = '0') then
              nxt_state <= IDLE;
            elsif (data_i_FT = '1') then
              nxt_state <= CNT0;
            else
              nxt_state <= CNT1;
            end if;
 
          when others   =>
            nxt_state <=  IDLE;
      end case;
    end process;
 
    process (ct_state)  --State output logic
    begin
      case ct_state is
        when IDLE   =>
          count_ones_en    <= '0';
          count_zeros_en   <= '0';
 
        when CNT0   =>
          count_ones_en    <= '0';
          count_zeros_en   <= '1';
 
        when CNT1   =>
          count_ones_en    <= '1';
          count_zeros_en   <= '0';
        --when others    => null;
        when others    => 
          count_ones_en    <= '0';
          count_zeros_en   <= '0';
    end case;
  end process;
 
  process (clk_i,rst_i)  --counters
  begin
    if (rst_i = '1') then
      count_ones    <=  0;
      count_zeros   <=  0;
    elsif (clk_i'event and clk_i = '1') then
      if (count_zeros_en = '1') then
        count_zeros   <= count_zeros + 1;
        count_ones    <= 0;
      elsif (count_ones_en = '1') then
        count_ones   <= count_ones + 1;
        count_zeros    <= 0;
      end if;
    end if;
  end process;
 
  process(count_ones)
  begin
    if (count_ones >= INTERVAL_MIN_DOUBLE) and (count_ones <= INTERVAL_MAX_DOUBLE) then
      double_one <= '1';
    else
      double_one <= '0';
    end if;
    if (count_ones >= INTERVAL_MIN_SINGLE) and (count_ones <= INTERVAL_MAX_SINGLE) then
      single_one <= '1';
    else
      single_one <= '0';
    end if;
  end process;
 
  process(count_zeros)
  begin
    if (count_zeros >= INTERVAL_MIN_DOUBLE) and (count_zeros <= INTERVAL_MAX_DOUBLE) then
      double_zero <= '1';
    else
      double_zero <= '0';
    end if;
    if (count_zeros >= INTERVAL_MIN_SINGLE) and (count_zeros <= INTERVAL_MAX_SINGLE) then
      single_zero <= '1';
    else
      single_zero <= '0';
    end if;
  end process;
 
  process (rst_i,data_i_RT,data_i_FT)
  begin
    if (rst_i = '1') then
      q_o   <= "0000";
    else
      q_o   <= double_zero & single_zero & double_one & single_one;
    end if;
  end process;
end;
 

Go to most recent revision | 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.