NVC code coverage report

File:  /__w/ctu-can-regression/ctu-can-regression/src/can_core/bit_stuffing.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:   --  Bit Stuffing. 
    71:   -- 
    72:   -- Purpose: 
    73:   --  Inserts Stuff Bits into TX serial stream. Operates in Stuff pipeline stage 
    74:   --  with Bit Stuffing Trigger. Signals insertion of Stuff Bit after n bits of 
    75:   --  equal value were processed. Supports regular and fixed bit stuffing. 
    76:   --  Inserts extra stuff bit upon transition from regular to fixed bit stuffing. 
    77:   --  Length of Stuff rule and bit stuffing method are controlled by Protocol 
    78:   --  control FSM. When disabled, data are only propagated from input to output 
    79:   --  with Bit Stuffing Trigger without insertion of Stuff bits. Processing of 
    80:   --  Input data always takes one clock cycle. Counts number of Inserted Stuff 
    81:   --  Bits modulo 8. 
    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 bit_stuffing is 
    96:       port ( 
    97:           ------------------------------------------------------------------------------------------- 
    98:           -- Clock and Asynchronous reset 
    99:           ------------------------------------------------------------------------------------------- 
   100:           clk_sys             : in  std_logic; 
   101:           res_n               : in  std_logic; 
   102:    
   103:           ------------------------------------------------------------------------------------------- 
   104:           -- Data-path 
   105:           ------------------------------------------------------------------------------------------- 
   106:           -- Data Input (from Protocol Control) 
   107:           data_in             : in  std_logic; 
   108:    
   109:           -- Data Output (to CAN Bus) 
   110:           data_out            : out std_logic; 
   111:    
   112:           ------------------------------------------------------------------------------------------- 
   113:           -- Control signals 
   114:           ------------------------------------------------------------------------------------------- 
   115:           -- Bit Stuffing Trigger (in SYNC segment) 
   116:           bst_trigger         : in  std_logic; 
   117:    
   118:           -- Bit Stuffing enabled. If not, data are only passed to the output 
   119:           stuff_enable        : in  std_logic; 
   120:    
   121:           -- Bit Stuffing type (0-Normal, 1-Fixed) 
   122:           fixed_stuff         : in  std_logic; 
   123:    
   124:           -- Frame transmission without SOF started 
   125:           tx_frame_no_sof     : in  std_logic; 
   126:    
   127:           ------------------------------------------------------------------------------------------- 
   128:           -- Status signals 
   129:           ------------------------------------------------------------------------------------------- 
   130:           -- Number of stuffed bits with Normal Bit stuffing 
   131:           bst_ctr             : out std_logic_vector(2 downto 0); 
   132:    
   133:           -- Stuff bit is inserted, Protocol control operation to be halted for one bit time 
   134:           data_halt           : out std_logic 
   135:       ); 
   136:   end entity; 
   137:    
   138:   architecture rtl of bit_stuffing is 
   139:    
   140:       signal data_out_i           : std_logic; 
   141:    
   142:       ----------------------------------------------------------------------------------------------- 
   143:       -- Counter with number of equal consequent bits 
   144:       ----------------------------------------------------------------------------------------------- 
   145:       signal same_bits_q          : unsigned(2 downto 0); 
   146:       signal same_bits_add        : unsigned(2 downto 0); 
   147:       signal same_bits_d          : unsigned(2 downto 0); 
   148:       signal tx_no_sof_val        : unsigned(1 downto 0); 
   149:    
   150:       -- Halt for CAN Core 
   151:       signal data_halt_q          : std_logic; 
   152:       signal data_halt_d          : std_logic; 
   153:    
   154:       ----------------------------------------------------------------------------------------------- 
   155:       -- Registered value of fixed stuffing. 
   156:       ----------------------------------------------------------------------------------------------- 
   157:       signal fixed_reg_q          : std_logic; 
   158:       signal fixed_reg_d          : std_logic; 
   159:    
   160:       ----------------------------------------------------------------------------------------------- 
   161:       -- Counter with regularly stuffed bits 
   162:       ----------------------------------------------------------------------------------------------- 
   163:       signal bst_ctr_q            : unsigned(2 downto 0); 
   164:       signal bst_ctr_add          : unsigned(2 downto 0); 
   165:       signal bst_ctr_d            : unsigned(2 downto 0); 
   166:    
   167:       ----------------------------------------------------------------------------------------------- 
   168:       -- Registered value of enable input 
   169:       ----------------------------------------------------------------------------------------------- 
   170:       signal enable_prev          : std_logic; 
   171:    
   172:    
   173:       ----------------------------------------------------------------------------------------------- 
   174:       -- Combinational signals 
   175:       ----------------------------------------------------------------------------------------------- 
   176:    
   177:       -- Bit stuffing method has changed from non-fixed to fixed bit stuffing. No need to assume 
   178:       -- change from fixed to non-fixed since after coding CRC of CAN FD, there are no further 
   179:       -- stuff bits with non-fixed bit stuffing! 
   180:       signal non_fix_to_fix_chng  : std_logic; 
   181:    
   182:       -- Signals that stuff count has reached number of same consecutive bits and that stuff bit 
   183:       -- should be inserted! 
   184:       signal stuff_lvl_reached    : std_logic; 
   185:    
   186:       -- Counter of equal consecutive bits should be re-set to 1 in next processed bit. 
   187:       signal same_bits_rst_trig   : std_logic; 
   188:    
   189:       -- Counter of equal consecutive bits should be re-set to 1 in next clock cycle. 
   190:       signal same_bits_rst        : std_logic; 
   191:    
   192:       -- Condition for insertion of stuff bit 
   193:       signal insert_stuff_bit     : std_logic; 
   194:    
   195:       -- Calculation of next data output value when circuit is enabled 
   196:       signal data_out_d_ena       : std_logic; 
   197:    
   198:       -- Next data output value (both when enabled and disabled) 
   199:       signal data_out_d           : std_logic; 
   200:    
   201:       -- Clock enable for output data register 
   202:       signal data_out_ce          : std_logic; 
   203:    
   204:   begin 
   205:    
   206:       ----------------------------------------------------------------------------------------------- 
   207:       -- Registering previous value of enable input to detect 0->1 transition. 
   208:       ----------------------------------------------------------------------------------------------- 
   209:       dff_ena_reg : entity ctu_can_fd_rtl.dff_arst 
   210:       generic map ( 
   211:           G_RESET_POLARITY   => '0', 
   212:           G_RST_VAL          => '0' 
   213:       ) 
   214:       port map ( 
   215:           arst               => res_n,            -- IN 
   216:           clk                => clk_sys,          -- IN 
   217:           reg_d              => stuff_enable,     -- IN 
   218:    
   219:           reg_q              => enable_prev       -- OUT 
   220:       ); 
   221:    
   222:       ----------------------------------------------------------------------------------------------- 
   223:       -- Detection of change on fixed stuff settings upon mismatch between actual and registered 
   224:       -- value of fixed stuff settings from previous bit. 
   225:       ----------------------------------------------------------------------------------------------- 
   226:       non_fix_to_fix_chng <= '1' when (fixed_stuff = '1' and fixed_reg_q = '0') 
   227:                                  else 
   228:                              '0'; 
   229:    
   230:       ----------------------------------------------------------------------------------------------- 
   231:       -- Calculation of next value in fixed stuff register: 
   232:       --  1. Re-started upon 0->1 transition on "enable" 
   233:       --  2. Store "fixed_stuff" configuration when data are processed 
   234:       ----------------------------------------------------------------------------------------------- 
   235:       fixed_reg_d <= '0'         when (enable_prev = '0') else 
   236:                      fixed_stuff when (bst_trigger = '1') else 
   237:                      fixed_reg_q; 
   238:    
   239:       ----------------------------------------------------------------------------------------------- 
   240:       -- Registering previous value of fixed bit stuffing to detect first fixed stuff bit and insert 
   241:       -- stuff bit in the beginning of CRC for CAN FD automatically! 
   242:       ----------------------------------------------------------------------------------------------- 
   243:       dff_fixed_stuff_reg : entity ctu_can_fd_rtl.dff_arst_ce 
   244:       generic map ( 
   245:           G_RESET_POLARITY   => '0', 
   246:           G_RST_VAL          => '0' 
   247:       ) 
   248:       port map ( 
   249:           arst               => res_n,            -- IN 
   250:           clk                => clk_sys,          -- IN 
   251:           reg_d              => fixed_reg_d,      -- IN 
   252:           ce                 => stuff_enable,     -- IN 
   253:    
   254:           reg_q              => fixed_reg_q       -- OUT 
   255:       ); 
   256:    
   257:       ----------------------------------------------------------------------------------------------- 
   258:       -- Combinationally incremented stuff counter by 1. 
   259:       ----------------------------------------------------------------------------------------------- 
   260:       bst_ctr_add <= (bst_ctr_q + 1) mod 8; 
   261:    
   262:       ----------------------------------------------------------------------------------------------- 
   263:       -- Calculation of next combinational value for counter of stuffed bits: 
   264:       --  1. Erase when restarted bit stuffing. 
   265:       --  2. Upon insertion of non-fixed stuff bit increment. 
   266:       --  3. Keep previous value otherwise. 
   267:       ----------------------------------------------------------------------------------------------- 
   268:       bst_ctr_d <=        "000" when (enable_prev = '0') else 
   269:                     bst_ctr_add when (bst_trigger = '1' and stuff_lvl_reached = '1' and 
   270:                                       fixed_stuff = '0') else 
   271:                       bst_ctr_q; 
   272:    
   273:       ----------------------------------------------------------------------------------------------- 
   274:       -- Counter of stuffed bits (for CRC of ISO FD). 
   275:       ----------------------------------------------------------------------------------------------- 
   276:       stuff_ctr_proc : process(res_n, clk_sys) 
   277:       begin 
   278:           if (res_n = '0') then 
   279:               bst_ctr_q <= (others => '0'); 
   280:           elsif rising_edge(clk_sys) then 
   281:               if (stuff_enable = '1') then 
   282:                   bst_ctr_q <= bst_ctr_d; 
   283:               end if; 
   284:           end if; 
   285:       end process; 
   286:    
   287:       ----------------------------------------------------------------------------------------------- 
   288:       -- Reset counter of equal consecutive bits to 1 with bit processing when: 
   289:       --  1. Processing first bit of fixed bit stuffing 
   290:       --  2. Stuff level was reached -> Stuff bit will be inserted 
   291:       --  3. Processed bit differs from previous bit (data out register) and regular stuffing is used. 
   292:       ----------------------------------------------------------------------------------------------- 
   293:       same_bits_rst_trig <= '1' when (non_fix_to_fix_chng = '1') or 
   294:                                      (stuff_lvl_reached = '1') or 
   295:                                      (data_in /= data_out_i and fixed_stuff = '0') 
   296:                                 else 
   297:                             '0'; 
   298:    
   299:       ----------------------------------------------------------------------------------------------- 
   300:       -- Reset counter of equal consecutive bits: 
   301:       --  1. Upon start of bit-stuffing 
   302:       --  2. When processing bit and should be restarted by dedicated signal. 
   303:       ----------------------------------------------------------------------------------------------- 
   304:       same_bits_rst <= '1' when (enable_prev = '0') or 
   305:                                 (bst_trigger = '1' and same_bits_rst_trig = '1') 
   306:                            else 
   307:                        '0'; 
   308:    
   309:       ----------------------------------------------------------------------------------------------- 
   310:       -- Combinationally incremented value of equal consecutive bits of equal value. 
   311:       ----------------------------------------------------------------------------------------------- 
   312:       same_bits_add <= (same_bits_q + 1) mod 8; 
   313:    
   314:       ----------------------------------------------------------------------------------------------- 
   315:       -- Preset value in case of start of transmission without transmission of SOF (as result of 
   316:       -- Sampling dominant and considering this as SOF!): 
   317:       --  1. If we transmitt dominant, we put two, this accounts for SOF + first bit of ID. 
   318:       --  2. If we transmitt recessive, we put one, this accounts only for first bit of ID. 
   319:       ----------------------------------------------------------------------------------------------- 
   320:       tx_no_sof_val <= "10" when (data_in = DOMINANT) else 
   321:                        "01"; 
   322:    
   323:       ----------------------------------------------------------------------------------------------- 
   324:       -- Next value for counter of equal consecutive bits: 
   325:       --  1. Preset to special value when we don't transmit SOF! 
   326:       --  2. Reset 
   327:       --  3. Increment if not reset when processing bit. 
   328:       --  4. Keep original value otherwise. 
   329:       ----------------------------------------------------------------------------------------------- 
   330:       same_bits_d <= ('0' & tx_no_sof_val) when (tx_frame_no_sof = '1') else 
   331:                                      "001" when (same_bits_rst = '1') else 
   332:                              same_bits_add when (bst_trigger = '1') else 
   333:                                same_bits_q; 
   334:    
   335:       ----------------------------------------------------------------------------------------------- 
   336:       -- Number of stuff bits is reached when: 
   337:       --  1. Normal bit stuffing, number of same bits is equal to stuff rule length. Stuff bit is 
   338:       --     already included in counting next consecutive bits of equal value (recursive behavior). 
   339:       --  2. Fixed bit stuffing, number of same bits is equal to one more than rule length, since 
   340:       --     stuff bit is not included then! 
   341:       -- 
   342:       -- In both cases the "same_bits_q" is equal to 5, since for fixed stuffing the length of 
   343:       -- stuff rule (4) compensates for recursivity of regular bit stuffing! 
   344:       ----------------------------------------------------------------------------------------------- 
   345:       stuff_lvl_reached <= '1' when (same_bits_q = "101") 
   346:                                else 
   347:                            '0'; 
   348:    
   349:       ----------------------------------------------------------------------------------------------- 
   350:       -- Counter of equal consecutive bits on input 
   351:       ----------------------------------------------------------------------------------------------- 
   352:       same_bits_ctr_proc : process(res_n, clk_sys) 
   353:       begin 
   354:           if (res_n = '0') then 
   355:               same_bits_q <= "001"; 
   356:           elsif rising_edge(clk_sys) then 
   357:               if (stuff_enable = '1') then 
   358:                   same_bits_q <= same_bits_d; 
   359:               else 
   360:                   same_bits_q <= "001"; 
   361:               end if; 
   362:           end if; 
   363:       end process; 
   364:    
   365:       ----------------------------------------------------------------------------------------------- 
   366:       -- Stuff bit should be inserted: 
   367:       --  1. Upon change of non-fixed to fixed bit stuffing 
   368:       --  2. Number of equal consecutive bits has reached length of stuff rule. 
   369:       ----------------------------------------------------------------------------------------------- 
   370:       insert_stuff_bit <= '1' when (non_fix_to_fix_chng = '1' or stuff_lvl_reached = '1') 
   371:                               else 
   372:                           '0'; 
   373:    
   374:       ----------------------------------------------------------------------------------------------- 
   375:       -- Calculation of output data value: 
   376:       --  1. Recessive bit after restart 
   377:       --  2. Negation of previous value when stuff bit is inserted. 
   378:       --  3. Pipe the input data upon trigger without stufffing 
   379:       --  4. Keep previous value otherwise 
   380:       ----------------------------------------------------------------------------------------------- 
   381:       data_out_d_ena <= (not data_out_i) when (bst_trigger = '1' and insert_stuff_bit = '1') else 
   382:                                 data_in  when (bst_trigger = '1') else 
   383:                              data_out_i; 
   384:    
   385:       data_out_d <= data_out_d_ena when (stuff_enable = '1') else 
   386:                            data_in when (bst_trigger = '1') else 
   387:                         data_out_i; 
   388:    
   389:       data_out_ce <= '1' when (stuff_enable = '1' or bst_trigger = '1') else 
   390:                        '0'; 
   391:    
   392:       ----------------------------------------------------------------------------------------------- 
   393:       -- Output data register. Stuffed data are stored to this register in trigger, or input data 
   394:       -- are piped directly to this register when enable = '0'. 
   395:       ----------------------------------------------------------------------------------------------- 
   396:       dff_data_out_reg : entity ctu_can_fd_rtl.dff_arst_ce 
   397:       generic map ( 
   398:           G_RESET_POLARITY   => '0', 
   399:           G_RST_VAL          => RECESSIVE 
   400:       ) 
   401:       port map ( 
   402:           arst               => res_n,            -- IN 
   403:           clk                => clk_sys,          -- IN 
   404:           reg_d              => data_out_d,       -- IN 
   405:           ce                 => data_out_ce,      -- IN 
   406:    
   407:           reg_q              => data_out_i        -- OUT 
   408:       ); 
   409:    
   410:    
   411:       ----------------------------------------------------------------------------------------------- 
   412:       -- Halt register signals to CAN Core that it should wait for one clock cycle because stuff-bit 
   413:       -- was inserted. 
   414:       -- 
   415:       -- Next value for halt register: 
   416:       --  1. Erase upon start of bit-stuffing, or when circuit is disabled. 
   417:       --  2. Signal halt when stuff bit is inserted. 
   418:       --  3. Erase when bit is processed, but stuff bit is not inserted. 
   419:       ----------------------------------------------------------------------------------------------- 
   420:       data_halt_d <= '0' when (enable_prev = '0' or stuff_enable = '0') else 
   421:                      '1' when (bst_trigger = '1' and insert_stuff_bit = '1') else 
   422:                      '0' when (bst_trigger = '1') else 
   423:                      data_halt_q; 
   424:    
   425:       ----------------------------------------------------------------------------------------------- 
   426:       -- Data halt register is updated in Stuff pipeline stage. But information that stuff bit is 
   427:       -- inserted is already needed by TX Shift register in the same cycle so that it stalls and does 
   428:       -- not shift out data (Data would get lost). So we bypass data_halt signal if there is a change 
   429:       -- so that this information is available one clock cycle earlier! 
   430:       ----------------------------------------------------------------------------------------------- 
   431:       data_halt <= data_halt_q when (data_halt_q = data_halt_d) else 
   432:                    data_halt_d; 
   433:    
   434:       ----------------------------------------------------------------------------------------------- 
   435:       -- Halt register 
   436:       ----------------------------------------------------------------------------------------------- 
   437:       dff_halt_reg : entity ctu_can_fd_rtl.dff_arst 
   438:       generic map ( 
   439:           G_RESET_POLARITY   => '0', 
   440:           G_RST_VAL          => '0' 
   441:       ) 
   442:       port map ( 
   443:           arst               => res_n,            -- IN 
   444:           clk                => clk_sys,          -- IN 
   445:           reg_d              => data_halt_d,      -- IN 
   446:    
   447:           reg_q              => data_halt_q       -- OUT 
   448:       ); 
   449:    
   450:       ----------------------------------------------------------------------------------------------- 
   451:       -- Propagating internal signals to output 
   452:       ----------------------------------------------------------------------------------------------- 
   453:       bst_ctr <= std_logic_vector(bst_ctr_q); 
   454:       data_out <= data_out_i; 
   455:    
   456:   end architecture;