NVC code coverage report

File:  /__w/ctu-can-regression/ctu-can-regression/src/tx_arbitrator/priority_decoder.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:   --  Priority decoder. 
    71:   -- 
    72:   -- Purpose: 
    73:   --  Combinational decoder for TXT BufferS priority. Considers priority, bufffer 
    74:   --  validity. Generic amount of buffers is available (up to 8). Decoder consists 
    75:   --  of 3 levels of comparators (4+2+1). If two frames have the same priority, 
    76:   --  a frame with lower index is selected. 
    77:   -------------------------------------------------------------------------------- 
    78:    
    79:   Library ieee; 
    80:   use ieee.std_logic_1164.all; 
    81:   use ieee.numeric_std.ALL; 
    82:   use ieee.math_real.ALL; 
    83:    
    84:   Library ctu_can_fd_rtl; 
    85:   use ctu_can_fd_rtl.can_constants_pkg.all; 
    86:   use ctu_can_fd_rtl.can_types_pkg.all; 
    87:    
    88:   use ctu_can_fd_rtl.CAN_FD_register_map.all; 
    89:   use ctu_can_fd_rtl.CAN_FD_frame_format.all; 
    90:    
    91:   entity priority_decoder is 
    92:       generic ( 
    93:           -- Number of TXT Buffers 
    94:           G_TXT_BUFFER_COUNT     : natural range 2 to 8 
    95:       ); 
    96:       port ( 
    97:           ------------------------------------------------------------------------------------------- 
    98:           -- TXT Buffer information 
    99:           ------------------------------------------------------------------------------------------- 
   100:           -- TXT Buffer priority 
   101:           prio             : in  t_txt_bufs_priorities(G_TXT_BUFFER_COUNT - 1 downto 0); 
   102:    
   103:           -- TXT Buffer is valid for selection 
   104:           prio_valid       : in  std_logic_vector(G_TXT_BUFFER_COUNT - 1 downto 0); 
   105:    
   106:           ------------------------------------------------------------------------------------------- 
   107:           -- Output interface 
   108:           ------------------------------------------------------------------------------------------- 
   109:           -- Whether selected buffer is valid (at least one buffer must be non-empty and allowed) 
   110:           output_valid     : out  std_logic; 
   111:    
   112:           -- Index of highest priority buffer which is non-empty and allowed for transmission 
   113:           output_index     : out  natural range 0 to G_TXT_BUFFER_COUNT - 1 
   114:       ); 
   115:   end entity; 
   116:    
   117:   architecture rtl of priority_decoder is 
   118:    
   119:       ----------------------------------------------------------------------------------------------- 
   120:       -- Level 0 aliases for input signals to provide variable signal width 
   121:       ----------------------------------------------------------------------------------------------- 
   122:       type level0_priority_type  is array (7 downto 0) of 
   123:             std_logic_vector(2 downto 0); 
   124:       signal l0_prio        : level0_priority_type; 
   125:       signal l0_valid       : std_logic_vector(7 downto 0); 
   126:    
   127:    
   128:       ----------------------------------------------------------------------------------------------- 
   129:       -- Level 1 priorities and valid indicators 
   130:       ----------------------------------------------------------------------------------------------- 
   131:       type level1_priority_type  is array (3 downto 0) of 
   132:             std_logic_vector(2 downto 0); 
   133:       type level1_comp_valid_type is array (3 downto 0) of 
   134:             std_logic_vector(1 downto 0); 
   135:       signal l1_prio        : level1_priority_type; 
   136:       signal l1_valid       : std_logic_vector(3 downto 0); 
   137:       signal l1_winner      : std_logic_vector(3 downto 0); 
   138:    
   139:    
   140:       ----------------------------------------------------------------------------------------------- 
   141:       -- Level 2 priorities and valid indicators 
   142:       ----------------------------------------------------------------------------------------------- 
   143:       type level2_priority_type  is array (1 downto 0) of 
   144:             std_logic_vector(2 downto 0); 
   145:       type level2_comp_valid_type is array (1 downto 0) of 
   146:             std_logic_vector(1 downto 0); 
   147:       signal l2_prio        : level2_priority_type; 
   148:       signal l2_valid       : std_logic_vector(1 downto 0); 
   149:       signal l2_winner      : std_logic_vector(1 downto 0); 
   150:    
   151:       ----------------------------------------------------------------------------------------------- 
   152:       -- Level 3, we dont need the priorities, we only need the outcome which of them is bigger 
   153:       -- (since there is no next stage) 
   154:       ----------------------------------------------------------------------------------------------- 
   155:       signal l3_valid       : std_logic; 
   156:       signal l3_winner      : std_logic; 
   157:    
   158:       constant LOWER_TREE   : std_logic := '0'; 
   159:       constant UPPER_TREE   : std_logic := '1'; 
   160:    
   161:   begin 
   162:    
   163:       ----------------------------------------------------------------------------------------------- 
   164:       -- Level 0 - aliases 
   165:       ----------------------------------------------------------------------------------------------- 
   166:       l0_gen : for i in 0 to G_TXT_BUFFER_COUNT - 1 generate 
   167:    
   168:           -- pragma translate_off 
   169:           -- coverage off 
   170:    
   171:           -- Since we cover "00" as inactive value, instead of active values 
   172:           -- "01", "10" or "11", rather make sure that input values are defined 
   173:           l0_val_proc : process(prio_valid(i)) 
   174:           begin 
   175:               if (prio_valid(i) /= '0' and prio_valid(i) /= '1' and now /= 0 fs) then 
   176:                   report "Input values not exactly defined" severity error; 
   177:               end if; 
   178:           end process; 
   179:    
   180:           -- coverage on 
   181:           -- pragma translate_on 
   182:    
   183:           l0_prio(i)  <= prio(i); 
   184:           l0_valid(i) <= prio_valid(i); 
   185:    
   186:       end generate; 
   187:    
   188:    
   189:       fill_zeroes_gen : if (G_TXT_BUFFER_COUNT < 8) generate 
   190:           l0_prio(7 downto G_TXT_BUFFER_COUNT)  <= (others => (others => '0')); 
   191:           l0_valid(7 downto G_TXT_BUFFER_COUNT) <= (others => '0'); 
   192:       end generate; 
   193:    
   194:    
   195:       ----------------------------------------------------------------------------------------------- 
   196:       -- Level 1 comparators 
   197:       ----------------------------------------------------------------------------------------------- 
   198:       l1_prio_dec_proc : process(l0_valid, l0_prio) 
   199:           variable tmp : level1_comp_valid_type; 
   200:       begin 
   201:           tmp := (others => (others => '0')); 
   202:           for i in 0 to 3 loop 
   203:               tmp(i) := l0_valid(2 * i + 1 downto 2 * i); 
   204:               case tmp(i) is 
   205:               when "01" => 
   206:                   l1_prio(i)      <= l0_prio(2 * i); 
   207:                   l1_valid(i)     <= '1'; 
   208:                   l1_winner(i)    <= LOWER_TREE; 
   209:    
   210:               when "10" => 
   211:                   l1_prio(i)      <= l0_prio(2 * i + 1); 
   212:                   l1_valid(i)     <= '1'; 
   213:                   l1_winner(i)    <= UPPER_TREE; 
   214:    
   215:               when "11" => 
   216:                   if (unsigned(l0_prio(2 * i + 1)) > unsigned(l0_prio(2 * i))) then 
   217:                       l1_prio(i)    <= l0_prio(2 * i + 1); 
   218:                       l1_winner(i)  <= UPPER_TREE; 
   219:                   else 
   220:                       l1_prio(i)    <= l0_prio(2 * i); 
   221:                       l1_winner(i)  <= LOWER_TREE; 
   222:                   end if; 
   223:                   l1_valid(i)     <= '1'; 
   224:    
   225:               when others => 
   226:                   l1_valid(i)     <= '0'; 
   227:                   l1_prio(i)      <= l0_prio(2 * i + 1); 
   228:                   l1_winner(i)    <= UPPER_TREE; 
   229:    
   230:               end case; 
   231:           end loop; 
   232:       end process; 
   233:    
   234:    
   235:       ----------------------------------------------------------------------------------------------- 
   236:       -- Level 2 comparators 
   237:       ----------------------------------------------------------------------------------------------- 
   238:       l2_prio_dec_proc : process(l1_valid, l1_prio) 
   239:           variable tmp : level2_comp_valid_type; 
   240:       begin 
   241:           tmp := (others => (others => '0')); 
   242:           for i in 0 to 1 loop 
   243:               tmp(i) := l1_valid(2 * i + 1 downto 2 * i); 
   244:    
   245:               case tmp(i) is 
   246:               when "01" => 
   247:                   l2_prio(i)      <= l1_prio(2 * i); 
   248:                   l2_valid(i)     <= '1'; 
   249:                   l2_winner(i)    <= LOWER_TREE; 
   250:    
   251:               when "10" => 
   252:                   l2_prio(i)      <= l1_prio(2 * i + 1); 
   253:                   l2_valid(i)     <= '1'; 
   254:                   l2_winner(i)    <= UPPER_TREE; 
   255:    
   256:               when "11" => 
   257:                   if (unsigned(l1_prio(2 * i + 1)) > unsigned(l1_prio(2 * i))) then 
   258:                       l2_prio(i)    <= l1_prio(2 * i + 1); 
   259:                       l2_winner(i)  <= UPPER_TREE; 
   260:                   else 
   261:                       l2_prio(i)    <= l1_prio(2 * i); 
   262:                       l2_winner(i)  <= LOWER_TREE; 
   263:                   end if; 
   264:                   l2_valid(i)     <= '1'; 
   265:    
   266:               when others => 
   267:                   l2_valid(i)     <= '0'; 
   268:                   l2_prio(i)      <= l1_prio(2 * i + 1); 
   269:                   l2_winner(i)    <= UPPER_TREE; 
   270:    
   271:               end case; 
   272:           end loop; 
   273:       end process; 
   274:    
   275:    
   276:       ----------------------------------------------------------------------------------------------- 
   277:       -- Level 3 comparators 
   278:       ----------------------------------------------------------------------------------------------- 
   279:    
   280:       -- Here we have only one comparator, plus we dont need 
   281:       -- the priority on the output... 
   282:    
   283:       -- Validity of level 3 is also the output validity 
   284:       l3_valid  <= '0' when l2_valid(1 downto 0) = "00" 
   285:                        else 
   286:                   '1'; 
   287:       output_valid <= '1' when l3_valid = '1' else '0'; 
   288:    
   289:       -- Priority comparator of level 3 
   290:       l3_winner  <= LOWER_TREE when l2_valid(1 downto 0) = "01" else 
   291:                     UPPER_TREE when l2_valid(1 downto 0) = "10" else 
   292:                     UPPER_TREE when (l2_valid(1 downto 0) = "11" and 
   293:                                    unsigned(l2_prio(1)) > unsigned(l2_prio(0))) 
   294:                                else 
   295:                     LOWER_TREE; 
   296:    
   297:       ----------------------------------------------------------------------------------------------- 
   298:       -- Output index decoder 
   299:       ----------------------------------------------------------------------------------------------- 
   300:       -- Just find out the winning buffer index from decisions in the tree 
   301:    
   302:       -- Note that modulo is used only for purpose of getting rid of compiler warnings. If lower 
   303:       -- amount of buffers is on input (TXT_BUFFER_COUNT), then higher indices of input priorities 
   304:       -- and valid sinals are set to 0. This leads to the case that "buf_index" will NEVER be 
   305:       -- assigned value higher than its available range. 
   306:    
   307:       out_index_proc : process(l3_winner, l2_winner, l1_winner) 
   308:       begin 
   309:           if (l3_winner = LOWER_TREE) then 
   310:               if (l2_winner(0) = LOWER_TREE) then 
   311:                   if (l1_winner(0) = LOWER_TREE) then 
   312:                       output_index <= 0; 
   313:                   else 
   314:                       output_index <= 1; 
   315:                   end if; 
   316:               else 
   317:                   if (l1_winner(1) = LOWER_TREE) then 
   318:                       output_index <= 2 mod G_TXT_BUFFER_COUNT; 
   319:                   else 
   320:                       output_index <= 3 mod G_TXT_BUFFER_COUNT; 
   321:                   end if; 
   322:               end if; 
   323:           else 
   324:               if (l2_winner(1) = LOWER_TREE) then 
   325:                   if (l1_winner(2) = LOWER_TREE) then 
   326:                       output_index <= 4 mod G_TXT_BUFFER_COUNT; 
   327:                   else 
   328:                       output_index <= 5 mod G_TXT_BUFFER_COUNT; 
   329:                   end if; 
   330:               else 
   331:                   if (l1_winner(3) = LOWER_TREE) then 
   332:                       output_index <= 6 mod G_TXT_BUFFER_COUNT; 
   333:                   else 
   334:                       output_index <= 7 mod G_TXT_BUFFER_COUNT; 
   335:                   end if; 
   336:               end if; 
   337:           end if; 
   338:       end process; 
   339:    
   340:   end architecture;