Commit 8a4722fd authored by Ille, Ondrej, Ing.'s avatar Ille, Ondrej, Ing.

src: Prescaler new implementation.

parent acc97185
......@@ -436,6 +436,12 @@ architecture rtl of CAN_top_level is
signal sync_nbt_del_1 : std_logic;
signal sync_dbt_del_1 : std_logic;
-- Trigger outputs from Prescaler
signal sample_nbt_i : std_logic_vector(2 downto 0);
signal sample_dbt_i : std_logic_vector(2 downto 0);
signal sync_nbt_i : std_logic_vector(1 downto 0);
signal sync_dbt_i : std_logic_vector(1 downto 0);
signal sp_control : std_logic_vector(1 downto 0);
signal sync_control : std_logic_vector(1 downto 0);
......@@ -777,6 +783,28 @@ begin
);
prescaler_comp : prescaler
generic map(
reset_polarity => '0',
capt_btr => false,
capt_tseg_1 => true,
capt_tseg_2 => false,
capt_sjw => false,
-- Width of Bit time segments
tseg1_nbt_width => 8,
tseg2_nbt_width => 6,
tq_nbt_width => 8,
sjw_nbt_width => 5,
tseg1_dbt_width => 7,
tseg2_dbt_width => 5,
tq_dbt_width => 8,
sjw_dbt_width => 5,
ipt_length => 4,
sync_trigger_count => 2,
sample_trigger_count => 3
)
port map(
clk_sys => clk_sys,
res_n => res_n_int,
......@@ -785,22 +813,30 @@ begin
drv_bus => drv_bus,
clk_tq_nbt => clk_tq_nbt,
clk_tq_dbt => clk_tq_dbt,
sample_nbt => sample_nbt,
sample_dbt => sample_dbt,
sample_nbt => sample_nbt_i,
sample_dbt => sample_dbt_i,
bt_FSM_out => bt_FSM_out,
sample_nbt_del_1 => sample_nbt_del_1,
sample_dbt_del_1 => sample_dbt_del_1,
sample_nbt_del_2 => sample_nbt_del_2,
sample_dbt_del_2 => sample_dbt_del_2,
sync_nbt => sync_nbt,
sync_dbt => sync_dbt,
sync_nbt_del_1 => sync_nbt_del_1,
sync_dbt_del_1 => sync_dbt_del_1,
sync_nbt => sync_nbt_i,
sync_dbt => sync_dbt_i,
data_tx => data_tx,
hard_sync_edge_valid => hard_sync_edge_valid,
sp_control => sp_control,
sync_control => sync_control
);
-- Temporary internal connections. Will be replaced during protocol
-- control re-work!
sample_nbt <= sample_nbt_i(2);
sample_dbt <= sample_dbt_i(2);
sample_nbt_del_1 <= sample_nbt_i(1);
sample_dbt_del_1 <= sample_dbt_i(1);
sample_nbt_del_2 <= sample_dbt_i(0);
sample_dbt_del_2 <= sample_dbt_i(0);
sync_nbt_del_1 <= sync_nbt_i(0);
sync_dbt_del_1 <= sync_dbt_i(0);
sync_nbt <= sync_nbt_i(1);
sync_dbt <= sync_dbt_i(1);
bus_sampling_comp : bus_sampling
generic map (
......
......@@ -509,10 +509,8 @@ begin
if (i = 17) then
case bt_FSM is
when sync => bit_type_vect <= "0001";
when prop => bit_type_vect <= "0010";
when ph1 => bit_type_vect <= "0100";
when ph2 => bit_type_vect <= "1000";
when tseg1 => bit_type_vect <= "0001";
when tseg2 => bit_type_vect <= "1000";
when others => bit_type_vect <= "0000";
end case;
end if;
......
......@@ -697,6 +697,24 @@ package can_components is
-- Prescaler module
----------------------------------------------------------------------------
component prescaler is
generic(
reset_polarity : std_logic := '0';
capt_btr : boolean := false;
capt_tseg_1 : boolean := true;
capt_tseg_2 : boolean := false;
capt_sjw : boolean := false;
tseg1_nbt_width : natural := 8;
tseg2_nbt_width : natural := 6;
tq_nbt_width : natural := 8;
sjw_nbt_width : natural := 5;
tseg1_dbt_width : natural := 7;
tseg2_dbt_width : natural := 5;
tq_dbt_width : natural := 8;
sjw_dbt_width : natural := 5;
ipt_length : natural := 4;
sync_trigger_count : natural range 2 to 8 := 2;
sample_trigger_count : natural range 2 to 8 := 3
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
......@@ -705,16 +723,10 @@ package can_components is
signal drv_bus : in std_logic_vector(1023 downto 0);
signal clk_tq_nbt : out std_logic;
signal clk_tq_dbt : out std_logic;
signal sample_nbt : out std_logic;
signal sample_dbt : out std_logic;
signal sample_nbt_del_1 : out std_logic;
signal sample_dbt_del_1 : out std_logic;
signal sample_nbt_del_2 : out std_logic;
signal sample_dbt_del_2 : out std_logic;
signal sync_nbt : out std_logic;
signal sync_dbt : out std_logic;
signal sync_nbt_del_1 : out std_logic;
signal sync_dbt_del_1 : out std_logic;
signal sample_nbt : out std_logic_vector(sample_trigger_count - 1 downto 0);
signal sample_dbt : out std_logic_vector(sample_trigger_count - 1 downto 0);
signal sync_nbt : out std_logic_vector(sync_trigger_count - 1 downto 0);
signal sync_dbt : out std_logic_vector(sync_trigger_count - 1 downto 0);
signal bt_FSM_out : out bit_time_type;
signal data_tx : in std_logic;
signal hard_sync_edge_valid : out std_logic;
......@@ -723,6 +735,166 @@ package can_components is
);
end component;
component bit_time_cfg_capture is
generic (
reset_polarity : std_logic := '0';
capt_btr : boolean := false;
capt_tseg_1 : boolean := true;
capt_tseg_2 : boolean := false;
capt_sjw : boolean := false;
tseg1_nbt_width : natural := 8;
tseg2_nbt_width : natural := 8;
tq_nbt_width : natural := 8;
sjw_nbt_width : natural := 5;
tseg1_dbt_width : natural := 8;
tseg2_dbt_width : natural := 8;
tq_dbt_width : natural := 8;
sjw_dbt_width : natural := 5
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal drv_bus : in std_logic_vector(1023 downto 0);
signal tseg1_nbt : out std_logic_vector(tseg1_nbt_width - 1 downto 0);
signal tseg2_nbt : out std_logic_vector(tseg2_nbt_width - 1 downto 0);
signal brp_nbt : out std_logic_vector(tq_nbt_width - 1 downto 0);
signal sjw_nbt : out std_logic_vector(sjw_nbt_width - 1 downto 0);
signal tseg1_dbt : out std_logic_vector(tseg1_dbt_width - 1 downto 0);
signal tseg2_dbt : out std_logic_vector(tseg2_dbt_width - 1 downto 0);
signal brp_dbt : out std_logic_vector(tq_dbt_width - 1 downto 0);
signal sjw_dbt : out std_logic_vector(sjw_dbt_width - 1 downto 0)
);
end component;
component ipt_checker is
generic (
reset_polarity : std_logic := '0';
ipt_length : natural := 4
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal ipt_req : in std_logic;
signal ipt_gnt : out std_logic
);
end component;
component resynchronisation is
generic (
reset_polarity : std_logic := '0';
sjw_width : natural := 4;
tseg1_width : natural := 8;
tseg2_width : natural := 8;
bt_width : natural := 8
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal resync_edge_valid : in std_logic;
signal ipt_ok : in std_logic;
signal is_tseg1 : in std_logic;
signal is_tseg2 : in std_logic;
signal tseg_1 : in std_logic_vector(tseg1_width - 1 downto 0);
signal tseg_2 : in std_logic_vector(tseg2_width - 1 downto 0);
signal sjw : in std_logic_vector(sjw_width - 1 downto 0);
signal bt_counter : in std_logic_vector(bt_width - 1 downto 0);
signal segm_end : in std_logic;
signal h_sync_valid : in std_logic;
signal exit_segm_req : out std_logic
);
end component;
component bit_time_counters is
generic (
reset_polarity : std_logic := '0';
bt_width : natural := 8;
tq_width : natural := 8
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal prescaler : in std_logic_vector(tq_width - 1 downto 0);
signal tq_reset : in std_logic;
signal bt_reset : in std_logic;
signal tq_edge : out std_logic;
signal bt_counter : out std_logic_vector(bt_width - 1 downto 0)
);
end component;
component segment_end_detector is
generic (
reset_polarity : std_logic := '0'
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal sp_control : in std_logic_vector(1 downto 0);
signal h_sync_edge_valid : in std_logic;
signal exit_segm_req_nbt : in std_logic;
signal exit_segm_req_dbt : in std_logic;
signal ipt_ok : in std_logic;
signal is_tseg1 : in std_logic;
signal is_tseg2 : in std_logic;
signal tq_edge_nbt : in std_logic;
signal tq_edge_dbt : in std_logic;
signal segm_end : out std_logic;
signal h_sync_valid : out std_logic
);
end component;
component bit_time_fsm is
generic (
reset_polarity : std_logic := '0'
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal segm_end : in std_logic;
signal h_sync_valid : in std_logic;
signal drv_ena : in std_logic;
signal is_tseg1 : out std_logic;
signal is_tseg2 : out std_logic;
signal sample_req : out std_logic;
signal sync_req : out std_logic
);
end component;
component synchronisation_checker is
generic (
reset_polarity : std_logic := '0'
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal sync_control : in std_logic_vector(1 downto 0);
signal sync_edge : in std_logic;
signal no_pos_resync : in std_logic;
signal segment_end : out std_logic;
signal is_tseg1 : in std_logic;
signal is_tseg2 : in std_logic;
signal resync_edge_valid : out std_logic;
signal h_sync_edge_valid : out std_logic
);
end component;
component trigger_generator is
generic (
reset_polarity : std_logic := '0';
sync_trigger_count : natural range 2 to 8 := 2;
sample_trigger_count : natural range 2 to 8 := 3
);
port(
signal clk_sys : in std_logic;
signal res_n : in std_logic;
signal sample_req : in std_logic;
signal sync_req : in std_logic;
signal sp_control : in std_logic_vector(1 downto 0);
signal sample_nbt : out std_logic_vector(sample_trigger_count - 1 downto 0);
signal sample_dbt : out std_logic_vector(sample_trigger_count - 1 downto 0);
signal sync_nbt : out std_logic_vector(sync_trigger_count - 1 downto 0);
signal sync_dbt : out std_logic_vector(sync_trigger_count - 1 downto 0)
);
end component;
----------------------------------------------------------------------------
-- Bus Sampling module
......
......@@ -123,11 +123,8 @@ package can_types is
);
type bit_time_type is (
sync,
prop,
ph1,
ph2,
h_sync,
tseg1,
tseg2,
reset
);
......
--------------------------------------------------------------------------------
--
-- 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:
-- Bit Time config capture
--
-- Captures Bit Timing configuration from BTR and BTR_FD registers when
-- Core is enabled (drv_ena:0->1).
-- This has two advantages:
-- 1. Register value is shadowed, thus chaning BTR or BTR FD when it is
-- not desired will avoid possible mal-function. Extra cost of few
-- DFFs is not that high.
-- 2. This circuit re-calculates PROP+PH1 to TSEG1. The advantage is that
-- adder will not be in combinational path of bit timing calculation
-- and will thus not screw maximal frequency.
-- Each capture register is optinally configurable by generic. E.g. it might
-- not have sense to insert capture register on SJW (since there is no
-- combinational logic).
--------------------------------------------------------------------------------
-- Revision History:
-- 03.02.2019 Created file
--------------------------------------------------------------------------------
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;
entity bit_time_cfg_capture is
generic (
-- Reset polarity
reset_polarity : std_logic := '0';
-- Insert Capture register for BTR, BTR_FD
capt_btr : boolean := false;
-- Insert Capture register for TSEG1
capt_tseg_1 : boolean := true;
-- Insert Capture register for TSEG2
capt_tseg_2 : boolean := false;
-- Insert Capture register for SJW
capt_sjw : boolean := false;
-- Nominal bit time widths
tseg1_nbt_width : natural := 8;
tseg2_nbt_width : natural := 8;
tq_nbt_width : natural := 8;
sjw_nbt_width : natural := 5;
-- Data bit time widths
tseg1_dbt_width : natural := 8;
tseg2_dbt_width : natural := 8;
tq_dbt_width : natural := 8;
sjw_dbt_width : natural := 5
);
port(
-----------------------------------------------------------------------
-- Clock and reset
-----------------------------------------------------------------------
signal clk_sys : in std_logic;
signal res_n : in std_logic;
-----------------------------------------------------------------------
-- Memory Registers interface and control signal
-----------------------------------------------------------------------
signal drv_bus : in std_logic_vector(1023 downto 0);
-----------------------------------------------------------------------
-- Output values
-----------------------------------------------------------------------
-- Time segment 1 - Nominal Bit Time
signal tseg1_nbt : out std_logic_vector(tseg1_nbt_width - 1 downto 0);
-- Time segment 2 - Nominal Bit Time
signal tseg2_nbt : out std_logic_vector(tseg2_nbt_width - 1 downto 0);
-- Baud Rate Prescaler - Nominal Bit Time
signal brp_nbt : out std_logic_vector(tq_nbt_width - 1 downto 0);
-- Synchronisation Jump Width - Nominal Bit Time
signal sjw_nbt : out std_logic_vector(sjw_nbt_width - 1 downto 0);
-- Time segment 1 - Data Bit Time
signal tseg1_dbt : out std_logic_vector(tseg1_dbt_width - 1 downto 0);
-- Time segment 2 - Data Bit Time
signal tseg2_dbt : out std_logic_vector(tseg2_dbt_width - 1 downto 0);
-- Baud Rate Prescaler - Data Bit Time
signal brp_dbt : out std_logic_vector(tq_dbt_width - 1 downto 0);
-- Synchronisation Jump Width - Data Bit Time
signal sjw_dbt : out std_logic_vector(sjw_dbt_width - 1 downto 0)
);
end entity;
architecture rtl of bit_time_cfg_capture is
---------------------------------------------------------------------------
-- Driving Bus aliases
---------------------------------------------------------------------------
-- Nominal
signal drv_tq_nbt : std_logic_vector(7 downto 0);
signal drv_prs_nbt : std_logic_vector(6 downto 0);
signal drv_ph1_nbt : std_logic_vector(5 downto 0);
signal drv_ph2_nbt : std_logic_vector(5 downto 0);
signal drv_sjw_nbt : std_logic_vector(4 downto 0);
-- Data
signal drv_tq_dbt : std_logic_vector(7 downto 0);
signal drv_prs_dbt : std_logic_vector(5 downto 0);
signal drv_ph1_dbt : std_logic_vector(4 downto 0);
signal drv_ph2_dbt : std_logic_vector(4 downto 0);
signal drv_sjw_dbt : std_logic_vector(4 downto 0);
---------------------------------------------------------------------------
-- Next values for configuration.
---------------------------------------------------------------------------
signal tseg1_nbt_nxt : std_logic_vector(tseg1_nbt_width - 1 downto 0);
signal tseg1_dbt_nxt : std_logic_vector(tseg1_dbt_width - 1 downto 0);
signal tseg2_nbt_nxt : std_logic_vector(tseg2_nbt_width - 1 downto 0);
signal tseg2_dbt_nxt : std_logic_vector(tseg2_dbt_width - 1 downto 0);
signal brp_nbt_nxt : std_logic_vector(tq_nbt_width - 1 downto 0);
signal brp_dbt_nxt : std_logic_vector(tq_dbt_width - 1 downto 0);
signal sjw_nbt_nxt : std_logic_vector(sjw_nbt_width - 1 downto 0);
signal sjw_dbt_nxt : std_logic_vector(sjw_dbt_width - 1 downto 0);
constant sync_length : unsigned(7 downto 0) := x"01";
---------------------------------------------------------------------------
-- Drv ena edge detection
---------------------------------------------------------------------------
signal drv_ena : std_logic;
signal drv_ena_reg : std_logic;
signal drv_ena_edge : std_logic;
-- Capture signal
signal capture : std_logic;
begin
---------------------------------------------------------------------------
-- Connect to Driving Bus
---------------------------------------------------------------------------
drv_tq_nbt <= drv_bus(DRV_TQ_NBT_HIGH downto DRV_TQ_NBT_LOW);
drv_tq_dbt <= drv_bus(DRV_TQ_DBT_HIGH downto DRV_TQ_DBT_LOW);
drv_prs_nbt <= drv_bus(DRV_PRS_NBT_HIGH downto DRV_PRS_NBT_LOW);
drv_ph1_nbt <= drv_bus(DRV_PH1_NBT_HIGH downto DRV_PH1_NBT_LOW);
drv_ph2_nbt <= drv_bus(DRV_PH2_NBT_HIGH downto DRV_PH2_NBT_LOW);
drv_prs_dbt <= drv_bus(DRV_PRS_DBT_HIGH downto DRV_PRS_DBT_LOW);
drv_ph1_dbt <= drv_bus(DRV_PH1_DBT_HIGH downto DRV_PH1_DBT_LOW);
drv_ph2_dbt <= drv_bus(DRV_PH2_DBT_HIGH downto DRV_PH2_DBT_LOW);
drv_sjw_nbt <= drv_bus(DRV_SJW_HIGH downto DRV_SJW_LOW);
drv_sjw_dbt <= drv_bus(DRV_SJW_DBT_HIGH downto DRV_SJW_DBT_LOW);
drv_ena <= drv_bus(DRV_ENA_INDEX);
---------------------------------------------------------------------------
-- DRV_ENA edge detection
---------------------------------------------------------------------------
drv_ena_reg_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
drv_ena_reg <= '0';
elsif (rising_edge(clk_sys)) then
drv_ena_reg <= drv_ena;
end if;
end process;
-- Capture the configuration upon enabbling of the core.
capture <= '1' when (drv_ena = '1' and drv_ena_reg = '0') else
'0';
---------------------------------------------------------------------------
-- Calculation of next values for capture registers
---------------------------------------------------------------------------
tseg1_nbt_nxt <= std_logic_vector(
resize(unsigned(drv_prs_nbt), tseg1_nbt_width) +
resize(unsigned(drv_ph1_nbt), tseg1_nbt_width) +
resize(sync_length, tseg1_nbt_width));
tseg1_dbt_nxt <= std_logic_vector(
resize(unsigned(drv_prs_dbt), tseg1_dbt_width) +
resize(unsigned(drv_ph1_dbt), tseg1_dbt_width) +
resize(sync_length, tseg1_dbt_width));
tseg2_nbt_nxt <=
std_logic_vector(resize(unsigned(drv_ph2_nbt), tseg2_nbt_width));
tseg2_dbt_nxt <=
std_logic_vector(resize(unsigned(drv_ph2_dbt), tseg2_dbt_width));
brp_nbt_nxt <=
std_logic_vector(resize(unsigned(drv_tq_nbt), tq_nbt_width));
brp_dbt_nxt <=
std_logic_vector(resize(unsigned(drv_tq_dbt), tq_dbt_width));
sjw_nbt_nxt <=
std_logic_vector(resize(unsigned(drv_sjw_nbt), sjw_nbt_width));
sjw_dbt_nxt <=
std_logic_vector(resize(unsigned(drv_sjw_dbt), sjw_nbt_width));
---------------------------------------------------------------------------
-- Capture registers for BRP, BRP_FD
---------------------------------------------------------------------------
brp_capt_true_gen : if (capt_btr) generate
brp_capt_proc : process(res_n, clk_sys)
begin
if (res_n = reset_polarity) then
brp_nbt <= (OTHERS => '0');
brp_dbt <= (OTHERS => '0');
elsif (rising_edge(clk_sys)) then
if (capture = '1') then
brp_nbt <= brp_nbt_nxt;
brp_dbt <= brp_dbt_nxt;
end if;
end if;
end process;
end generate brp_capt_true_gen;
brp_capt_false_gen : if (not capt_btr) generate
brp_nbt <= brp_nbt_nxt;
brp_dbt <= brp_dbt_nxt;
end generate brp_capt_false_gen;