NVC code coverage report

File:  ../../Sources/A15_A16_encode_run.vhd

     0:   ---------------------------------------------------------------------------------- 
     1:   -- Engineer:    Vitor Mendes Camilo 
     2:   -- 
     3:   -- Module Name: A15_A16_encode_run - Behavioral 
     4:   -- Description: Code segments A.15 and A.16 — run-segment encoding. 
     5:   -- 
     6:   --              Mealy FSM: outputs are combinational from A14's current outputs 
     7:   --              and registered state. A14 is connected combinationally (no 
     8:   --              register between A14 and this stage). 
     9:   -- 
    10:   --              sNextBound: cumulative pixel count at which the next A15 '1' bit 
    11:   --              fires. Initialized to 2^J[RUNindex] at run start; advances by 
    12:   --              2^J[RUNindex+1] on each boundary hit. 
    13:   -- 
    14:   --              Each cycle when iRunHit='1': 
    15:   --                if iRunCnt == sNextBound → emit A15 '1' (oA15Valid). 
    16:   --              When run ends (iRunContinue='0'): 
    17:   --                EOLine, residual > 0: emit A16 '1' bit (only if no boundary hit). 
    18:   --                Break (iRunHit='0'): emit RI token with A16 prefix. Covers 
    19:   --                both breaks after one or more matches (sInRun='1') and the 
    20:   --                immediate-break case on the first pixel of run mode 
    21:   --                (sInRun='0', RUNcnt=0 → single '0' bit + RI). 
    22:   -- 
    23:   --              RUNindex persists across runs within a scan; resets at iEoi. 
    24:   ---------------------------------------------------------------------------------- 
    25:    
    26:   library ieee; 
    27:     use ieee.std_logic_1164.all; 
    28:     use ieee.numeric_std.all; 
    29:     use work.openjls_pkg.all; 
    30:    
    31:   entity a15_a16_encode_run is 
    32:     generic ( 
    33:       BITNESS       : natural := CO_BITNESS_STD; 
    34:       RUN_CNT_WIDTH : natural := 16 
    35:     ); 
    36:     port ( 
    37:       iClk          : in    std_logic; 
    38:       iRst          : in    std_logic; 
    39:       iCE           : in    std_logic; 
    40:       iEoi          : in    std_logic; 
    41:    
    42:       -- From A14 (combinational — no register between A14 and this stage) 
    43:       iRunCnt       : in    unsigned(RUN_CNT_WIDTH - 1 downto 0); -- A14 oRunCnt 
    44:       iRunHit       : in    std_logic;                            -- A14 oRunHit 
    45:       iRunContinue  : in    std_logic;                            -- A14 oRunContinue 
    46:    
    47:       -- Mode gate: only process when pipeline is in run mode 
    48:       iModeIsRun    : in    std_logic; 
    49:    
    50:       -- Pixel data for RI token (valid on break cycle) 
    51:       iIx           : in    unsigned(BITNESS - 1 downto 0); 
    52:       iRa           : in    unsigned(BITNESS - 1 downto 0); 
    53:       iRb           : in    unsigned(BITNESS - 1 downto 0); 
    54:    
    55:       -- Raw bit token: A15 '1' bits (SuffixLen=1, SuffixVal=1) and 
    56:       --               A16 break prefix (SuffixLen=J+1, SuffixVal=residual). 
    57:       --               oRiValid may be asserted simultaneously on break. 
    58:       oRawValid     : out   std_logic; 
    59:       oRawSuffixLen : out   unsigned(4 downto 0); 
    60:       oRawSuffixVal : out   unsigned(RUN_CNT_WIDTH - 1 downto 0); 
    61:    
    62:       -- Run-interruption token (break case only); carries Ix/Ra/Rb for Golomb path. 
    63:       -- oRiRunIndex is RUNindex before the A.16 decrement, used by A.22.1 to 
    64:       -- compute glimit = LIMIT - J[RUNindex] - 1. 
    65:       oRiValid      : out   std_logic; 
    66:       oRiIx         : out   unsigned(BITNESS - 1 downto 0); 
    67:       oRiRa         : out   unsigned(BITNESS - 1 downto 0); 
    68:       oRiRb         : out   unsigned(BITNESS - 1 downto 0); 
    69:       oRiRunIndex   : out   unsigned(4 downto 0); 
    70:       oInRunNext    : out   std_logic                             -- Tells top level we are mid-run 
    71:     ); 
    72:   end entity a15_a16_encode_run; 
    73:    
    74:   architecture behavioral of a15_a16_encode_run is 
    75:    
    76:     constant C_BOUND_WIDTH : natural := RUN_CNT_WIDTH + 1; 
    77:    
    78:     -- Registered state 
    79:     signal sRunIndex       : unsigned(4 downto 0); 
    80:     signal sNextBound      : unsigned(C_BOUND_WIDTH - 1 downto 0); 
    81:     signal sInRun          : std_logic; 
    82:    
    83:     -- Next-state signals (driven combinationally, captured by clocked process) 
    84:     signal sRunIndexNext   : unsigned(4 downto 0); 
    85:     signal sNextBoundNext  : unsigned(C_BOUND_WIDTH - 1 downto 0); 
    86:     signal sInRunNext      : std_logic; 
    87:    
    88:   begin 
    89:    
    90:     -- Contract assertions in PSL (active in NVC sims via --psl, plain comments 
    91:     -- to synthesis): run state and RUNindex must clear one cycle after iEoi 
    92:     -- (T.87: RUNindex persists across runs within a scan only); tokens only 
    93:     -- fire in run mode. 
    94:     -- psl default clock is rising_edge(iClk); 
    95:     -- psl assert always ((iRst = '1' or iEoi = '1') -> next (sInRun = '0' and sRunIndex = 0)) report "a15_a16: run state must clear one cycle after iEoi/reset"; 
    96:     -- psl assert always (iModeIsRun = '0' -> (oRawValid = '0' and oRiValid = '0')) report "a15_a16: no tokens outside run mode"; 
    97:    
    98:     -- ── Combinational: outputs and next-state ───────────────────────────────── 
    99:     p_comb : process (sRunIndex, sNextBound, sInRun, 
   100:                       iRunCnt, iRunHit, iRunContinue, iModeIsRun, iEoi, iRst, 
   101:                       iIx, iRa, iRb) is 
   102:    
   103:       variable vJ        : natural; 
   104:       variable vJNext    : natural; 
   105:       variable vStep     : unsigned(C_BOUND_WIDTH - 1 downto 0); 
   106:       variable vStepNext : unsigned(C_BOUND_WIDTH - 1 downto 0); 
   107:       variable vBoundHit : boolean; 
   108:       variable vNewIndex : unsigned(4 downto 0); 
   109:    
   110:     begin 
   111:    
   112:       -- Output defaults 
   113:       oRawValid     <= '0'; 
   114:       oRawSuffixLen <= to_unsigned(1, 5); 
   115:       oRawSuffixVal <= to_unsigned(1, RUN_CNT_WIDTH); 
   116:       oRiValid      <= '0'; 
   117:       oRiIx         <= iIx; 
   118:       oRiRa         <= iRa; 
   119:       oRiRb         <= iRb; 
   120:       oRiRunIndex   <= sRunIndex; 
   121:    
   122:       -- Next-state defaults: hold current 
   123:       sRunIndexNext  <= sRunIndex; 
   124:       sNextBoundNext <= sNextBound; 
   125:       sInRunNext     <= sInRun; 
   126:    
   127:       if (iModeIsRun = '1' and iRst = '0') then 
   128:         vJ    := CO_J_TABLE(to_integer(sRunIndex)); 
   129:         vStep := shift_left(to_unsigned(1, C_BOUND_WIDTH), vJ); 
   130:         if (sRunIndex < 31) then 
   131:           vJNext := CO_J_TABLE(to_integer(sRunIndex) + 1); 
   132:         else 
   133:           vJNext := CO_J_TABLE(31); 
   134:         end if; 
   135:         vStepNext := shift_left(to_unsigned(1, C_BOUND_WIDTH), vJNext); 
   136:    
   137:         if (iRunHit = '1') then 
   138:           -- ── A.15: matching pixel ─────────────────────────────────────────── 
   139:           vBoundHit := resize(iRunCnt, C_BOUND_WIDTH) = sNextBound; 
   140:           vNewIndex := sRunIndex; 
   141:    
   142:           if (vBoundHit) then 
   143:             oRawValid <= '1'; 
   144:             if (sRunIndex < 31) then 
   145:               vNewIndex := sRunIndex + 1; 
   146:             end if; 
   147:           end if; 
   148:    
   149:           sInRunNext <= '1'; 
   150:    
   151:           if (iRunContinue = '0') then 
   152:             -- EOLine 
   153:             sInRunNext <= '0'; 
   154:             if (not vBoundHit and iRunCnt > 0) then 
   155:               oRawValid <= '1'; -- A16 EOLine '1' bit 
   156:             end if; 
   157:             sRunIndexNext  <= vNewIndex; 
   158:             sNextBoundNext <= shift_left(to_unsigned(1, C_BOUND_WIDTH), 
   159:                                          CO_J_TABLE(to_integer(vNewIndex))); 
   160:           else 
   161:             -- Run continues 
   162:             sRunIndexNext <= vNewIndex; 
   163:             if (vBoundHit) then 
   164:               sNextBoundNext <= sNextBound + vStepNext; 
   165:             end if; 
   166:           end if; 
   167:         else 
   168:           -- ── A.16: break (iRunHit='0') ───────────────────────────────────── 
   169:           -- Covers both break-after-matches (sInRun='1') and immediate break on 
   170:           -- the first pixel of run mode (sInRun='0', RUNcnt=0). 
   171:           -- residual = iRunCnt - (sNextBound - vStep) = count since last boundary 
   172:           -- (for immediate break: iRunCnt=0, sNextBound=1, vStep=1 → residual=0, 
   173:           --  SuffixLen = J[0]+1 = 1 → single '0' break marker). 
   174:           oRawValid     <= '1'; 
   175:           oRawSuffixLen <= to_unsigned(vJ + 1, 5); 
   176:           oRawSuffixVal <= iRunCnt - resize(sNextBound - vStep, RUN_CNT_WIDTH); 
   177:           oRiValid      <= '1'; 
   178:           oRiIx         <= iIx; 
   179:           oRiRa         <= iRa; 
   180:           oRiRb         <= iRb; 
   181:    
   182:           if (sRunIndex > 0) then 
   183:             vNewIndex := sRunIndex - 1; 
   184:           else 
   185:             vNewIndex := (others => '0'); 
   186:           end if; 
   187:    
   188:           sInRunNext     <= '0'; 
   189:           sRunIndexNext  <= vNewIndex; 
   190:           sNextBoundNext <= shift_left(to_unsigned(1, C_BOUND_WIDTH), 
   191:                                        CO_J_TABLE(to_integer(vNewIndex))); 
   192:         end if; 
   193:       end if; 
   194:    
   195:     end process p_comb; 
   196:    
   197:     oInRunNext <= sInRunNext; 
   198:    
   199:     -- ── Clocked: state registers ────────────────────────────────────────────── 
   200:     p_state_reg : process (iClk) is 
   201:     begin 
   202:    
   203:       if rising_edge(iClk) then 
   204:         if (iRst = '1' or iEoi = '1') then 
   205:           sRunIndex  <= (others => '0'); 
   206:           sNextBound <= to_unsigned(1, C_BOUND_WIDTH); 
   207:           sInRun     <= '0'; 
   208:         elsif (iCE = '1') then 
   209:           sRunIndex  <= sRunIndexNext; 
   210:           sNextBound <= sNextBoundNext; 
   211:           sInRun     <= sInRunNext; 
   212:         end if; 
   213:       end if; 
   214:    
   215:     end process p_state_reg; 
   216:    
   217:   end architecture behavioral;