NVC code coverage report

File:  /__w/ctu-can-regression/ctu-can-regression/src/txt_buffer/txt_buffer_fsm.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:   --  Transmitt Frame Buffer FSM. 
    71:   -- 
    72:   -- Purpose: 
    73:   --  Handles HW commands from Protocol control and SW commands from Memory 
    74:   --  registers. 
    75:   -------------------------------------------------------------------------------- 
    76:    
    77:   Library ieee; 
    78:   use ieee.std_logic_1164.all; 
    79:   use ieee.numeric_std.ALL; 
    80:   use ieee.math_real.ALL; 
    81:    
    82:   Library ctu_can_fd_rtl; 
    83:   use ctu_can_fd_rtl.can_constants_pkg.all; 
    84:   use ctu_can_fd_rtl.can_types_pkg.all; 
    85:    
    86:   use ctu_can_fd_rtl.CAN_FD_register_map.all; 
    87:   use ctu_can_fd_rtl.CAN_FD_frame_format.all; 
    88:    
    89:   entity txt_buffer_fsm is 
    90:       port ( 
    91:           ------------------------------------------------------------------------------------------- 
    92:           -- Clock and Asynchronous reset 
    93:           ------------------------------------------------------------------------------------------- 
    94:           clk_sys                 : in  std_logic; 
    95:           res_n                   : in  std_logic; 
    96:    
    97:           ------------------------------------------------------------------------------------------- 
    98:           -- Memory registers interface 
    99:           ------------------------------------------------------------------------------------------- 
   100:           mr_mode_bmm             : in  std_logic; 
   101:           mr_mode_rom             : in  std_logic; 
   102:           mr_settings_tbfbo       : in  std_logic; 
   103:    
   104:           ------------------------------------------------------------------------------------------- 
   105:           -- Control signals 
   106:           ------------------------------------------------------------------------------------------- 
   107:           tx_command_txce_valid   : in  std_logic; 
   108:           tx_command_txcr_valid   : in  std_logic; 
   109:           abort_applied           : in  std_logic; 
   110:           abort_or_skipped        : in  std_logic; 
   111:    
   112:           ------------------------------------------------------------------------------------------- 
   113:           -- CAN Core interface 
   114:           ------------------------------------------------------------------------------------------- 
   115:           -- HW Commands 
   116:           txtb_hw_cmd             : in  t_txtb_hw_cmd; 
   117:    
   118:           -- HW Buffer select 
   119:           txtb_hw_cmd_cs          : in  std_logic; 
   120:    
   121:           -- Unit is Bus off 
   122:           is_bus_off              : in  std_logic; 
   123:    
   124:           ------------------------------------------------------------------------------------------- 
   125:           -- Parity checking logic 
   126:           ------------------------------------------------------------------------------------------- 
   127:           -- Parity Error 
   128:           txtb_parity_error_valid : in  std_logic; 
   129:    
   130:           ------------------------------------------------------------------------------------------- 
   131:           -- Status signals 
   132:           ------------------------------------------------------------------------------------------- 
   133:           -- Buffer accessible from SW 
   134:           txtb_user_accessible    : out std_logic; 
   135:    
   136:           -- TXT Buffer is in state for which its backup buffer can be used 
   137:           txtb_allow_bb           : out std_logic; 
   138:    
   139:           -- HW Command applied on TXT Buffer. 
   140:           txtb_hw_cmd_int         : out std_logic; 
   141:    
   142:           -- Buffer status (FSM state) encoded for reading by SW. 
   143:           txtb_state              : out std_logic_vector(3 downto 0); 
   144:    
   145:           -- TXT Buffer is available to be locked by CAN Core for transmission 
   146:           txtb_available          : out std_logic; 
   147:    
   148:           -- UnMask content of TXT Buffer RAM 
   149:           txtb_unmask_data_ram    : out std_logic 
   150:       ); 
   151:   end entity; 
   152:    
   153:   architecture rtl of txt_buffer_fsm is 
   154:    
   155:       -- FSM signals 
   156:       signal next_state           : t_txt_buf_state; 
   157:       signal curr_state           : t_txt_buf_state; 
   158:    
   159:       -- TXT Buffer clock enable 
   160:       signal txt_fsm_ce           : std_logic; 
   161:    
   162:       -- Forced transition to failed state 
   163:       signal go_to_failed         : std_logic; 
   164:       signal transient_state      : std_logic; 
   165:    
   166:       -- Internal HW Command, filtered by HW chip select for this Buffer 
   167:       signal txtb_hw_cmd_i         : t_txtb_hw_cmd; 
   168:    
   169:       -- Arbitration lost or error valid fro current TXT Buffer 
   170:       signal arbl_or_err           : std_logic; 
   171:    
   172:   begin 
   173:    
   174:       transient_state <= '1' when ((curr_state = s_txt_ab_prog) or 
   175:                                    (curr_state = s_txt_tx_prog) or 
   176:                                    (curr_state = s_txt_ready)) 
   177:                             else 
   178:                         '0'; 
   179:    
   180:       go_to_failed <= '1' when ((is_bus_off = '1' and mr_settings_tbfbo = TXTBUF_FAILED_BUS_OFF_ENABLED) or 
   181:                                 mr_mode_bmm = BMM_ENABLED or 
   182:                                 mr_mode_rom = ROM_ENABLED) 
   183:                           else 
   184:                       '0'; 
   185:    
   186:       txtb_hw_cmd_i <= txtb_hw_cmd when (txtb_hw_cmd_cs = '1') 
   187:                                    else 
   188:                        (others => '0'); 
   189:    
   190:       arbl_or_err <= '1' when (txtb_hw_cmd_i.err = '1' or txtb_hw_cmd_i.arbl = '1') else 
   191:                      '0'; 
   192:    
   193:       txtb_allow_bb <= transient_state; 
   194:    
   195:       ----------------------------------------------------------------------------------------------- 
   196:       -- Next state process 
   197:       ----------------------------------------------------------------------------------------------- 
   198:       tx_buf_fsm_next_state_proc : process(curr_state, tx_command_txce_valid, tx_command_txcr_valid, 
   199:           txtb_hw_cmd_i, abort_applied, go_to_failed, txtb_parity_error_valid, abort_or_skipped, 
   200:           arbl_or_err) 
   201:       begin 
   202:           next_state <= curr_state; 
   203:    
   204:           case curr_state is 
   205:    
   206:           ------------------------------------------------------------------------------------------- 
   207:           -- Buffer is empty 
   208:           ------------------------------------------------------------------------------------------- 
   209:           when s_txt_empty => 
   210:    
   211:               -- "Set_ready" 
   212:               if (tx_command_txcr_valid = '1') then 
   213:                   next_state <= s_txt_ready; 
   214:               end if; 
   215:    
   216:           ------------------------------------------------------------------------------------------- 
   217:           -- Buffer is ready for transmission 
   218:           ------------------------------------------------------------------------------------------- 
   219:           when s_txt_ready => 
   220:    
   221:               -- Node became bus-off 
   222:               if (go_to_failed = '1') then 
   223:                   next_state <= s_txt_failed; 
   224:    
   225:               -- Parity Error occured 
   226:               elsif (txtb_parity_error_valid = '1') then 
   227:                   next_state <= s_txt_parity_err; 
   228:    
   229:               -- Locking for transmission 
   230:               elsif (txtb_hw_cmd_i.lock = '1') then 
   231:    
   232:                   -- Simultaneous "lock" and abort -> transmit, but with abort pending 
   233:                   if (abort_applied = '1') then 
   234:                       next_state <= s_txt_ab_prog; 
   235:                   else 
   236:                       next_state <= s_txt_tx_prog; 
   237:                   end if; 
   238:    
   239:               -- Abort the ready buffer or Skip the original TXT Buffer getting "failed" or "OK". 
   240:               elsif (abort_or_skipped = '1') then 
   241:                   next_state <= s_txt_aborted; 
   242:               end if; 
   243:    
   244:           ------------------------------------------------------------------------------------------- 
   245:           -- Transmission from buffer is in progress 
   246:           ------------------------------------------------------------------------------------------- 
   247:           when s_txt_tx_prog => 
   248:    
   249:               -- Node became bus-off 
   250:               if (go_to_failed = '1') then 
   251:                   next_state <= s_txt_failed; 
   252:    
   253:               -- Parity Error occured 
   254:               elsif (txtb_parity_error_valid = '1') then 
   255:                   next_state <= s_txt_parity_err; 
   256:    
   257:               -- Retransmitt reached, do not try again 
   258:               elsif (txtb_hw_cmd_i.failed = '1') then 
   259:                   next_state <= s_txt_failed; 
   260:    
   261:               -- Transmission OK 
   262:               elsif (txtb_hw_cmd_i.valid = '1') then 
   263:                   next_state <= s_txt_ok; 
   264:    
   265:               -- Error or arbitration lost 
   266:               elsif (arbl_or_err = '1') then 
   267:                   if (abort_applied = '1') then 
   268:                       next_state <= s_txt_aborted; 
   269:                   else 
   270:                       next_state <= s_txt_ready; 
   271:                   end if; 
   272:    
   273:               -- Request abort during transmission 
   274:               elsif (abort_applied = '1') then 
   275:                   next_state <= s_txt_ab_prog; 
   276:               end if; 
   277:    
   278:           ------------------------------------------------------------------------------------------- 
   279:           -- Transmission is in progress -> abort at nearest error! 
   280:           ------------------------------------------------------------------------------------------- 
   281:           when s_txt_ab_prog => 
   282:    
   283:               -- Node became bus-off 
   284:               if (go_to_failed = '1') then 
   285:                   next_state <= s_txt_failed; 
   286:    
   287:               -- Parity Error occured 
   288:               elsif (txtb_parity_error_valid = '1') then 
   289:                   next_state <= s_txt_parity_err; 
   290:    
   291:               -- Retransmitt reached, do not try again 
   292:               elsif (txtb_hw_cmd_i.failed = '1') then 
   293:                   next_state <= s_txt_failed; 
   294:    
   295:               -- Transmission OK 
   296:               elsif (txtb_hw_cmd_i.valid = '1') then 
   297:                   next_state <= s_txt_ok; 
   298:    
   299:               -- Error or arbitration lost 
   300:               elsif (arbl_or_err = '1') then 
   301:                   next_state <= s_txt_aborted; 
   302:               end if; 
   303:    
   304:           ------------------------------------------------------------------------------------------- 
   305:           -- Transmission from buffer failed. Retransmitt limit was reached. 
   306:           ------------------------------------------------------------------------------------------- 
   307:           when s_txt_failed => 
   308:    
   309:               -- "Set_ready" 
   310:               if (tx_command_txcr_valid = '1') then 
   311:                   next_state <= s_txt_ready; 
   312:    
   313:               -- "Set_empty" 
   314:               elsif (tx_command_txce_valid = '1') then 
   315:                   next_state <= s_txt_empty; 
   316:               end if; 
   317:    
   318:           ------------------------------------------------------------------------------------------- 
   319:           -- Transmission was aborted by user command 
   320:           ------------------------------------------------------------------------------------------- 
   321:           when s_txt_aborted => 
   322:    
   323:               -- "Set_ready" 
   324:               if (tx_command_txcr_valid = '1') then 
   325:                   next_state <= s_txt_ready; 
   326:    
   327:               -- "Set_empty" 
   328:               elsif (tx_command_txce_valid = '1') then 
   329:                   next_state <= s_txt_empty; 
   330:               end if; 
   331:    
   332:           ------------------------------------------------------------------------------------------- 
   333:           -- Transmission was succesfull 
   334:           ------------------------------------------------------------------------------------------- 
   335:           when s_txt_ok => 
   336:    
   337:               -- "Set_ready" 
   338:               if (tx_command_txcr_valid = '1') then 
   339:                   next_state <= s_txt_ready; 
   340:    
   341:               -- "Set_empty" 
   342:               elsif (tx_command_txce_valid = '1') then 
   343:                   next_state <= s_txt_empty; 
   344:               end if; 
   345:    
   346:           ------------------------------------------------------------------------------------------- 
   347:           -- Parity Error 
   348:           ------------------------------------------------------------------------------------------- 
   349:           when s_txt_parity_err => 
   350:    
   351:               -- "Set_ready" 
   352:               if (tx_command_txcr_valid = '1') then 
   353:                   next_state <= s_txt_ready; 
   354:    
   355:               -- "Set_empty" 
   356:               elsif (tx_command_txce_valid = '1') then 
   357:                   next_state <= s_txt_empty; 
   358:               end if; 
   359:    
   360:           end case; 
   361:    
   362:       end process; 
   363:    
   364:       ----------------------------------------------------------------------------------------------- 
   365:       -- State register clock enable 
   366:       ----------------------------------------------------------------------------------------------- 
   367:       txt_fsm_ce <= '1' when (next_state /= curr_state) else 
   368:                     '0'; 
   369:    
   370:       ----------------------------------------------------------------------------------------------- 
   371:       -- State register 
   372:       ----------------------------------------------------------------------------------------------- 
   373:       tx_buf_fsm_state_reg_proc : process(res_n, clk_sys) 
   374:       begin 
   375:           if (res_n = '0') then 
   376:               curr_state <= s_txt_empty; 
   377:           elsif (rising_edge(clk_sys)) then 
   378:               if (txt_fsm_ce = '1') then 
   379:                   curr_state <= next_state; 
   380:               end if; 
   381:           end if; 
   382:       end process; 
   383:    
   384:       ----------------------------------------------------------------------------------------------- 
   385:       -- Buffer FSM outputs 
   386:       ----------------------------------------------------------------------------------------------- 
   387:       -- Memory protection of TXT Buffer 
   388:       txtb_user_accessible <= '0' when ((curr_state = s_txt_ready)   or 
   389:                                         (curr_state = s_txt_tx_prog) or 
   390:                                         (curr_state = s_txt_ab_prog)) 
   391:                                     else 
   392:                               '1'; 
   393:    
   394:       -- TXT Buffer HW Command generates interrupt upon transition to Failed, Done and Aborted states! 
   395:       txtb_hw_cmd_int <= '1' when (txtb_hw_cmd_i.failed = '1') or  -- Fail transition completely 
   396:                                   (txtb_hw_cmd_i.valid = '1') or   -- Finish transition OK 
   397:                                   ((txtb_hw_cmd_i.arbl = '1' or 
   398:                                     txtb_hw_cmd_i.err = '1') and 
   399:                                    (curr_state = s_txt_ab_prog))   -- Not failed completely, but already in 
   400:                                                                    -- abort in progress -> No further transmissions 
   401:                                                                    -- will continue -> Indicate to user 
   402:                              else 
   403:                          '1' when (is_bus_off = '1' and next_state = s_txt_failed and 
   404:                                    transient_state = '1') 
   405:                              else 
   406:                          '0'; 
   407:    
   408:       -- Buffer is available for selection by TX Arbitrator only in state "Ready" Abort signal must 
   409:       -- not be active. If not considered, race condition between HW and SW commands could occur! 
   410:       txtb_available   <= '1' when ((curr_state = s_txt_ready) and (abort_applied = '0')) 
   411:                               else 
   412:                           '0'; 
   413:    
   414:       -- Encoding Buffer FSM to output values read from TXT Buffer status register. 
   415:       with curr_state select txtb_state <= 
   416:           TXT_RDY   when s_txt_ready, 
   417:           TXT_TRAN  when s_txt_tx_prog, 
   418:           TXT_ABTP  when s_txt_ab_prog, 
   419:           TXT_TOK   when s_txt_ok, 
   420:           TXT_ERR   when s_txt_failed, 
   421:           TXT_ABT   when s_txt_aborted, 
   422:           TXT_ETY   when s_txt_empty, 
   423:           TXT_PER   when s_txt_parity_err; 
   424:    
   425:       ----------------------------------------------------------------------------------------------- 
   426:       -- Unmask content of TXT Buffer RAM (make it available for CAN Core and TX Arbitrator) when it 
   427:       -- is valid for them to read from there. That is during TXT Buffer selection or during 
   428:       -- transmission. During other moments content of TXT Buffer RAM is not needed by CAN Core nor 
   429:       -- TX Arbitrator! 
   430:       ----------------------------------------------------------------------------------------------- 
   431:       txtb_unmask_data_ram <= '1' when (transient_state = '1') 
   432:                                   else 
   433:                               '0'; 
   434:    
   435:       ----------------------------------------------------------------------------------------------- 
   436:       -- Assertions 
   437:       ----------------------------------------------------------------------------------------------- 
   438:    
   439:       -- psl default clock is rising_edge(clk_sys); 
   440:    
   441:       -- HW Lock command should never arrive when the buffer is in other state 
   442:       -- than ready 
   443:       -- 
   444:       -- psl txtb_lock_only_in_rdy_asrt : assert always 
   445:       --  ((txtb_hw_cmd.lock = '1' and txtb_hw_cmd_cs = '1') -> curr_state = s_txt_ready) 
   446:       --  report "TXT Buffer not READY when LOCK command occurred!"; 
   447:       ----------------------------------------------------------------------------------------------- 
   448:       -- HW Unlock command is valid only when Buffer is TX in Progress or Abort in 
   449:       -- progress. 
   450:       -- 
   451:       -- psl txtb_unlock_only_in_tx_prog_asrt : assert always 
   452:       --  ((txtb_hw_cmd_i.valid = '1' or txtb_hw_cmd_i.err = '1' or txtb_hw_cmd_i.arbl = '1' or txtb_hw_cmd_i.failed = '1') -> 
   453:       --   (curr_state = s_txt_tx_prog or curr_state = s_txt_ab_prog or curr_state = s_txt_parity_err)) 
   454:       --  report "TXT Buffer not TX in progress, Abort in progress or Parity Error when unlock received!"; 
   455:       ----------------------------------------------------------------------------------------------- 
   456:       -- HW Lock command should never occur when there was abort in previous cycle! 
   457:       -- 
   458:       -- psl txtb_no_lock_after_abort : assert never 
   459:       --  {abort_applied = '1';txtb_hw_cmd.lock = '1' and txtb_hw_cmd_cs = '1'} 
   460:       --  report "LOCK command after ABORT was applied!"; 
   461:       ----------------------------------------------------------------------------------------------- 
   462:    
   463:   end architecture;