bit_time_counters.vhd 7.71 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
--------------------------------------------------------------------------------
-- 
-- CTU CAN FD IP Core
-- Copyright (C) 2015-2018
-- 
-- Authors:
--     Ondrej Ille <ondrej.ille@gmail.com>
--     Martin Jerabek <martin.jerabek01@gmail.com>
-- 
-- Project advisors: 
-- 	Jiri Novak <jnovak@fel.cvut.cz>
-- 	Pavel Pisa <pisa@cmp.felk.cvut.cz>
-- 
-- Department of Measurement         (http://meas.fel.cvut.cz/)
-- Faculty of Electrical Engineering (http://www.fel.cvut.cz)
-- Czech Technical University        (http://www.cvut.cz/)
-- 
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this VHDL component and associated documentation files (the "Component"),
-- to deal in the Component without restriction, including without limitation
-- the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Component, and to permit persons to whom the
-- Component 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 Component.
-- 
-- THE COMPONENT 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 COMPONENT OR THE USE OR OTHER DEALINGS
-- IN THE COMPONENT.
-- 
-- 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:
44 45 46
--  Contains two counters:
--      1. Time Quanta counter.
--      2. Bit time counter.
47
--
48 49 50 51 52 53
--  Time Quanta counter counts duration of Time quanta segment and provides
--- Time Quanta edge signal.
--  Bit Time counter counts with granularity of Time Quanta and provides value
--  of Bit Time counter to the output.
--
--------------------------------------------------------------------------------
54
-- Revision History:
55
--    15.02.2019   Created file
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
--------------------------------------------------------------------------------

Library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
use ieee.math_real.ALL;

Library work;
use work.id_transfer.all;
use work.can_constants.all;
use work.can_components.all;
use work.can_types.all;
use work.cmn_lib.all;
use work.drv_stat_pkg.all;
use work.endian_swap.all;
use work.reduce_lib.all;

use work.CAN_FD_register_map.all;
use work.CAN_FD_frame_format.all;

76
entity bit_time_counters is
77 78
    generic (
        -- Reset polarity
79 80 81 82 83 84 85
        reset_polarity  : std_logic := '0';
        
        -- Bit Time counter width
        bt_width        : natural := 8;
        
        -- Time Qunata counter width
        tq_width        : natural := 8
86 87 88 89 90 91 92 93 94
    );
    port(
        -----------------------------------------------------------------------
        -- Clock and reset
        -----------------------------------------------------------------------
        signal clk_sys          : in    std_logic;
        signal res_n            : in    std_logic;

        -----------------------------------------------------------------------
95 96 97 98 99 100 101 102 103 104 105 106
        -- Control signals
        -----------------------------------------------------------------------
        
        -- Prescaler value
        signal prescaler        : in    std_logic_vector(tq_width - 1 downto 0);
        
        -- Time Quanta reset (synchronous)
        signal tq_reset         : in    std_logic;
        
        -- Bit Time reset (synchronous)
        signal bt_reset         : in    std_logic;
        
107 108 109
        -- Core is enabled
        signal drv_ena          : in    std_logic;
        
110 111
        -----------------------------------------------------------------------
        -- Status signals
112
        -----------------------------------------------------------------------
113 114 115 116 117
        -- Time Quanta edge
        signal tq_edge          : out   std_logic;
        
        -- Bit Time counter
        signal bt_counter       : out   std_logic_vector(bt_width - 1 downto 0)
118 119 120
    );
end entity;

121 122 123 124 125 126
architecture rtl of bit_time_counters is
    
    -- Time Quanta Counter
    signal tq_counter_d         : std_logic_vector(tq_width - 1 downto 0);
    signal tq_counter_q         : std_logic_vector(tq_width - 1 downto 0);
    signal tq_counter_ce        : std_logic;
127

128
    signal tq_edge_i            : std_logic;
129

130 131 132 133
    constant tq_zeroes : std_logic_vector(tq_width - 1 downto 0) :=
        (OTHERS => '0');
    constant tq_run_th : std_logic_vector(tq_width - 1 downto 0) :=
        (0 => '1', OTHERS => '0');
134
    
135 136 137
    -- Bit Time counter
    signal bt_counter_d         : std_logic_vector(bt_width - 1 downto 0);
    signal bt_counter_q         : std_logic_vector(bt_width - 1 downto 0);
138
    
139
    constant bt_zeroes : std_logic_vector(bt_width - 1 downto 0) :=
140
        (OTHERS => '0');
141 142

begin    
143 144

    ---------------------------------------------------------------------------
145 146
    -- If prescaler is defined as 0 or 1, there is no need to run the counter!
    -- Run it only when Prescaler is higher than 1! 
147
    ---------------------------------------------------------------------------
148
    tq_counter_ce <= '1' when (prescaler > tq_run_th and drv_ena = '1') else
149
                     '0';
150 151

    ---------------------------------------------------------------------------
152 153 154 155
    -- Time quanta counter next value:
    --  1. Erase when reaching value of prescaler.
    --  2. Erase when re-started.
    --  3. Add 1 ohterwise!
156
    ---------------------------------------------------------------------------
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
    tq_counter_d <=
        (OTHERS => '0') when (unsigned(tq_counter_q) = unsigned(prescaler) - 1)
                        else
        (OTHERS => '0') when (tq_reset = '1')
                        else
        std_logic_vector(unsigned(tq_counter_q) + 1);

    tq_proc : process(clk_sys, res_n)
    begin
        if (res_n = reset_polarity) then
            tq_counter_q <= (OTHERS => '0');
        elsif (rising_edge(clk_sys)) then
            if (tq_counter_ce = '1') then
                tq_counter_q <= tq_counter_d;
            end if;
        end if;
    end process;
174 175
    
    ---------------------------------------------------------------------------
176
    -- Time quanta edge
177
    ---------------------------------------------------------------------------
178 179 180
    tq_edge_i <= '1' when (tq_counter_ce = '0' or 
                           unsigned(tq_counter_q) = unsigned(prescaler) - 1)
                     else
181 182 183 184 185 186 187 188 189
                 '0';

    ---------------------------------------------------------------------------
    -- Bit time counter
    ---------------------------------------------------------------------------
    bt_counter_d <= bt_zeroes when (bt_reset = '1') else
                    std_logic_vector(unsigned(bt_counter_q) + 1);

    bt_counter_proc : process(clk_sys, res_n)
190 191
    begin
        if (res_n = reset_polarity) then
192
            bt_counter_q <= (OTHERS => '0');
193
        elsif (rising_edge(clk_sys)) then
194
            if (tq_edge_i = '1' and drv_ena = '1') then
195
                bt_counter_q <= bt_counter_d;
196 197 198
            end if;
        end if;
    end process;
199
    
200
    ---------------------------------------------------------------------------
201
    -- Internal signals to output propagation
202
    ---------------------------------------------------------------------------
203 204
    bt_counter <= bt_counter_q;
    tq_edge <= tq_edge_i;
205 206

end architecture rtl;