diff --git a/src/lib/can_components.vhd b/src/lib/can_components.vhd index bb4be44349cfacf291b3c32ff8b1bf5eff19f77d..1bd00404ab96b94e9625c7948a098fbc3abd072d 100644 --- a/src/lib/can_components.vhd +++ b/src/lib/can_components.vhd @@ -762,7 +762,8 @@ package can_components is 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) + signal sjw_dbt : out std_logic_vector(sjw_dbt_width - 1 downto 0); + signal start_edge : out std_logic ); end component; @@ -798,6 +799,7 @@ package can_components is 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 start_edge : in std_logic; signal segm_end : in std_logic; signal h_sync_valid : in std_logic; signal exit_segm_req : out std_logic @@ -816,6 +818,7 @@ package can_components is signal prescaler : in std_logic_vector(tq_width - 1 downto 0); signal tq_reset : in std_logic; signal bt_reset : in std_logic; + signal drv_ena : in std_logic; signal tq_edge : out std_logic; signal bt_counter : out std_logic_vector(bt_width - 1 downto 0) ); @@ -855,7 +858,8 @@ package can_components is signal is_tseg1 : out std_logic; signal is_tseg2 : out std_logic; signal sample_req : out std_logic; - signal sync_req : out std_logic + signal sync_req : out std_logic; + signal bt_FSM_out : out bit_time_type ); end component; diff --git a/src/prescaler/bit_time_cfg_capture.vhd b/src/prescaler/bit_time_cfg_capture.vhd index 26d71540c36bbc2f38e07fe2984a94bb4971b324..b37afae375301bee707ff862a4303b79e9d2bcb6 100644 --- a/src/prescaler/bit_time_cfg_capture.vhd +++ b/src/prescaler/bit_time_cfg_capture.vhd @@ -145,7 +145,10 @@ entity bit_time_cfg_capture is 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) + signal sjw_dbt : out std_logic_vector(sjw_dbt_width - 1 downto 0); + + -- Signal to load the expected segment length by Bit time counters + signal start_edge : out std_logic ); end entity; @@ -190,8 +193,8 @@ architecture rtl of bit_time_cfg_capture is --------------------------------------------------------------------------- signal drv_ena : std_logic; signal drv_ena_reg : std_logic; - signal drv_ena_edge : std_logic; - + signal drv_ena_reg_2 : std_logic; + -- Capture signal signal capture : std_logic; @@ -219,9 +222,11 @@ begin drv_ena_reg_proc : process(res_n, clk_sys) begin if (res_n = reset_polarity) then - drv_ena_reg <= '0'; + drv_ena_reg <= '0'; + drv_ena_reg_2 <= '0'; elsif (rising_edge(clk_sys)) then - drv_ena_reg <= drv_ena; + drv_ena_reg <= drv_ena; + drv_ena_reg_2 <= drv_ena_reg; end if; end process; @@ -229,6 +234,11 @@ begin capture <= '1' when (drv_ena = '1' and drv_ena_reg = '0') else '0'; + -- Start edge is generated one clock cycle after the capture so that + -- resynchronisation will capture correct values already! + start_edge <= '1' when (drv_ena_reg_2 = '0' and drv_ena_reg = '1') else + '0'; + --------------------------------------------------------------------------- -- Calculation of next values for capture registers --------------------------------------------------------------------------- diff --git a/src/prescaler/bit_time_counters.vhd b/src/prescaler/bit_time_counters.vhd index a6a1d53b1215b7477b515b12bf38e21e0bf792ac..192ed21a2adb2fd9f8b854e74046cd7a91d14376 100644 --- a/src/prescaler/bit_time_counters.vhd +++ b/src/prescaler/bit_time_counters.vhd @@ -104,6 +104,9 @@ entity bit_time_counters is -- Bit Time reset (synchronous) signal bt_reset : in std_logic; + -- Core is enabled + signal drv_ena : in std_logic; + ----------------------------------------------------------------------- -- Status signals ----------------------------------------------------------------------- @@ -135,8 +138,6 @@ architecture rtl of bit_time_counters is constant bt_zeroes : std_logic_vector(bt_width - 1 downto 0) := (OTHERS => '0'); - constant bt_ones : std_logic_vector(bt_width - 1 downto 0) := - (OTHERS => '1'); begin @@ -144,7 +145,7 @@ begin -- 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! --------------------------------------------------------------------------- - tq_counter_ce <= '1' when (prescaler > tq_run_th) else + tq_counter_ce <= '1' when (prescaler > tq_run_th and drv_ena = '1') else '0'; --------------------------------------------------------------------------- @@ -174,9 +175,10 @@ begin --------------------------------------------------------------------------- -- Time quanta edge --------------------------------------------------------------------------- - tq_edge_i <= '1' when (tq_counter_ce = '0' or tq_counter_q = tq_zeroes) else + tq_edge_i <= '1' when (tq_counter_ce = '0' or + unsigned(tq_counter_q) = unsigned(prescaler) - 1) + else '0'; - tq_edge <= tq_edge_i; --------------------------------------------------------------------------- -- Bit time counter @@ -189,20 +191,16 @@ begin if (res_n = reset_polarity) then bt_counter_q <= (OTHERS => '0'); elsif (rising_edge(clk_sys)) then - if (tq_edge_i = '1') then + if (tq_edge_i = '1' and drv_ena = '1') then bt_counter_q <= bt_counter_d; end if; end if; end process; - - --------------------------------------------------------------------------- - --------------------------------------------------------------------------- - -- Assertions + --------------------------------------------------------------------------- + -- Internal signals to output propagation --------------------------------------------------------------------------- - -- psl default clock is rising_edge(clk_sys); - -- - -- psl no_bt_overflow_asrt : assert never - -- (bt_counter_q = bt_ones and tq_edge = '1' and bt_reset = '0'); + bt_counter <= bt_counter_q; + tq_edge <= tq_edge_i; end architecture rtl; \ No newline at end of file diff --git a/src/prescaler/bit_time_fsm.vhd b/src/prescaler/bit_time_fsm.vhd index 4f178fb40e317597e7bb1603ef2826788ce16e89..d55595c0a61eba49fe9bc4df56c5e1238c8a3298 100644 --- a/src/prescaler/bit_time_fsm.vhd +++ b/src/prescaler/bit_time_fsm.vhd @@ -101,7 +101,10 @@ entity bit_time_fsm is signal sample_req : out std_logic; -- Sync signal request - signal sync_req : out std_logic + signal sync_req : out std_logic; + + -- Bit time FSM output + signal bt_FSM_out : out bit_time_type ); end entity; @@ -119,7 +122,7 @@ begin ---------------------------------------------------------------------------- -- Next state process (combinational) ---------------------------------------------------------------------------- - next_state_proc : process(current_state, h_sync_valid, segm_end) + next_state_proc : process(current_state, h_sync_valid, segm_end, drv_ena) begin next_state <= current_state; @@ -127,22 +130,29 @@ begin next_state <= reset; elsif (h_sync_valid = '1') then next_state <= tseg1; - elsif (segm_end = '1') then + else case current_state is when tseg1 => - next_state <= tseg2; + if (segm_end = '1') then + next_state <= tseg2; + end if; when tseg2 => - next_state <= tseg1; + if (segm_end = '1') then + next_state <= tseg1; + end if; when reset => next_state <= tseg1; end case; end if; end process; + -- State register to output propagation + bt_FSM_out <= current_state; + ---------------------------------------------------------------------------- -- Current state process (combinational) ---------------------------------------------------------------------------- - curr_state_proc : process(current_state, h_sync_valid, segm_end) + curr_state_proc : process(current_state, segm_end) begin -- Default values is_tseg1 <= '0'; @@ -152,7 +162,6 @@ begin case current_state is when reset => - when tseg1 => is_tseg1 <= '1'; if (segm_end = '1') then diff --git a/src/prescaler/prescaler.vhd b/src/prescaler/prescaler.vhd index f9c0f216106ef22049e545b621f5c761dc2a0516..3d1e493f4babd59551554bdcd9b8cf0bbe3cee59 100644 --- a/src/prescaler/prescaler.vhd +++ b/src/prescaler/prescaler.vhd @@ -42,7 +42,6 @@ -------------------------------------------------------------------------------- -- Purpose: -- Prescaler circuit. --- -- -------------------------------------------------------------------------------- -- Revision History: @@ -244,6 +243,14 @@ architecture rtl of prescaler is -- Sync trigger request (in beginning of SYNC segment) signal sync_req : std_logic; + constant nbt_ones : std_logic_vector(bt_width_nbt - 1 downto 0) := + (OTHERS => '1'); + constant dbt_ones : std_logic_vector(bt_width_nbt - 1 downto 0) := + (OTHERS => '1'); + + -- Signal that expected semgent length should be loaded after restart! + signal start_edge : std_logic; + begin drv_ena <= drv_bus(DRV_ENA_INDEX); @@ -278,7 +285,8 @@ begin tseg1_dbt => tseg1_dbt, tseg2_dbt => tseg2_dbt, brp_dbt => brp_dbt, - sjw_dbt => sjw_dbt + sjw_dbt => sjw_dbt, + start_edge => start_edge ); --------------------------------------------------------------------------- @@ -337,6 +345,7 @@ begin tseg_1 => tseg1_nbt, tseg_2 => tseg2_nbt, sjw => sjw_nbt, + start_edge => start_edge, bt_counter => bt_counter_nbt, segm_end => segment_end, h_sync_valid => h_sync_valid, @@ -359,6 +368,7 @@ begin prescaler => brp_nbt, tq_reset => segment_end, bt_reset => segment_end, + drv_ena => drv_ena, tq_edge => tq_edge_nbt, bt_counter => bt_counter_nbt ); @@ -385,6 +395,7 @@ begin tseg_1 => tseg1_dbt, tseg_2 => tseg2_dbt, sjw => sjw_dbt, + start_edge => start_edge, bt_counter => bt_counter_dbt, segm_end => segment_end, h_sync_valid => h_sync_valid, @@ -393,7 +404,7 @@ begin --------------------------------------------------------------------------- - -- Bit Time counter (Nominal Bit Time) + -- Bit Time counter (Data Bit Time) --------------------------------------------------------------------------- bit_time_counters_dbt_comp : bit_time_counters generic map( @@ -407,6 +418,7 @@ begin prescaler => brp_dbt, tq_reset => segment_end, bt_reset => segment_end, + drv_ena => drv_ena, tq_edge => tq_edge_dbt, bt_counter => bt_counter_dbt ); @@ -436,7 +448,7 @@ begin --------------------------------------------------------------------------- - -- End of Segment detector + -- Bit time FSM --------------------------------------------------------------------------- bit_time_fsm_comp : bit_time_fsm generic map( @@ -451,7 +463,8 @@ begin is_tseg1 => is_tseg1, is_tseg2 => is_tseg2, sample_req => sample_req, - sync_req => sync_req + sync_req => sync_req, + bt_FSM_out => bt_FSM_out ); --------------------------------------------------------------------------- @@ -479,5 +492,24 @@ begin -- Internal signals to output propagation --------------------------------------------------------------------------- hard_sync_edge_valid <= h_sync_valid; + + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + -- Assertions + --------------------------------------------------------------------------- + --------------------------------------------------------------------------- + -- psl default clock is rising_edge(clk_sys); + -- + -- psl no_nbt_bt_overflow_asrt : assert never + -- (bt_counter_dbt = nbt_ones and tq_edge_nbt = '1' and + -- segment_end = '0' and sp_control = NOMINAL_SAMPLE) + -- report "Nominal Bit time counter overflow!" severity error; + -- + -- psl no_dbt_bt_overflow_asrt : assert never + -- (bt_counter_dbt = dbt_ones and tq_edge_dbt = '1' and + -- segment_end = '0' and + -- (sp_control = DATA_SAMPLE or sp_control = SECONDARY_SAMPLE)) + -- report "Data Bit time counter overflow!" severity error; + -- end architecture; \ No newline at end of file diff --git a/src/prescaler/resynchronisation.vhd b/src/prescaler/resynchronisation.vhd index 39a02b6117ca53a5f8b30ccb52e6724bdab071b6..1208bddab9b8a4fb862cfbf21aae1365cc549975 100644 --- a/src/prescaler/resynchronisation.vhd +++ b/src/prescaler/resynchronisation.vhd @@ -220,6 +220,9 @@ entity resynchronisation is -- Synchronisation Jump Width signal sjw : in std_logic_vector(sjw_width - 1 downto 0); + -- Circuit operation has started -> load expected segment length reg. + signal start_edge : in std_logic; + ----------------------------------------------------------------------- -- Bit Time counter interface ----------------------------------------------------------------------- @@ -311,14 +314,13 @@ begin -- Re-synchronisation data-path --------------------------------------------------------------------------- --------------------------------------------------------------------------- - sel_tseg1 <= '1' when (h_sync_valid = '1') else + sel_tseg1 <= '1' when (h_sync_valid = '1' or start_edge = '1') else '1' when (segm_end = '1' and is_tseg2 = '1') else - '1' when (is_tseg1 = '1') else '0'; basic_segm_length <= - resize(unsigned(tseg_2), bs_width) when (sel_tseg1 = '1') else - resize(unsigned(tseg_1), bs_width); + resize(unsigned(tseg_1), bs_width) when (sel_tseg1 = '1') else + resize(unsigned(tseg_2), bs_width); segm_extension <= resize(unsigned(sjw), ext_width) when (phase_err_mt_sjw = '1') else @@ -339,10 +341,11 @@ begin -- 2. Value post-resynchronisation. --------------------------------------------------------------------------- exp_seg_length_d <= - resize(basic_segm_length, exp_width) when (segm_end = '1') else + resize(basic_segm_length, exp_width) when (segm_end = '1' or start_edge = '1') else resize(sync_segm_length, exp_width); - exp_seg_length_ce <= '1' when (segm_end = '1' or resync_edge_valid = '1') + exp_seg_length_ce <= '1' when (segm_end = '1' or resync_edge_valid = '1' or + start_edge = '1') else '0'; @@ -389,7 +392,7 @@ begin -- segment. --------------------------------------------------------------------------- exit_segm_regular <= '1' when (resize(unsigned(bt_counter), exp_width) >= - resize(unsigned(exp_seg_length_q), exp_width)) + resize(unsigned(exp_seg_length_q) - 1, exp_width)) else '0'; diff --git a/src/prescaler/segment_end_detector.vhd b/src/prescaler/segment_end_detector.vhd index 1fbadc3ae0c6e9230cefa6a539e39ebec82f7182..195a800fadeaaf217b434a39eda5b2cb655d8568 100644 --- a/src/prescaler/segment_end_detector.vhd +++ b/src/prescaler/segment_end_detector.vhd @@ -102,7 +102,7 @@ entity segment_end_detector is -- Time Quanta edges (Nominal and Data) signal tq_edge_nbt : in std_logic; signal tq_edge_dbt : in std_logic; - + ----------------------------------------------------------------------- -- Outputs - Decision that current segment should end ----------------------------------------------------------------------- @@ -243,7 +243,7 @@ begin -- 2. Data Bit Time Resynchronisation signals end of segment, Data -- Time Quanta edge and Sample control is either DATA_SAMPLE or -- SECONDARY_SAMPLE! - -- 3. + -- 3. Hard synchronisation induced end of segment. --------------------------------------------------------------------------- segment_end_i <= '1' when (tseg1_end_req_valid = '1' or tseg2_end_req_valid = '1' or diff --git a/src/prescaler/trigger_generator.vhd b/src/prescaler/trigger_generator.vhd index 126a1afd271b3ab1c2416c84a9ef13ca896f9b58..f859dbf03c930d9b7e39e4e769fb2e0043a7eaa2 100644 --- a/src/prescaler/trigger_generator.vhd +++ b/src/prescaler/trigger_generator.vhd @@ -171,20 +171,40 @@ begin --------------------------------------------------------------------------- -- Sync trigger capture register --------------------------------------------------------------------------- - sync_req_flag_q <= '1' when (sample_sr_empty = '0' and sync_req = '1') else + sync_req_flag_d <= '1' when (sample_sr_empty = '0' and sync_req = '1') else '0' when (sample_sr_empty = '1') else - sync_req_flag_d; + sync_req_flag_q; + + sync_req_flag_proc : process(clk_sys, res_n) + begin + if (res_n = reset_polarity) then + sync_req_flag_q <= '0'; + elsif (rising_edge(clk_sys)) then + sync_req_flag_q <= sync_req_flag_d; + end if; + end process; + + sync_req_flag_dq <= sync_req or sync_req_flag_q; + - sync_req_flag_dq <= sync_req_flag_d or sync_req_flag_q; - --------------------------------------------------------------------------- -- Sample trigger capture register --------------------------------------------------------------------------- - sample_req_flag_q <= '1' when (sync_sr_empty = '0' and sample_req = '1') else + sample_req_flag_d <= '1' when (sync_sr_empty = '0' and sample_req = '1') else '0' when (sync_sr_empty = '1') else - sample_req_flag_d; + sample_req_flag_q; + + sample_req_flag_proc : process(clk_sys, res_n) + begin + if (res_n = reset_polarity) then + sample_req_flag_q <= '0'; + elsif (rising_edge(clk_sys)) then + sample_req_flag_q <= sample_req_flag_d; + end if; + end process; - sync_req_flag_dq <= sync_req_flag_d or sync_req_flag_q; + sample_req_flag_dq <= sample_req or sample_req_flag_q; + --------------------------------------------------------------------------- -- Decoding internal value of triggers. Allow for trigger to propagate @@ -236,10 +256,10 @@ begin sample_trig_sr_proc : process(clk_sys, res_n) begin if (res_n = reset_polarity) then - sample_sr(sample_sr'length - 3 downto 0) <= (OTHERS => '0'); + sample_sr(sample_sr'length - 2 downto 0) <= (OTHERS => '0'); elsif (rising_edge(clk_sys)) then - sample_sr(sample_sr'length - 3 downto 0) <= - sample_sr(sample_sr'length - 2 downto 1); + sample_sr(sample_sr'length - 2 downto 0) <= + sample_sr(sample_sr'length - 1 downto 1); end if; end process; end generate sample_trig_sr_gen; @@ -263,7 +283,7 @@ begin sample_trig_i when (sp_control = NOMINAL_SAMPLE) else '0'; - sample_dbt(sync_trigger_count - 1) <= + sample_dbt(sample_trigger_count - 1) <= sample_trig_i when (sp_control = DATA_SAMPLE or sp_control = SECONDARY_SAMPLE) else