brs_comp.vhd 5.88 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
--------------------------------------------------------------------------------
--
-- CAN with Flexible Data-Rate IP Core 
--
-- Copyright (C) 2015 Ondrej Ille <ondrej.ille@gmail.com>
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy 
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is 
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in 
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
-- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
-- IN THE SOFTWARE.
--
-- The CAN protocol is developed by Robert Bosch GmbH and protected by patents. 
-- Anybody who wants to implement this IP core on silicon has to obtain a CAN 
-- protocol license from Bosch.
--
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
-- Purpose:
--  Processing of the CAN RX data in sample point involves mutli-stage pipeline
--  after sampling itself.
--  First stage - bit destuffing. Second stage - Processing by Protocol control
--  and update of state signals. This involves "sp_control" which drives the
--  time quanta counter.
--  Due to this architecture it takes 3 clock cycles after sample point (of a
--  bit where bit-rate was switched) till time quantum starts to be "counted"
--  with proper value. During these clock cycles ph2 phase is counted with old
--  value and thus it reaches incorrect value.
--  To correct this, compensation of "ph2_real" is performed. It considers 
--  relations of Nominal/Data time quanta durations, switching from slower to 
--  faster bit-rate or vice versa, and duration of 3 cycles of "incorrect"
--  counting.
--
--  Note that other parts of the architecture are not affected since update of
--  all state variables happends during Information Processing Time. Time quanta
--  duration is the only state information which needs to be updated directly
--  after sample point!
--
--  Another approach is to provide extra signal from protocol control which
--  would be set at the beginning of the "switching bit" and prescaler would
--  use hard-coded value of time quanta during ph1 and ph2 bit times.
--------------------------------------------------------------------------------
56 57 58 59
-- Revision History:
--    July 2015   Created file
--
--------------------------------------------------------------------------------
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

Library ieee;
USE IEEE.std_logic_1164.all;
USE IEEE.numeric_std.ALL;
USE ieee.std_logic_unsigned.All;
USE WORK.CANconstants.ALL;

package brs_comp_package is
  procedure brs_comp(
        signal tq_nbt : in natural range 0 to 63;
        signal tq_dbt : in natural range 0 to 63;
        signal sp_control : in std_logic_vector(1 downto 0);
        signal ph2_nbt : in natural range 0 to 63;
        signal ph2_dbt : in natural range 0 to 15;
        signal ph2_real : out integer range -63 to 63
  );
end brs_comp_package;

package body brs_comp_package is
  
  ---------------------------------
  -- Bit rate switch compensation
  ---------------------------------
  --Sample type has changed we have to modify "ph2_real" accordingly...
  -- This corresponds to moment of bit rate switching. Since the processing
  -- of switching takes 3 clock cycles (bit destuffing, protocol control,
  -- sp_control update, actual update of the ph2_real), compensation
  -- of the ph2_real is needed based on Time quanta(TQ) duration
  procedure brs_comp(
        signal tq_nbt : in natural range 0 to 63;
        signal tq_dbt : in natural range 0 to 63;
        signal sp_control : in std_logic_vector(1 downto 0);
        signal ph2_nbt : in natural range 0 to 63;
        signal ph2_dbt : in natural range 0 to 15;
        signal ph2_real : out integer range -63 to 63
  )is
  variable ntd : boolean; --Nominal to Data switch
  begin
    
    if ((sp_control = SECONDARY_SAMPLE) or (sp_control=DATA_SAMPLE)) then
       ntd := true;
    elsif (sp_control = NOMINAL_SAMPLE) then
       ntd := false;
    else
       ntd := false;
       report "Unknown sampling type" severity error;
    end if;
    
    if(ntd=true)then
      if (tq_nbt=1 and tq_dbt>3) then
        ph2_real <= ph2_dbt+3; 
      elsif ((tq_nbt=2 or tq_nbt=3) and (tq_dbt>3)) then
        ph2_real <= ph2_dbt+1;
      elsif (tq_nbt=1 and (tq_dbt=2 or tq_dbt=3)) then
        ph2_real <= ph2_dbt+2;
      elsif ((tq_nbt=2 or tq_nbt=3) and (tq_dbt=1)) then
        ph2_real <= ph2_dbt-2;
      elsif ((tq_dbt=2 or tq_dbt=3) and (tq_nbt>3)) then
        ph2_real <= ph2_dbt-1;
      elsif (tq_nbt>3 and tq_dbt=1) then
        ph2_real <= ph2_dbt-3; 
      else 
        ph2_real <= ph2_dbt;
      end if;
    else
      if (tq_nbt>3 and tq_dbt=1)then
        ph2_real <= ph2_nbt+3;
      elsif (tq_nbt>3 and (tq_dbt=2 or tq_dbt=3)) then
        ph2_real <= ph2_nbt+1;
      elsif (tq_dbt=1 and (tq_nbt=2 or tq_nbt=3)) then
        ph2_real <= ph2_nbt+1;
      elsif (tq_dbt>3 and (tq_nbt=2 or tq_nbt=3)) then
        ph2_real <= ph2_nbt-1;
      elsif (tq_nbt=1 and (tq_dbt=2 or tq_dbt=3)) then
        ph2_real <= ph2_nbt-2;
      elsif (tq_nbt=1 and tq_dbt>3) then
        ph2_real <= ph2_nbt-3;
      else
        ph2_real <= ph2_nbt;
      end if;
    end if;
  end procedure;

end package body;