NVC code coverage report

File:  /__w/ctu-can-regression/ctu-can-regression/src/can_core/err_counters.vhd

     0:   -------------------------------------------------------------------------------- 
     1:   -- 
     2:   -- CTU CAN FD IP Core 
     3:   -- Copyright (C) 2021-2023 Ondrej Ille 
     4:   -- Copyright (C) 2023-     Logic Design Services Ltd.s 
     5:   -- 
     6:   -- Permission is hereby granted, free of charge, to any person obtaining a copy 
     7:   -- of this VHDL component and associated documentation files (the "Component"), 
     8:   -- to use, copy, modify, merge, publish, distribute the Component for 
     9:   -- non-commercial purposes. Using the Component for commercial purposes is 
    10:   -- forbidden unless previously agreed with Copyright holder. 
    11:   -- 
    12:   -- The above copyright notice and this permission notice shall be included in 
    13:   -- all copies or substantial portions of the Component. 
    14:   -- 
    15:   -- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    16:   -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    17:   -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    18:   -- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    19:   -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    20:   -- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS 
    21:   -- IN THE COMPONENT. 
    22:   -- 
    23:   -- The CAN protocol is developed by Robert Bosch GmbH and protected by patents. 
    24:   -- Anybody who wants to implement this IP core on silicon has to obtain a CAN 
    25:   -- protocol license from Bosch. 
    26:   -- 
    27:   -- ------------------------------------------------------------------------------- 
    28:   -- 
    29:   -- CTU CAN FD IP Core 
    30:   -- Copyright (C) 2015-2020 MIT License 
    31:   -- 
    32:   -- Authors: 
    33:   --     Ondrej Ille <ondrej.ille@gmail.com> 
    34:   --     Martin Jerabek <martin.jerabek01@gmail.com> 
    35:   -- 
    36:   -- Project advisors: 
    37:   -- 	Jiri Novak <jnovak@fel.cvut.cz> 
    38:   -- 	Pavel Pisa <pisa@cmp.felk.cvut.cz> 
    39:   -- 
    40:   -- Department of Measurement         (http://meas.fel.cvut.cz/) 
    41:   -- Faculty of Electrical Engineering (http://www.fel.cvut.cz) 
    42:   -- Czech Technical University        (http://www.cvut.cz/) 
    43:   -- 
    44:   -- Permission is hereby granted, free of charge, to any person obtaining a copy 
    45:   -- of this VHDL component and associated documentation files (the "Component"), 
    46:   -- to deal in the Component without restriction, including without limitation 
    47:   -- the rights to use, copy, modify, merge, publish, distribute, sublicense, 
    48:   -- and/or sell copies of the Component, and to permit persons to whom the 
    49:   -- Component is furnished to do so, subject to the following conditions: 
    50:   -- 
    51:   -- The above copyright notice and this permission notice shall be included in 
    52:   -- all copies or substantial portions of the Component. 
    53:   -- 
    54:   -- THE COMPONENT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    55:   -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    56:   -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    57:   -- AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    58:   -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    59:   -- FROM, OUT OF OR IN CONNECTION WITH THE COMPONENT OR THE USE OR OTHER DEALINGS 
    60:   -- IN THE COMPONENT. 
    61:   -- 
    62:   -- The CAN protocol is developed by Robert Bosch GmbH and protected by patents. 
    63:   -- Anybody who wants to implement this IP core on silicon has to obtain a CAN 
    64:   -- protocol license from Bosch. 
    65:   -- 
    66:   -------------------------------------------------------------------------------- 
    67:    
    68:   -------------------------------------------------------------------------------- 
    69:   -- Module: 
    70:   --  Error counters. 
    71:   -- 
    72:   -- Purpose: 
    73:   --  Error counters for fault confinement. Following counters are implemented: 
    74:   --    RX Error counter - Counts errors of reciver. 
    75:   --    TX Error counter - Counts errors of transmitter. 
    76:   --    Nominal Error counter - Counts errors in Nominal Bit rate. 
    77:   --    Data Error counter - Counts errors in Data Bit rate. 
    78:   --  Only RX Error counter and TX Error counter are used for Fault confinement. 
    79:   --  Nominal and Data Error counter are used to distuiguish relative error rate 
    80:   --  of both bit-rates and are always incremented by 1 when Error frame is 
    81:   --  transmitted. All counters can be modified from Driving Bus. 
    82:   -------------------------------------------------------------------------------- 
    83:    
    84:   Library ieee; 
    85:   use ieee.std_logic_1164.all; 
    86:   use ieee.numeric_std.ALL; 
    87:    
    88:   Library ctu_can_fd_rtl; 
    89:   use ctu_can_fd_rtl.can_constants_pkg.all; 
    90:   use ctu_can_fd_rtl.can_types_pkg.all; 
    91:    
    92:   use ctu_can_fd_rtl.CAN_FD_register_map.all; 
    93:   use ctu_can_fd_rtl.CAN_FD_frame_format.all; 
    94:    
    95:   entity err_counters is 
    96:       port ( 
    97:           ------------------------------------------------------------------------------------------- 
    98:           -- System clock and Asynchronous Reset 
    99:           ------------------------------------------------------------------------------------------- 
   100:           clk_sys                 : in  std_logic; 
   101:           res_n                   : in  std_logic; 
   102:    
   103:           ------------------------------------------------------------------------------------------- 
   104:           -- DFT support 
   105:           ------------------------------------------------------------------------------------------- 
   106:           scan_enable             : in  std_logic; 
   107:    
   108:           ------------------------------------------------------------------------------------------- 
   109:           -- Control inputs 
   110:           ------------------------------------------------------------------------------------------- 
   111:           -- Sample control (Nominal, Data, Secondary) 
   112:           sp_control              : in  std_logic_vector(1 downto 0); 
   113:    
   114:           -- Increment error counter by 1 
   115:           inc_one                 : in  std_logic; 
   116:    
   117:           -- Increment error counter by 8 
   118:           inc_eight               : in  std_logic; 
   119:    
   120:           -- Decrement error counter by 1 
   121:           dec_one                 : in  std_logic; 
   122:    
   123:           -- Set unit to error active (after re-integration). Erases error 
   124:           -- counters to 0! 
   125:           set_err_active          : in  std_logic; 
   126:    
   127:           -- Unit is transmitter 
   128:           is_transmitter          : in  std_logic; 
   129:    
   130:           -- Unit is receiver 
   131:           is_receiver             : in  std_logic; 
   132:    
   133:           ------------------------------------------------------------------------------------------- 
   134:           -- Memory registers interface 
   135:           ------------------------------------------------------------------------------------------- 
   136:           mr_ctr_pres_ctpv        : in  std_logic_vector(8 downto 0); 
   137:           mr_ctr_pres_ptx         : in  std_logic; 
   138:           mr_ctr_pres_prx         : in  std_logic; 
   139:           mr_ctr_pres_enorm       : in  std_logic; 
   140:           mr_ctr_pres_efd         : in  std_logic; 
   141:    
   142:           ------------------------------------------------------------------------------------------- 
   143:           -- Counter statuses 
   144:           ------------------------------------------------------------------------------------------- 
   145:           -- RX Error counter 
   146:           rx_err_ctr              : out std_logic_vector(8 downto 0); 
   147:    
   148:           -- TX Error counter 
   149:           tx_err_ctr              : out std_logic_vector(8 downto 0); 
   150:    
   151:           -- Nominal Bit Rate Error counter 
   152:           norm_err_ctr            : out std_logic_vector(15 downto 0); 
   153:    
   154:           -- Nominal Bit Rate Error counter 
   155:           data_err_ctr            : out std_logic_vector(15 downto 0) 
   156:       ); 
   157:   end entity; 
   158:    
   159:   architecture rtl of err_counters is 
   160:    
   161:       -- Error counter registers 
   162:       signal tx_err_ctr_d         : unsigned(8 downto 0); 
   163:       signal rx_err_ctr_d         : unsigned(8 downto 0); 
   164:       signal tx_err_ctr_q         : unsigned(8 downto 0); 
   165:       signal rx_err_ctr_q         : unsigned(8 downto 0); 
   166:    
   167:       signal rx_err_ctr_inc       : unsigned(8 downto 0); 
   168:       signal rx_err_ctr_sat       : unsigned(8 downto 0); 
   169:    
   170:       -- Clock enables for error counter registers 
   171:       signal tx_err_ctr_ce        : std_logic; 
   172:       signal rx_err_ctr_ce        : std_logic; 
   173:    
   174:       -- Modify TX/RX Error counter 
   175:       signal modif_tx_ctr         : std_logic; 
   176:       signal modif_rx_ctr         : std_logic; 
   177:    
   178:       -- TX/RX Error counter decremented value 
   179:       signal tx_err_ctr_dec       : unsigned(8 downto 0); 
   180:       signal rx_err_ctr_dec       : unsigned(8 downto 0); 
   181:    
   182:       -- Error counters for nominal bit errors, data bit errors 
   183:       signal nom_err_ctr_d        : unsigned(15 downto 0); 
   184:       signal data_err_ctr_d       : unsigned(15 downto 0); 
   185:       signal nom_err_ctr_q        : unsigned(15 downto 0); 
   186:       signal data_err_ctr_q       : unsigned(15 downto 0); 
   187:    
   188:       -- Selected value of counter 
   189:       signal nom_dat_sel_ctr      : unsigned(15 downto 0); 
   190:    
   191:       -- Combinationally added value 
   192:       signal nom_dat_sel_ctr_add  : unsigned(15 downto 0); 
   193:    
   194:       -- Clock enables for error counter registers 
   195:       signal nom_err_ctr_ce       : std_logic; 
   196:       signal data_err_ctr_ce      : std_logic; 
   197:    
   198:       signal res_err_ctrs_d       : std_logic; 
   199:       signal res_err_ctrs_q_scan  : std_logic; 
   200:    
   201:       signal mr_ctr_pres_ptx_q    : std_logic; 
   202:       signal mr_ctr_pres_prx_q    : std_logic; 
   203:       signal mr_ctr_pres_enorm_q  : std_logic; 
   204:       signal mr_ctr_pres_efd_q    : std_logic; 
   205:    
   206:   begin 
   207:    
   208:       ----------------------------------------------------------------------------------------------- 
   209:       -- Counter preset mask - must be registered, since value is also registered! This allows 
   210:       -- setting both by a single access! 
   211:       ----------------------------------------------------------------------------------------------- 
   212:       ctr_pres_reg_proc : process(res_n, clk_sys) 
   213:       begin 
   214:           if (res_n = '0') then 
   215:               mr_ctr_pres_ptx_q   <= '0'; 
   216:               mr_ctr_pres_prx_q   <= '0'; 
   217:               mr_ctr_pres_enorm_q <= '0'; 
   218:               mr_ctr_pres_efd_q   <= '0'; 
   219:           elsif (rising_edge(clk_sys)) then 
   220:               mr_ctr_pres_ptx_q   <= mr_ctr_pres_ptx; 
   221:               mr_ctr_pres_prx_q   <= mr_ctr_pres_prx; 
   222:               mr_ctr_pres_enorm_q <= mr_ctr_pres_enorm; 
   223:               mr_ctr_pres_efd_q   <= mr_ctr_pres_efd; 
   224:           end if; 
   225:       end process; 
   226:    
   227:       modif_tx_ctr <= '1' when (inc_eight = '1' or dec_one = '1') else 
   228:                       '0'; 
   229:    
   230:       -- Counters are modified either +1. +8 or -1 
   231:       modif_rx_ctr <= '1' when (inc_one = '1' or inc_eight = '1' or dec_one = '1') 
   232:                           else 
   233:                       '0'; 
   234:    
   235:       ----------------------------------------------------------------------------------------------- 
   236:       -- TX Error counter, next value calculation 
   237:       ----------------------------------------------------------------------------------------------- 
   238:       tx_err_ctr_dec <=  (tx_err_ctr_q - 1) when (tx_err_ctr_q > 0) else 
   239:                          tx_err_ctr_q; 
   240:    
   241:       -- Next value for error counter inctement when any of "inc" commands is 
   242:       -- valid. Decrement otherwise! 
   243:       tx_err_ctr_d <= 
   244:                 unsigned(mr_ctr_pres_ctpv) when (mr_ctr_pres_ptx_q = '1') else 
   245:                           tx_err_ctr_q + 8 when (inc_eight = '1') else 
   246:                             tx_err_ctr_dec; 
   247:    
   248:       -- Clock enable: Tick error counter register when unit is transmitter and 
   249:       -- one of commands is valid! 
   250:       tx_err_ctr_ce <= '1' when (modif_tx_ctr = '1' and is_transmitter = '1') else 
   251:                        '1' when (mr_ctr_pres_ptx_q = '1') else 
   252:                        '0'; 
   253:    
   254:       ----------------------------------------------------------------------------------------------- 
   255:       -- Registering counter reset (to avoid glitches) 
   256:       ----------------------------------------------------------------------------------------------- 
   257:       res_err_ctrs_d <= '0' when (res_n = '0' or set_err_active = '1') 
   258:                             else 
   259:                         '1'; 
   260:    
   261:       rst_reg_inst : entity ctu_can_fd_rtl.rst_reg 
   262:       generic map ( 
   263:           G_RESET_POLARITY    => '0' 
   264:       ) 
   265:       port map( 
   266:           -- Clock and Reset 
   267:           clk                 => clk_sys,                     -- IN 
   268:           arst                => res_n,                       -- IN 
   269:    
   270:           -- Flip flop input / output 
   271:           d                   => res_err_ctrs_d,              -- IN 
   272:           q                   => res_err_ctrs_q_scan,         -- OUT 
   273:    
   274:           -- Scan mode control 
   275:           scan_enable         => scan_enable                  -- IN 
   276:       ); 
   277:    
   278:       ----------------------------------------------------------------------------------------------- 
   279:       -- TX Error counter register 
   280:       ----------------------------------------------------------------------------------------------- 
   281:       tx_err_ctr_reg_proc : process(clk_sys, res_err_ctrs_q_scan) 
   282:       begin 
   283:           if (res_err_ctrs_q_scan = '0') then 
   284:               tx_err_ctr_q <= (others => '0'); 
   285:           elsif (rising_edge(clk_sys)) then 
   286:               if (tx_err_ctr_ce = '1') then 
   287:                   tx_err_ctr_q <= tx_err_ctr_d; 
   288:               end if; 
   289:           end if; 
   290:       end process; 
   291:    
   292:       ----------------------------------------------------------------------------------------------- 
   293:       -- RX Error counter, next value calculation 
   294:       ----------------------------------------------------------------------------------------------- 
   295:       -- Set to 120 when counter is more than 127, decrement otherwise! 
   296:       rx_err_ctr_dec <= to_unsigned(120, 9) when (rx_err_ctr_q > 127) else 
   297:                          (rx_err_ctr_q - 1) when (rx_err_ctr_q > 0) else 
   298:                               rx_err_ctr_q; 
   299:    
   300:    
   301:       -- Inrement RX counter 
   302:       rx_err_ctr_inc <= rx_err_ctr_q + 1 when (inc_one = '1') else 
   303:                         rx_err_ctr_q + 8; 
   304:    
   305:       -- Saturate RX counter when overflow would occur according to 12.1.4.3 of CAN FD ISO spec 
   306:       rx_err_ctr_sat <= (others => '1') when (rx_err_ctr_inc < rx_err_ctr_q) else 
   307:                         rx_err_ctr_inc; 
   308:    
   309:       ----------------------------------------------------------------------------------------------- 
   310:       -- Next value for error counter increment when any of "inc" commands is valid, decrement 
   311:       -- otherwise! 
   312:       ----------------------------------------------------------------------------------------------- 
   313:       rx_err_ctr_d <= unsigned(mr_ctr_pres_ctpv) when (mr_ctr_pres_prx_q = '1') else 
   314:                                   rx_err_ctr_sat when (inc_one = '1' or inc_eight = '1') else 
   315:                                   rx_err_ctr_dec; 
   316:    
   317:       -- Clock enable: Tick error counter register when unit is transmitter and one of commands is 
   318:       -- valid! 
   319:       rx_err_ctr_ce <= '1' when (modif_rx_ctr = '1' and is_receiver = '1') else 
   320:                        '1' when (mr_ctr_pres_prx_q = '1') else 
   321:                        '0'; 
   322:    
   323:       ----------------------------------------------------------------------------------------------- 
   324:       -- RX error counter register 
   325:       ----------------------------------------------------------------------------------------------- 
   326:       rx_err_ctr_reg_proc : process(clk_sys, res_err_ctrs_q_scan) 
   327:       begin 
   328:           if (res_err_ctrs_q_scan = '0') then 
   329:               rx_err_ctr_q <= (others => '0'); 
   330:           elsif (rising_edge(clk_sys)) then 
   331:               if (rx_err_ctr_ce = '1') then 
   332:                   rx_err_ctr_q <= rx_err_ctr_d; 
   333:               end if; 
   334:           end if; 
   335:       end process; 
   336:    
   337:    
   338:       ----------------------------------------------------------------------------------------------- 
   339:       ----------------------------------------------------------------------------------------------- 
   340:       -- Error counters for Errors in Nominal, Data Bit rate 
   341:       ----------------------------------------------------------------------------------------------- 
   342:       ----------------------------------------------------------------------------------------------- 
   343:    
   344:       -- Selection of counter to be incremented 
   345:       nom_dat_sel_ctr <= nom_err_ctr_q when (sp_control = NOMINAL_SAMPLE) else 
   346:                          data_err_ctr_q; 
   347:    
   348:       nom_dat_sel_ctr_add <= nom_dat_sel_ctr + 1; 
   349:    
   350:       nom_err_ctr_d <= nom_dat_sel_ctr_add when (mr_ctr_pres_enorm_q = '0') 
   351:                                            else 
   352:                            (others => '0'); 
   353:    
   354:       data_err_ctr_d <= nom_dat_sel_ctr_add when (mr_ctr_pres_efd_q = '0') 
   355:                                             else 
   356:                            (others => '0'); 
   357:    
   358:       -- Clock enables for counters, increment only 
   359:       nom_err_ctr_ce <= '1' when (mr_ctr_pres_enorm_q = '1') or 
   360:                                  ((inc_one = '1' or inc_eight = '1') and 
   361:                                   (sp_control = NOMINAL_SAMPLE)) 
   362:                             else 
   363:                         '0'; 
   364:    
   365:       data_err_ctr_ce <= '1' when (mr_ctr_pres_efd_q = '1') or 
   366:                                   ((inc_one = '1' or inc_eight = '1') and 
   367:                                    (sp_control = DATA_SAMPLE or sp_control = SECONDARY_SAMPLE)) 
   368:                              else 
   369:                          '0'; 
   370:    
   371:       ----------------------------------------------------------------------------------------------- 
   372:       -- Nominal / Data Bit rate error counters registers 
   373:       ----------------------------------------------------------------------------------------------- 
   374:       nom_err_ctr_proc : process(clk_sys, res_err_ctrs_q_scan) 
   375:       begin 
   376:           if (res_err_ctrs_q_scan = '0') then 
   377:               nom_err_ctr_q <= (others => '0'); 
   378:           elsif (rising_edge(clk_sys)) then 
   379:               if (nom_err_ctr_ce = '1') then 
   380:                   nom_err_ctr_q <= nom_err_ctr_d; 
   381:               end if; 
   382:           end if; 
   383:       end process; 
   384:    
   385:       dat_err_ctr_proc : process(clk_sys, res_err_ctrs_q_scan) 
   386:       begin 
   387:           if (res_err_ctrs_q_scan = '0') then 
   388:               data_err_ctr_q <= (others => '0'); 
   389:           elsif (rising_edge(clk_sys)) then 
   390:               if (data_err_ctr_ce = '1') then 
   391:                   data_err_ctr_q <= data_err_ctr_d; 
   392:               end if; 
   393:           end if; 
   394:       end process; 
   395:    
   396:       ----------------------------------------------------------------------------------------------- 
   397:       -- Internal signals to output propagation 
   398:       ----------------------------------------------------------------------------------------------- 
   399:       rx_err_ctr <= std_logic_vector(rx_err_ctr_q); 
   400:       tx_err_ctr <= std_logic_vector(tx_err_ctr_q); 
   401:    
   402:       norm_err_ctr <= std_logic_vector(nom_err_ctr_q); 
   403:       data_err_ctr <= std_logic_vector(data_err_ctr_q); 
   404:    
   405:      ----------------------------------------------------------------------------------------------- 
   406:      -- Assertions 
   407:      ----------------------------------------------------------------------------------------------- 
   408:    
   409:      -- psl default clock is rising_edge(clk_sys); 
   410:      -- 
   411:      -- psl no_simul_inc_dec_asrt : assert never 
   412:      --  (inc_one = '1' and inc_eight = '1') or 
   413:      --  (inc_one = '1' and dec_one = '1') or 
   414:      --  (dec_one = '1' and inc_eight = '1') 
   415:      -- report "Can't manipulate Error counters by multiple commands at once"; 
   416:    
   417:      -- psl no_simul_transm_rec_asrt : assert never 
   418:      --   (is_transmitter = '1' and is_receiver = '1') 
   419:      -- report "Unit can't be transmitter and receiver at once"; 
   420:    
   421:   end architecture;