NVC code coverage report

File:  /__w/ctu-can-regression/ctu-can-regression/src/tx_arbitrator/tx_arbitrator.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:   --  TX Arbitrator 
    71:   -- 
    72:   -- Purpose: 
    73:   --  Circuit for selecting the valid frame for CAN Core from generic number of 
    74:   --  TXT buffer inputs. Compares priorities of each buffer (SW selected) and 
    75:   --  picks the highest priority buffer whose input is valid. Timestamp of high- 
    76:   --  est priority frame is selected and compared with external timestamp. The 
    77:   --  frame is marked as valid for CAN Core only if this timestamp is lower than 
    78:   --  value of external Timestamp. This realizes the functionality of transmission 
    79:   --  at exact time! Metadata of transmitted frame are loaded to output of TX 
    80:   --  Arbitrator as part of selection process. 
    81:   -------------------------------------------------------------------------------- 
    82:    
    83:   Library ieee; 
    84:   use ieee.std_logic_1164.all; 
    85:   use ieee.numeric_std.ALL; 
    86:   use ieee.math_real.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 tx_arbitrator is 
    96:       generic ( 
    97:           -- Number of TXT Buffers 
    98:           G_TXT_BUFFER_COUNT      : natural range 1 to 8 
    99:       ); 
   100:       port ( 
   101:           ------------------------------------------------------------------------------------------- 
   102:           -- Clock and Asynchronous reset 
   103:           ------------------------------------------------------------------------------------------- 
   104:           clk_sys                 : in  std_logic; 
   105:           res_n                   : in  std_logic; 
   106:    
   107:           ------------------------------------------------------------------------------------------- 
   108:           -- TXT Buffers interface 
   109:           ------------------------------------------------------------------------------------------- 
   110:           -- Data words from TXT Buffers RAM memories 
   111:           txtb_port_b_data_out    : in  t_txt_bufs_output(G_TXT_BUFFER_COUNT - 1 downto 0); 
   112:    
   113:           -- TXT Buffers are available, can be selected by TX Arbitrator 
   114:           txtb_available          : in  std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0); 
   115:    
   116:           -- TXT Buffer is in state in which it can have backup buffer 
   117:           txtb_allow_bb           : in  std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0); 
   118:    
   119:           -- Pointer to TXT Buffer 
   120:           txtb_port_b_address     : out std_logic_vector(4 downto 0); 
   121:    
   122:           -- Clock enable to TXT Buffer port B 
   123:           txtb_port_b_clk_en      : out std_logic; 
   124:    
   125:           -- Parity check valid 
   126:           txtb_parity_check_valid : out std_logic; 
   127:    
   128:           -- Parity Mismatch in TXT Buffer 
   129:           txtb_parity_mismatch    : in  std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0); 
   130:    
   131:           -- TXT Buffer index 
   132:           txtb_index_muxed        : out natural range 0 to G_TXT_BUFFER_COUNT - 1; 
   133:    
   134:           -- TXT Buffer is operating as backup buffer 
   135:           txtb_is_bb              : out std_logic_vector(G_TXT_BUFFER_COUNT / 2 - 1 downto 0); 
   136:    
   137:           ------------------------------------------------------------------------------------------- 
   138:           -- CAN Core Interface 
   139:           ------------------------------------------------------------------------------------------- 
   140:           -- TXT Buffer memory word 
   141:           tran_word               : out std_logic_vector(31 downto 0); 
   142:    
   143:           -- TX Data length code 
   144:           tran_dlc                : out std_logic_vector(3 downto 0); 
   145:    
   146:           -- TX Remote transmission request flag 
   147:           tran_is_rtr             : out std_logic; 
   148:    
   149:           -- TX Identifier type (0-Basic,1-Extended); 
   150:           tran_ident_type         : out std_logic; 
   151:    
   152:           -- TX Frame type (0-CAN 2.0, 1-CAN FD) 
   153:           tran_frame_type         : out std_logic; 
   154:    
   155:           -- TX Frame Bit rate shift Flag 
   156:           tran_brs                : out std_logic; 
   157:    
   158:           -- TX Identifier 
   159:           tran_identifier         : out std_logic_vector(28 downto 0); 
   160:    
   161:           -- TX Frame test 
   162:           tran_frame_test         : out t_frame_test_w; 
   163:    
   164:           -- There is valid frame selected, can be locked for transmission 
   165:           tran_frame_valid        : out std_logic; 
   166:    
   167:           -- Parity error occured during read of data words from TXT Buffer 
   168:           tran_frame_parity_error : out std_logic; 
   169:    
   170:           -- HW Commands from CAN Core for manipulation with TXT Buffers 
   171:           txtb_hw_cmd             : in  t_txtb_hw_cmd; 
   172:    
   173:           -- Selected TXT Buffer changed in comparison to previous transmission 
   174:           txtb_changed            : out std_logic; 
   175:    
   176:           -- Index of the TXT Buffer for which the actual HW command is valid 
   177:           txtb_hw_cmd_cs          : out std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0); 
   178:    
   179:           -- Pointer to TXT Buffer given by CAN Core. Used for reading data words. 
   180:           txtb_ptr                : in  natural range 0 to 20; 
   181:    
   182:           -- TXT Buffer clock enable (from Protocol control) 
   183:           txtb_clk_en             : in  std_logic; 
   184:    
   185:           ------------------------------------------------------------------------------------------- 
   186:           -- RX Buffer interface 
   187:           ------------------------------------------------------------------------------------------- 
   188:    
   189:           -- TXT Buffer index that is: 
   190:           --   - Currently validated (when no transmission is in progress) 
   191:           --   - Used for transmission (when transmission is in progress) 
   192:           curr_txtb_index         : out std_logic_vector(2 downto 0); 
   193:    
   194:           ------------------------------------------------------------------------------------------- 
   195:           -- Memory registers interface 
   196:           ------------------------------------------------------------------------------------------- 
   197:           mr_mode_tttm            : in  std_logic; 
   198:           mr_mode_txbbm           : in  std_logic; 
   199:           mr_settings_pchke       : in  std_logic; 
   200:           mr_tx_priority          : in  t_txt_bufs_priorities(G_TXT_BUFFER_COUNT - 1 downto 0); 
   201:    
   202:           ------------------------------------------------------------------------------------------- 
   203:           -- Timestamp 
   204:           ------------------------------------------------------------------------------------------- 
   205:           timestamp               : in  std_logic_vector(63 downto 0) 
   206:     ); 
   207:   end entity; 
   208:    
   209:   architecture rtl of tx_arbitrator is 
   210:    
   211:       ----------------------------------------------------------------------------------------------- 
   212:       -- Internal signals 
   213:       ----------------------------------------------------------------------------------------------- 
   214:    
   215:       -- Indicates the highest selected buffer and its validity from combinational priority decoder 
   216:       signal select_buf_avail           : std_logic; 
   217:       signal select_buf_index           : natural range 0 to G_TXT_BUFFER_COUNT - 1; 
   218:    
   219:       -- Input word from TXT Buffer !!! 
   220:       signal txtb_selected_input        : std_logic_vector(31 downto 0); 
   221:    
   222:       -- TXT Buffer timestamp joined combinationally. Given by ts_low_internal and upper timestamp 
   223:       -- word, out the output of RAM 
   224:       signal txtb_timestamp             : std_logic_vector(63 downto 0); 
   225:    
   226:       -- Comparison of loaded timestamp from TXT Buffer. 
   227:       signal timestamp_valid            : std_logic; 
   228:    
   229:       -- The output of priority decoder (selected TXT Buffer) has changed, pulse for one clock cycle 
   230:       signal select_index_changed       : std_logic; 
   231:    
   232:       -- Signal that there is "Validated" TXT Buffer 
   233:       signal validated_buffer           : std_logic; 
   234:    
   235:       -- TXT Buffer clock enable (one cycle later) 
   236:       signal txtb_clk_en_q              : std_logic; 
   237:    
   238:       -- Metadata words read by TX Arbitrator are valid 
   239:       signal tx_arb_parity_check_valid  : std_logic; 
   240:    
   241:       ----------------------------------------------------------------------------------------------- 
   242:       -- Internal registers 
   243:       ----------------------------------------------------------------------------------------------- 
   244:    
   245:       -- Registered values for detection of change 
   246:       signal select_buf_index_reg       : natural range 0 to G_TXT_BUFFER_COUNT - 1; 
   247:    
   248:       -- Lower timestamp loaded from TXT Buffer 
   249:       signal ts_low_internal            : std_logic_vector(31 downto 0); 
   250:    
   251:       -- TXT Buffer index that is: 
   252:       --      - Currently validated (when no transmission is in progress) 
   253:       --      - Used for transmission (when transmission is in progress) 
   254:       signal curr_txtb_index_i          : natural range 0 to G_TXT_BUFFER_COUNT - 1; 
   255:    
   256:       -- TXT Buffer internal index of last buffer that was locked from buffer change, Protocol control 
   257:       -- can erase retransmitt counter 
   258:       signal last_txtb_index            : natural range 0 to G_TXT_BUFFER_COUNT - 1; 
   259:    
   260:       -- TXT Buffer index validated or used for transmission 
   261:       signal txtb_index_muxed_i         : natural range 0 to G_TXT_BUFFER_COUNT - 1; 
   262:    
   263:       -- Pointer to TXT Buffer for loading CAN frame metadata and timstamp during the selection of 
   264:       -- TXT Buffer. 
   265:       signal txtb_pointer_meta_q        : natural range 0 to 20; 
   266:       signal txtb_pointer_meta_d        : natural range 0 to 20; 
   267:    
   268:       -- Double buffer registers for metadata 
   269:       signal tran_dlc_dbl_buf           : std_logic_vector(3 downto 0); 
   270:       signal tran_is_rtr_dbl_buf        : std_logic; 
   271:       signal tran_ident_type_dbl_buf    : std_logic; 
   272:       signal tran_frame_type_dbl_buf    : std_logic; 
   273:       signal tran_brs_dbl_buf           : std_logic; 
   274:    
   275:       -- Double buffer register for frame testability 
   276:       signal tran_frame_test_dbl_buf    : t_frame_test_w; 
   277:    
   278:       -- Comitted values of internal signals 
   279:       signal tran_dlc_com               : std_logic_vector(3 downto 0); 
   280:       signal tran_is_rtr_com            : std_logic; 
   281:       signal tran_ident_type_com        : std_logic; 
   282:       signal tran_frame_type_com        : std_logic; 
   283:       signal tran_brs_com               : std_logic; 
   284:       signal tran_frame_valid_com       : std_logic; 
   285:       signal tran_identifier_com        : std_logic_vector(28 downto 0); 
   286:    
   287:       ----------------------------------------------------------------------------------------------- 
   288:       -- TX Arbitrator FSM outputs 
   289:       ----------------------------------------------------------------------------------------------- 
   290:    
   291:       -- Load Timestamp lower word to metadata pointer 
   292:       signal load_ts_lw_addr            : std_logic; 
   293:    
   294:       -- Load Timestamp upper word to metadata pointer 
   295:       signal load_ts_uw_addr            : std_logic; 
   296:    
   297:       -- Load Frame format word to metadata pointer 
   298:       signal load_ffmt_w_addr           : std_logic; 
   299:    
   300:       -- Load identifier word to metadata pointer 
   301:       signal load_ident_w_addr          : std_logic; 
   302:    
   303:       -- Load frame test word to metadata pointer 
   304:       signal load_frame_test_w_addr     : std_logic; 
   305:    
   306:       -- Store timestamp lower word 
   307:       signal store_ts_l_w               : std_logic; 
   308:    
   309:       -- Commit content of double buffer registers to registers visible by CAN Core 
   310:       signal commit_dbl_bufs            : std_logic; 
   311:    
   312:       -- Store metadata (Frame format word) to double buffer registers. 
   313:       signal buffer_md_w                : std_logic; 
   314:    
   315:       -- Store frame test word to double buffer registers 
   316:       signal buffer_frame_test_w        : std_logic; 
   317:    
   318:       -- Store last locked TXT Buffer index 
   319:       signal store_last_txtb_index      : std_logic; 
   320:    
   321:       -- Set valid selected buffer on TX Arbitrator output. 
   322:       signal frame_valid_com_set        : std_logic; 
   323:    
   324:       -- Clear valid selected buffer on TX Arbitrator output. 
   325:       signal frame_valid_com_clear      : std_logic; 
   326:    
   327:       -- TX Arbitrator is locked 
   328:       signal tx_arb_locked              : std_logic; 
   329:    
   330:       -- TXT Buffer clock enable for reading metadata 
   331:       signal txtb_meta_clk_en           : std_logic; 
   332:    
   333:       -- TXT Buffer Backup mode enable 
   334:       signal mr_tx_priority_txbbm       : t_txt_bufs_priorities(G_TXT_BUFFER_COUNT - 1 downto 0); 
   335:    
   336:       -- Parity mismatches in TXT Buffers: 
   337:       --  1. Mismatch during TXT Buffer validation 
   338:       --  2. Mismatch during transmission 
   339:       signal txtb_parity_mismatch_vld   : std_logic; 
   340:       signal txtb_parity_mismatch_tx    : std_logic; 
   341:    
   342:       -- Unlocking TXT Buffers at the end of transmission 
   343:       signal txtb_hw_cmd_unlock         : std_logic; 
   344:    
   345:       ----------------------------------------------------------------------------------------------- 
   346:       -- Comparing procedure for two 64 bit std logic vectors 
   347:       ----------------------------------------------------------------------------------------------- 
   348:       function less_than( 
   349:           signal   a       : in std_logic_vector(63 downto 0); 
   350:           signal   b       : in std_logic_vector(63 downto 0) 
   351:       )return std_logic is 
   352:       begin 
   353:           if (unsigned(a(63 downto 32)) < unsigned(b(63 downto 32))) or 
   354:               ((a(63 downto 32) = b(63 downto 32)) and 
   355:               (unsigned(a(31 downto 0)) < unsigned(b(31 downto 0))))then 
   356:               return '1'; 
   357:           else 
   358:              return '0'; 
   359:           end if; 
   360:       end function; 
   361:    
   362:   begin 
   363:    
   364:       ----------------------------------------------------------------------------------------------- 
   365:       -- Priority decoder on TXT Buffers 
   366:       ----------------------------------------------------------------------------------------------- 
   367:       priority_decoder_inst : entity ctu_can_fd_rtl.priority_decoder 
   368:       generic map ( 
   369:           G_TXT_BUFFER_COUNT    => G_TXT_BUFFER_COUNT 
   370:       ) 
   371:       port map ( 
   372:           prio                       => mr_tx_priority_txbbm,        -- IN 
   373:           prio_valid                 => txtb_available,              -- IN 
   374:    
   375:           output_valid               => select_buf_avail,            -- OUT 
   376:           output_index               => select_buf_index             -- OUT 
   377:       ); 
   378:    
   379:    
   380:       ----------------------------------------------------------------------------------------------- 
   381:       -- TX Arbitrator FSM 
   382:       ----------------------------------------------------------------------------------------------- 
   383:       tx_arbitrator_fsm_inst : entity ctu_can_fd_rtl.tx_arbitrator_fsm 
   384:       port map ( 
   385:           clk_sys                     => clk_sys,                     -- IN 
   386:           res_n                       => res_n,                       -- IN 
   387:    
   388:           select_buf_avail            => select_buf_avail,            -- IN 
   389:           select_index_changed        => select_index_changed,        -- IN 
   390:           timestamp_valid             => timestamp_valid,             -- IN 
   391:           txtb_hw_cmd_lock            => txtb_hw_cmd.lock,            -- IN 
   392:           txtb_hw_cmd_unlock          => txtb_hw_cmd_unlock,          -- IN 
   393:           txtb_parity_mismatch_vld    => txtb_parity_mismatch_vld,    -- IN 
   394:    
   395:           load_ts_lw_addr             => load_ts_lw_addr,             -- OUT 
   396:           load_ts_uw_addr             => load_ts_uw_addr,             -- OUT 
   397:           load_ffmt_w_addr            => load_ffmt_w_addr,            -- OUT 
   398:           load_ident_w_addr           => load_ident_w_addr,           -- OUT 
   399:           load_frame_test_w_addr      => load_frame_test_w_addr,      -- OUT 
   400:           txtb_meta_clk_en            => txtb_meta_clk_en,            -- OUT 
   401:    
   402:           store_ts_l_w                => store_ts_l_w,                -- OUT 
   403:           commit_dbl_bufs             => commit_dbl_bufs,             -- OUT 
   404:           buffer_frame_test_w         => buffer_frame_test_w,         -- OUT 
   405:           buffer_md_w                 => buffer_md_w,                 -- OUT 
   406:           tx_arb_locked               => tx_arb_locked,               -- OUT 
   407:           store_last_txtb_index       => store_last_txtb_index,       -- OUT 
   408:           frame_valid_com_set         => frame_valid_com_set,         -- OUT 
   409:           frame_valid_com_clear       => frame_valid_com_clear,       -- OUT 
   410:           tx_arb_parity_check_valid   => tx_arb_parity_check_valid    -- OUT 
   411:       ); 
   412:    
   413:       ----------------------------------------------------------------------------------------------- 
   414:       -- TXT Buffer differences fo Shuffle priorites of TXT Buffers, in TXT Buffer Backup mode, 
   415:       -- replace priority of "Backup" buffer with priority of "original" buffer 
   416:       ----------------------------------------------------------------------------------------------- 
   417:       txtb_priority_gen : for i in 0 to G_TXT_BUFFER_COUNT - 1 generate 
   418:    
   419:           -- Original Buffers 
   420:           txtb_priority_even_gen : if ((i mod 2) = 0) generate 
   421:               mr_tx_priority_txbbm(i) <= mr_tx_priority(i); 
   422:           end generate; 
   423:    
   424:           -- Backup buffers 
   425:           txtb_priority_odd_gen : if ((i mod 2) = 1) generate 
   426:    
   427:               mr_tx_priority_txbbm(i) <= mr_tx_priority(i) when (mr_mode_txbbm = '0') 
   428:                                                            else 
   429:                                          mr_tx_priority(i - 1); 
   430:    
   431:               txtb_is_bb(i / 2) <= '1' when (mr_mode_txbbm = '1' and curr_txtb_index_i = i-1 and 
   432:                                              txtb_allow_bb(i - 1) = '1') 
   433:                                        else 
   434:                                    '0'; 
   435:           end generate; 
   436:       end generate; 
   437:    
   438:    
   439:       ----------------------------------------------------------------------------------------------- 
   440:       -- Comparing timestamp with external timestamp. This assumes that Upper timestamp is on the 
   441:       -- output of buffer and lower timestamp is stored in "ts_low_internal". 
   442:       ----------------------------------------------------------------------------------------------- 
   443:       timestamp_valid <= less_than(txtb_timestamp, timestamp) when (mr_mode_tttm = TTTM_ENABLED) 
   444:                                                               else 
   445:                                                           '1'; 
   446:    
   447:       ----------------------------------------------------------------------------------------------- 
   448:       -- When TXT Buffer which is currently "Validated" suddenly becomes "Unavailable" (e.g. due to 
   449:       -- Set Abort command), this must be signalled to Protocol control in the same clock cycle! 
   450:       -- During transmission, CAN Core is reading metadata from outputs. Since the frame is valid, 
   451:       -- it is logical to also have "tran_frame_valid" active! 
   452:       ----------------------------------------------------------------------------------------------- 
   453:       validated_buffer <= '1' when (txtb_available(curr_txtb_index_i) = '1') and 
   454:                                    (tran_frame_valid_com = '1') 
   455:                               else 
   456:                           '0'; 
   457:    
   458:       tran_frame_valid <= '1' when (validated_buffer = '1') or (tx_arb_locked = '1') 
   459:                               else 
   460:                           '0'; 
   461:    
   462:       ----------------------------------------------------------------------------------------------- 
   463:       -- Parity mismatch during validation of TXT Buffer, must be indexed using "raw" / 
   464:       -- "combinatorial" index of buffer which is currently being validated. 
   465:       ----------------------------------------------------------------------------------------------- 
   466:       txtb_parity_mismatch_vld <= '1' when (txtb_parity_mismatch(select_buf_index) = '1') 
   467:                                       else 
   468:                                   '0'; 
   469:    
   470:       ----------------------------------------------------------------------------------------------- 
   471:       -- Protocol controller reads from TXT Buffer, so if there is parity mismatch one clock cycle 
   472:       -- later, this means there was error in data word. In such case, signal to Protocol controller 
   473:       -- to start error frame! Buffer one which parity mismatch is checked, must be selected by 
   474:       -- registered index of TXT Buffer which is used for transmission. 
   475:       ----------------------------------------------------------------------------------------------- 
   476:       txtb_parity_mismatch_tx <= '1' when (txtb_parity_mismatch(curr_txtb_index_i) = '1') 
   477:                                      else 
   478:                                  '0'; 
   479:    
   480:       tran_frame_parity_error <= '1' when (txtb_parity_mismatch_tx = '1' and txtb_clk_en_q = '1') 
   481:                                      else 
   482:                                  '0'; 
   483:    
   484:       ----------------------------------------------------------------------------------------------- 
   485:       -- Selecting TXT Buffer output word based on TXT Buffer index. During transmission, use last 
   486:       -- stored TXT buffer. Otherwise use combinatorially selected TXT buffer (during validation). 
   487:       ----------------------------------------------------------------------------------------------- 
   488:       txtb_index_muxed_i <= curr_txtb_index_i when (tx_arb_locked = '1') 
   489:                                               else 
   490:                             select_buf_index; 
   491:    
   492:       -- Parity check. When Protocol controller wants to enable clock for TXT Buffer, it reads data 
   493:       -- words from it for transmission. When this occurs, data will we available on the output of 
   494:       -- TXT Buffer RAM one clock cycle later. At this cycle, TXT Buffer needs to check for parity 
   495:       -- error. 
   496:       txtb_parity_check_valid <= txtb_clk_en_q when (tx_arb_locked = '1') 
   497:                                                else 
   498:                                  tx_arb_parity_check_valid; 
   499:    
   500:       -- Select read data based on index of TXT buffer which should be accessed 
   501:       txtb_selected_input <= txtb_port_b_data_out(txtb_index_muxed_i); 
   502:    
   503:       -- Transmitted data word taken from TXT Buffer output 
   504:       tran_word <= txtb_selected_input; 
   505:       txtb_index_muxed <= txtb_index_muxed_i; 
   506:    
   507:       ----------------------------------------------------------------------------------------------- 
   508:       -- Joined timestamp from TXT Buffer. Note that it is not always valid! Only when the TXT Buffer 
   509:       -- is addressed with upper timestamp word address! 
   510:       ----------------------------------------------------------------------------------------------- 
   511:       txtb_timestamp <= txtb_selected_input & ts_low_internal; 
   512:    
   513:       ----------------------------------------------------------------------------------------------- 
   514:       -- Output frame metadata and Identifier for CAN Core 
   515:       ----------------------------------------------------------------------------------------------- 
   516:       tran_dlc         <= tran_dlc_com; 
   517:       tran_is_rtr      <= tran_is_rtr_com; 
   518:       tran_ident_type  <= tran_ident_type_com; 
   519:       tran_frame_type  <= tran_frame_type_com; 
   520:       tran_brs         <= tran_brs_com; 
   521:       tran_identifier  <= tran_identifier_com; 
   522:    
   523:       ----------------------------------------------------------------------------------------------- 
   524:       -- During Buffer selection, TX Arbitrator is addressing TXT Buffers. 
   525:       -- During Transmission, the Core is addressing TXT Buffers. The same goes for clock enable. 
   526:       ----------------------------------------------------------------------------------------------- 
   527:       -- TODO: Convert pointers to std_logic! 
   528:       txtb_port_b_address <= std_logic_vector(to_unsigned(txtb_ptr, 5)) when (tx_arb_locked = '1') 
   529:                                                                         else 
   530:                              std_logic_vector(to_unsigned(txtb_pointer_meta_q, 5)); 
   531:    
   532:       txtb_port_b_clk_en <= txtb_clk_en when (tx_arb_locked = '1') 
   533:                                         else 
   534:                             txtb_meta_clk_en; 
   535:    
   536:       txtb_hw_cmd_cs_demux_proc : process(curr_txtb_index_i) 
   537:       begin 
   538:           txtb_hw_cmd_cs <= (others => '0'); 
   539:           txtb_hw_cmd_cs(curr_txtb_index_i) <= '1'; 
   540:       end process; 
   541:    
   542:       ----------------------------------------------------------------------------------------------- 
   543:       -- Register for TXT Buffer clock enable 
   544:       ----------------------------------------------------------------------------------------------- 
   545:       txtb_clk_en_reg_proc : process(clk_sys, res_n) 
   546:       begin 
   547:           if (res_n = '0') then 
   548:               txtb_clk_en_q <= '0'; 
   549:           elsif (rising_edge(clk_sys)) then 
   550:               txtb_clk_en_q <= txtb_clk_en; 
   551:           end if; 
   552:       end process; 
   553:    
   554:    
   555:       ----------------------------------------------------------------------------------------------- 
   556:       -- Register for loading lower 32 bits of CAN Frame timestamp 
   557:       ----------------------------------------------------------------------------------------------- 
   558:       low_ts_reg_proc : process(res_n, clk_sys) 
   559:       begin 
   560:           if (res_n = '0') then 
   561:               ts_low_internal <= (others => '0'); 
   562:           elsif (rising_edge(clk_sys)) then 
   563:               if (store_ts_l_w = '1') then 
   564:                   ts_low_internal <= txtb_selected_input; 
   565:               end if; 
   566:           end if; 
   567:       end process; 
   568:    
   569:       ----------------------------------------------------------------------------------------------- 
   570:       -- Double buffer registers for Metadata. 
   571:       ----------------------------------------------------------------------------------------------- 
   572:       dbl_buf_reg_ffmt_proc : process(clk_sys, res_n) 
   573:       begin 
   574:           if (res_n = '0') then 
   575:               tran_dlc_dbl_buf           <= (others => '0'); 
   576:               tran_is_rtr_dbl_buf        <= '0'; 
   577:               tran_ident_type_dbl_buf    <= '0'; 
   578:               tran_frame_type_dbl_buf    <= '0'; 
   579:               tran_brs_dbl_buf           <= '0'; 
   580:           elsif (rising_edge(clk_sys)) then 
   581:               if (buffer_md_w = '1') then 
   582:                   tran_dlc_dbl_buf           <= txtb_selected_input(DLC_H downto DLC_L); 
   583:                   tran_is_rtr_dbl_buf        <= txtb_selected_input(RTR_IND); 
   584:                   tran_ident_type_dbl_buf    <= txtb_selected_input(IDE_IND); 
   585:                   tran_frame_type_dbl_buf    <= txtb_selected_input(FDF_IND); 
   586:                   tran_brs_dbl_buf           <= txtb_selected_input(BRS_IND); 
   587:               end if; 
   588:           end if; 
   589:       end process; 
   590:    
   591:       ----------------------------------------------------------------------------------------------- 
   592:       -- Double buffer registers for Frame test word 
   593:       ----------------------------------------------------------------------------------------------- 
   594:       dbl_buf_reg_ftw_proc : process(clk_sys, res_n) 
   595:       begin 
   596:           if (res_n = '0') then 
   597:               tran_frame_test_dbl_buf.fstc <= '0'; 
   598:               tran_frame_test_dbl_buf.fcrc <= '0'; 
   599:               tran_frame_test_dbl_buf.sdlc <= '0'; 
   600:               tran_frame_test_dbl_buf.tprm <= (others => '0'); 
   601:           elsif (rising_edge(clk_sys)) then 
   602:               if (buffer_frame_test_w = '1') then 
   603:                   tran_frame_test_dbl_buf.fstc <= txtb_selected_input(FSTC_IND); 
   604:                   tran_frame_test_dbl_buf.fcrc <= txtb_selected_input(FCRC_IND); 
   605:                   tran_frame_test_dbl_buf.sdlc <= txtb_selected_input(SDLC_IND); 
   606:                   tran_frame_test_dbl_buf.tprm <= txtb_selected_input(TPRM_H downto TPRM_L); 
   607:               end if; 
   608:           end if; 
   609:       end process; 
   610:    
   611:    
   612:       ----------------------------------------------------------------------------------------------- 
   613:       -- Capture registers for metadata commited to output of TX Arbitrator. Takenfrom double buffer 
   614:       -- register. 
   615:       ----------------------------------------------------------------------------------------------- 
   616:       meta_data_reg_proc : process(clk_sys, res_n) 
   617:       begin 
   618:           if (res_n = '0') then 
   619:               tran_dlc_com         <= (others => '0'); 
   620:               tran_is_rtr_com      <= '0'; 
   621:               tran_ident_type_com  <= '0'; 
   622:               tran_frame_type_com  <= '0'; 
   623:               tran_brs_com         <= '0'; 
   624:           elsif (rising_edge(clk_sys)) then 
   625:               if (commit_dbl_bufs = '1') then 
   626:                   tran_frame_type_com  <= tran_frame_type_dbl_buf; 
   627:                   tran_ident_type_com  <= tran_ident_type_dbl_buf; 
   628:                   tran_dlc_com         <= tran_dlc_dbl_buf; 
   629:                   tran_is_rtr_com      <= tran_is_rtr_dbl_buf; 
   630:                   tran_brs_com         <= tran_brs_dbl_buf; 
   631:               end if; 
   632:           end if; 
   633:       end process; 
   634:    
   635:       ----------------------------------------------------------------------------------------------- 
   636:       -- Capture registers for Identifier commited to output of TX Arbitrator. 
   637:       ----------------------------------------------------------------------------------------------- 
   638:       identifier_reg_proc : process(clk_sys, res_n) 
   639:       begin 
   640:           if (res_n = '0') then 
   641:               tran_identifier_com <= (others => '0'); 
   642:           elsif (rising_edge(clk_sys)) then 
   643:               if (commit_dbl_bufs = '1') then 
   644:                   tran_identifier_com <= txtb_selected_input(28 downto 0); 
   645:               end if; 
   646:           end if; 
   647:       end process; 
   648:    
   649:       ----------------------------------------------------------------------------------------------- 
   650:       -- Capture registers for Frame test word commited to output of TX Arbitrator. 
   651:       ----------------------------------------------------------------------------------------------- 
   652:       frame_test_w_reg_proc : process(clk_sys, res_n) 
   653:       begin 
   654:           if (res_n = '0') then 
   655:               tran_frame_test.fstc <= '0'; 
   656:               tran_frame_test.fcrc <= '0'; 
   657:               tran_frame_test.sdlc <= '0'; 
   658:               tran_frame_test.tprm <= (others => '0'); 
   659:           elsif (rising_edge(clk_sys)) then 
   660:               if (commit_dbl_bufs = '1') then 
   661:                   tran_frame_test <= tran_frame_test_dbl_buf; 
   662:               end if; 
   663:           end if; 
   664:       end process; 
   665:    
   666:       ----------------------------------------------------------------------------------------------- 
   667:       -- Register for "committed" valid frame output for CAN Core 
   668:       ----------------------------------------------------------------------------------------------- 
   669:       tran_frame_valid_com_proc : process(clk_sys, res_n) 
   670:       begin 
   671:           if (res_n = '0') then 
   672:               tran_frame_valid_com        <= '0'; 
   673:           elsif (rising_edge(clk_sys)) then 
   674:               if (frame_valid_com_set = '1') then 
   675:                   tran_frame_valid_com    <= '1'; 
   676:               elsif (frame_valid_com_clear = '1') then 
   677:                   tran_frame_valid_com    <= '0'; 
   678:               end if; 
   679:           end if; 
   680:       end process; 
   681:    
   682:    
   683:       ----------------------------------------------------------------------------------------------- 
   684:       -- Storing values of selected TXT Buffer index when selection process ends. Storing TXT Buffer 
   685:       -- at the time of LOCK from CAN Core. Two values are needed to determine change of selected TXT 
   686:       -- Buffer for CAN Core. CAN Core needs this information for erasing retransmitt limit counter. 
   687:       ----------------------------------------------------------------------------------------------- 
   688:       store_indices_proc : process(clk_sys, res_n) 
   689:       begin 
   690:           if (res_n = '0') then 
   691:               last_txtb_index             <= 0; 
   692:               curr_txtb_index_i           <= 0; 
   693:    
   694:           elsif (rising_edge(clk_sys)) then 
   695:               -- At the time of lock, the last index is stored from the last stored index. 
   696:               if (store_last_txtb_index = '1') then 
   697:                   last_txtb_index         <= curr_txtb_index_i; 
   698:               end if; 
   699:    
   700:               -- Combinationally selected index (select_buf_index) is stored when metadata are stored. 
   701:               if (commit_dbl_bufs = '1') then 
   702:                   curr_txtb_index_i       <= select_buf_index; 
   703:               end if; 
   704:    
   705:           end if; 
   706:       end process; 
   707:    
   708:       txtb_changed  <= '1' when (last_txtb_index /= curr_txtb_index_i and store_last_txtb_index = '1') 
   709:                            else 
   710:                        '0'; 
   711:    
   712:       curr_txtb_index <= std_logic_vector(to_unsigned(curr_txtb_index_i, 3)); 
   713:    
   714:       ----------------------------------------------------------------------------------------------- 
   715:       -- Registering value of combinationally selected index by priority decoder to determine change 
   716:       -- and signal restarting selection process to TX Arbitrator FSM. 
   717:       ----------------------------------------------------------------------------------------------- 
   718:       sel_index_change_proc : process(clk_sys, res_n) 
   719:       begin 
   720:           if (res_n = '0') then 
   721:               select_buf_index_reg  <= 0; 
   722:           elsif (rising_edge(clk_sys)) then 
   723:               select_buf_index_reg <= select_buf_index; 
   724:           end if; 
   725:       end process; 
   726:    
   727:       select_index_changed <= '0' when (select_buf_index = select_buf_index_reg) 
   728:                                   else 
   729:                               '1'; 
   730:    
   731:    
   732:       ----------------------------------------------------------------------------------------------- 
   733:       -- Metadata pointer to address TXT Buffer Timestamp and Metadata Words. 
   734:       ----------------------------------------------------------------------------------------------- 
   735:       txtb_pointer_meta_d <= 
   736:           to_integer(unsigned(TIMESTAMP_L_W_ADR(11 downto 2))) when (load_ts_lw_addr = '1') else 
   737:           to_integer(unsigned(TIMESTAMP_U_W_ADR(11 downto 2))) when (load_ts_uw_addr = '1') else 
   738:           to_integer(unsigned(FRAME_FORMAT_W_ADR(11 downto 2))) when (load_ffmt_w_addr = '1') else 
   739:           to_integer(unsigned(IDENTIFIER_W_ADR(11 downto 2))) when (load_ident_w_addr = '1') else 
   740:           to_integer(unsigned(FRAME_TEST_W_ADR(11 downto 2))) when (load_frame_test_w_addr = '1') else 
   741:           txtb_pointer_meta_q; 
   742:    
   743:       store_meta_data_ptr_proc : process(clk_sys, res_n) 
   744:       begin 
   745:           if (res_n = '0') then 
   746:               txtb_pointer_meta_q <= to_integer(unsigned(TIMESTAMP_L_W_ADR(11 downto 2))); 
   747:           elsif (rising_edge(clk_sys)) then 
   748:               txtb_pointer_meta_q <= txtb_pointer_meta_d; 
   749:           end if; 
   750:       end process; 
   751:    
   752:       ----------------------------------------------------------------------------------------------- 
   753:       -- TXT Buffer unlock - When PC FSM ends transmission from a TXT Buffer 
   754:       ----------------------------------------------------------------------------------------------- 
   755:       txtb_hw_cmd_unlock <= '1' when (txtb_hw_cmd.valid  = '1' or txtb_hw_cmd.err    = '1' or 
   756:                                       txtb_hw_cmd.arbl   = '1' or txtb_hw_cmd.failed = '1') 
   757:                                 else 
   758:                             '0'; 
   759:    
   760:       ----------------------------------------------------------------------------------------------- 
   761:       -- Assertions 
   762:       ----------------------------------------------------------------------------------------------- 
   763:    
   764:       -- psl default clock is rising_edge(clk_sys); 
   765:    
   766:       -- When TXT Buffer is not ready for more than one cycle, LOCK command might not occur. If it is 
   767:       -- not ready for one clock cycle, it might still be due to set abort and LOCK command applied 
   768:       -- simultaneously. This is OK. But as soon as buffer is not ready for second cycle, LOCK command 
   769:       -- can't be active! 
   770:       -- 
   771:       -- psl txtb_no_lock_when_not_ready_asrt : assert never 
   772:       --   {tran_frame_valid = '0'; 
   773:       --    tran_frame_valid = '0' and txtb_hw_cmd.lock = '1'} 
   774:       --   report "NO TXT Buffer ready and lock occurs!"; 
   775:       ----------------------------------------------------------------------------------------------- 
   776:    
   777:   end architecture;