NVC code coverage report

File:  ../../Sources/line_buffer.vhd

     0:   ---------------------------------------------------------------------------------- 
     1:   -- Engineer:    Vitor Mendes Camilo 
     2:   -- 
     3:   -- Module Name: line_buffer - Behavioral 
     4:   -- 
     5:   -- Notes: 
     6:   --              Stores one row of pixels on FIFO and provides the four T.87 causal 
     7:   --              context neighbors for each pixel, where x is the current pixel: 
     8:   -- 
     9:   --                  c  b  d 
    10:   --                  a  x 
    11:   -- 
    12:   --              a = left neighbor        (same row, col-1) 
    13:   --              b = upper neighbor       (previous row, col) 
    14:   --              c = upper-left neighbor  (previous row, col-1) 
    15:   --              d = upper-right neighbor (previous row, col+1) 
    16:   -- 
    17:   --              Border conditions (T.87 A.2.1): 
    18:   --                First row      : b = c = d = 0 
    19:   --                Col 0 (rows>0) : a = Rb = first pixel of previous row 
    20:   --                                 c = Ra from start of previous row 
    21:   --                                   = first pixel of the row before that 
    22:   --                Col W-1        : d = b (replicate last pixel of previous row) 
    23:   -- 
    24:   -- Assumptions: 
    25:   --              iImageWidth >= 3, iImageHeight >= 1. 
    26:   --              iImageWidth and iImageHeight are stable for the entire image. 
    27:   -- 
    28:   ---------------------------------------------------------------------------------- 
    29:    
    30:   library ieee; 
    31:     use ieee.std_logic_1164.all; 
    32:     use ieee.numeric_std.all; 
    33:     use work.openjls_pkg.all; 
    34:    
    35:   library work; 
    36:     use work.olo_base_pkg_math.log2ceil; 
    37:    
    38:   entity line_buffer is 
    39:     generic ( 
    40:       MAX_IMAGE_WIDTH  : positive range 3 to integer'high; 
    41:       MAX_IMAGE_HEIGHT : positive; 
    42:       BITNESS          : natural := CO_BITNESS_STD 
    43:     ); 
    44:     port ( 
    45:       iClk             : in    std_logic; 
    46:       iRst             : in    std_logic; 
    47:       iImageWidth      : in    unsigned(log2ceil(MAX_IMAGE_WIDTH + 1) - 1 downto 0); 
    48:       iImageHeight     : in    unsigned(log2ceil(MAX_IMAGE_HEIGHT + 1) - 1 downto 0); 
    49:       iValid           : in    std_logic; 
    50:       iPixel           : in    unsigned(BITNESS - 1 downto 0); 
    51:       oA               : out   unsigned(BITNESS - 1 downto 0); 
    52:       oB               : out   unsigned(BITNESS - 1 downto 0); 
    53:       oC               : out   unsigned(BITNESS - 1 downto 0); 
    54:       oD               : out   unsigned(BITNESS - 1 downto 0); 
    55:       oValid           : out   std_logic; 
    56:       oEol             : out   std_logic; -- end of line 
    57:       oEoi             : out   std_logic  -- end of image 
    58:     ); 
    59:   end entity line_buffer; 
    60:    
    61:   architecture behavioral of line_buffer is 
    62:    
    63:     constant COL_WIDTH         : natural := log2ceil(MAX_IMAGE_WIDTH + 1); 
    64:     constant ROW_WIDTH         : natural := log2ceil(MAX_IMAGE_HEIGHT + 1); 
    65:    
    66:     type fifo_state_t is (preload, wait_end_first_row, nominal); 
    67:    
    68:     signal sFifoState          : fifo_state_t; 
    69:    
    70:     signal sFifoOutReady       : std_logic; 
    71:     signal sFifoOutValid       : std_logic; 
    72:     signal sFifoOutData        : std_logic_vector(BITNESS - 1 downto 0); 
    73:     signal sFifoFull           : std_logic; 
    74:     signal sFifoEmpty          : std_logic; 
    75:     signal sD                  : unsigned(BITNESS - 1 downto 0); -- d: upper-right 
    76:     signal sB                  : unsigned(BITNESS - 1 downto 0); -- b: upper 
    77:     signal sC                  : unsigned(BITNESS - 1 downto 0); -- c: upper-left 
    78:     signal sA                  : unsigned(BITNESS - 1 downto 0); -- a: left 
    79:     signal sBorderC            : unsigned(BITNESS - 1 downto 0); -- c at col 0: sB captured at col 0 of previous row 
    80:     signal sColCounter         : unsigned(COL_WIDTH - 1 downto 0); 
    81:     signal sRowCounter         : unsigned(ROW_WIDTH - 1 downto 0); 
    82:     signal sIsLastCol          : boolean; 
    83:     signal sIsLastRow          : boolean; 
    84:     signal sIsEoi              : boolean; 
    85:     signal sIsEol              : boolean; 
    86:     signal sIsFifoOutHandshake : boolean; 
    87:     signal sIsFirstCol         : boolean; 
    88:     signal sPreloadCounter     : unsigned(1 downto 0); 
    89:     signal sFifoInValid        : std_logic; 
    90:    
    91:   begin 
    92:    
    93:     -- Combinatorial process ---------------------------------------------------------------- 
    94:     comb_proc : process (iValid, iImageWidth, iImageHeight, sFifoState, 
    95:                          sFifoOutReady, sFifoOutValid, sColCounter, sRowCounter, 
    96:                          sIsLastCol, sIsLastRow, sIsFirstCol, sIsEol, sIsEoi, 
    97:                          sA, sB, sC, sD, sBorderC) is 
    98:     begin 
    99:    
   100:       oValid              <= iValid; 
   101:       sIsLastCol          <= sColCounter = iImageWidth - 1; 
   102:       sIsLastRow          <= sRowCounter = iImageHeight - 1; 
   103:       sIsFirstCol         <= sColCounter = 0; 
   104:       sIsEol              <= sIsLastCol and iValid = '1'; 
   105:       sIsEoi              <= sIsLastCol and sIsLastRow and iValid = '1'; 
   106:       oEoi                <= bool2bit(sIsEoi); 
   107:       oEol                <= bool2bit(sIsEol); 
   108:       sIsFifoOutHandshake <= (sFifoOutReady and sFifoOutValid) = '1'; 
   109:    
   110:       -- Read FIFO logic ------------------------------------------------------ 
   111:       if (sFifoState = preload) then 
   112:         sFifoOutReady <= '1'; 
   113:       elsif (sFifoState = nominal) then 
   114:         sFifoOutReady <= iValid; 
   115:       else 
   116:         sFifoOutReady <= '0'; 
   117:       end if; 
   118:    
   119:       -- Corner case handling for border conditions (T.87 A.2.1) -------------- 
   120:       if (sRowCounter = 0) then                                          -- First row: b = c = d = 0 
   121:         oB <= (others => '0'); 
   122:         oC <= (others => '0'); 
   123:         oD <= (others => '0'); 
   124:       else 
   125:         oB <= sB; 
   126:         if (sIsFirstCol) then 
   127:           oC <= sBorderC;                                                -- Col 0: c = Ra from start of previous row 
   128:         else 
   129:           oC <= sC; 
   130:         end if; 
   131:    
   132:         if (sIsLastCol) then 
   133:           oD <= sB;                                                      -- Last col: replicate last pixel of previous row (= b) 
   134:         else 
   135:           oD <= sD; 
   136:         end if; 
   137:       end if; 
   138:    
   139:       if (sIsFirstCol) then 
   140:         oA <= sB;                                                        -- First col: replicate first pixel of previous row (= b) 
   141:       else 
   142:         oA <= sA; 
   143:       end if; 
   144:    
   145:     end process comb_proc; ---------------------------------------------------------------------------- 
   146:    
   147:     -- Clocked Process ---------------------------------------------------------------------- 
   148:     clocked_proc : process (iClk) is 
   149:     begin 
   150:    
   151:       if rising_edge(iClk) then 
   152:         if (iRst = '1') then 
   153:           sPreloadCounter <= (others => '0'); 
   154:           sFifoState      <= preload; 
   155:    
   156:           sColCounter <= (others => '0'); 
   157:           sRowCounter <= (others => '0'); 
   158:    
   159:           sB       <= (others => '0'); 
   160:           sC       <= (others => '0'); 
   161:           sD       <= (others => '0'); 
   162:           sA       <= (others => '0'); 
   163:           sBorderC <= (others => '0'); 
   164:         else 
   165:           -- FIFO control FSM ---------------------------- 
   166:           -- sFifoOutReady is controlled combinationally using these states 
   167:           case sFifoState is 
   168:    
   169:             when preload => 
   170:    
   171:               -- When FIFO receives the first pixels it loads them into registers, preparing for nominal operation 
   172:               -- Only loads b and d, since c is out of image 
   173:    
   174:               if (sIsFifoOutHandshake) then 
   175:                 sPreloadCounter <= sPreloadCounter + 1; 
   176:                 if (sPreloadCounter = 1) then 
   177:                   sFifoState <= wait_end_first_row; 
   178:    
   179:                   if (sIsEol) then                           -- needs this check to work with images with width=4 (Annex H.3 test image) 
   180:                     sFifoState <= nominal; 
   181:                   end if; 
   182:                 end if; 
   183:               end if; 
   184:    
   185:             when wait_end_first_row => 
   186:    
   187:               -- Nominal operation starts only on second row, since first row has no valid context 
   188:               if (sIsEol) then 
   189:                 sFifoState <= nominal; 
   190:               end if; 
   191:    
   192:             when nominal => 
   193:    
   194:               -- On valid operation, every new pixel steps the context window by reading a new neighbor pixels and shifting the current ones 
   195:    
   196:               if (sIsEoi) then 
   197:                 sFifoState      <= preload; 
   198:                 sPreloadCounter <= (others => '0'); 
   199:               end if; 
   200:    
   201:           end case; 
   202:    
   203:           -- Counters ------------------------------------- 
   204:           if (iValid = '1') then 
   205:             if (sIsLastCol) then 
   206:               sColCounter <= (others => '0'); 
   207:               if (sIsLastRow) then 
   208:                 sRowCounter <= (others => '0'); 
   209:               else 
   210:                 sRowCounter <= sRowCounter + 1; 
   211:               end if; 
   212:             else 
   213:               sColCounter <= sColCounter + 1; 
   214:             end if; 
   215:           end if; 
   216:    
   217:           -- Output control ------------------------------- 
   218:           -- Shift context window 
   219:           if (sIsFifoOutHandshake) then 
   220:             sC <= sB; 
   221:             sB <= sD; 
   222:             sD <= unsigned(sFifoOutData); 
   223:           elsif (sFifoState = nominal and iValid = '1') then 
   224:             -- FIFO empty (last row, end of row): sD has no new data but sB/sC still step 
   225:             sC <= sB; 
   226:             sB <= sD; 
   227:           end if; 
   228:    
   229:           if (iValid = '1') then 
   230:             -- Store last pixel 
   231:             sA <= iPixel; 
   232:    
   233:             if (sIsFirstCol) then 
   234:               sBorderC <= sB;                                -- Capture sB at col 0 for use as c border at col 0 of next ro 
   235:             end if; 
   236:           end if; 
   237:    
   238:           if (sIsEoi) then 
   239:             sB       <= (others => '0'); 
   240:             sC       <= (others => '0'); 
   241:             sD       <= (others => '0'); 
   242:             sA       <= (others => '0'); 
   243:             sBorderC <= (others => '0'); 
   244:           end if; 
   245:         end if; 
   246:       end if; 
   247:    
   248:     end process clocked_proc; ----------------------------------------------------------------------------- 
   249:    
   250:     -- Instance FIFO ------------------------------------------------------------------------- 
   251:     sFifoInValid <= iValid and not bool2bit(sIsLastRow); 
   252:    
   253:     fifo_inst : entity work.olo_base_fifo_sync(rtl) 
   254:       generic map ( 
   255:         WIDTH_G       => BITNESS, 
   256:         DEPTH_G       => MAX_IMAGE_WIDTH, 
   257:         RAMBEHAVIOR_G => "RBW" 
   258:       ) 
   259:       port map ( 
   260:         Clk           => iClk, 
   261:         Rst           => iRst, 
   262:         In_Data       => std_logic_vector(iPixel), 
   263:         In_Valid      => sFifoInValid, 
   264:         Out_Ready     => sFifoOutReady, 
   265:         Out_Data      => sFifoOutData, 
   266:         Out_Valid     => sFifoOutValid, 
   267:         Full          => sFifoFull, 
   268:         Empty         => sFifoEmpty 
   269:       ); 
   270:    
   271:   end architecture behavioral;