@ -14,97 +14,100 @@ entity zero_counter is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				end entity zero_counter;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				architecture behaviour of zero_counter is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    zerocounter0: process(all)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable l32, r32 : std_ulogic;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable v32      : std_ulogic_vector(31 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable v16      : std_ulogic_vector(15 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable v8       : std_ulogic_vector(7 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable v4       : std_ulogic_vector(3 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        variable sel      : std_ulogic_vector(5 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        l32 := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        r32 := '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        v32 := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        v16 := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        v8  := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        v4  := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        sel := (others => '0');
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					l32 := or (rs(63 downto 32));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					r32 := or (rs(31 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if (l32 = '0' or is_32bit = '1') and r32 = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    -- operand is zero, return 32 for 32-bit, else 64
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    result <= x"00000000000000" & '0' & not is_32bit & is_32bit & "00000";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal y, z     : std_ulogic_vector(3 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal v16      : std_ulogic_vector(15 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal v4       : std_ulogic_vector(3 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    signal sel      : std_ulogic_vector(5 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if count_right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(5) := l32 and (not is_32bit);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Return the index of the leftmost or rightmost 1 in a set of 4 bits.
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    -- Assumes v is not "0000"; if it is, return (right ? "11" : "00").
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    function encoder(v: std_ulogic_vector(3 downto 0); right: std_ulogic) return std_ulogic_vector is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if v(3) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "11";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    elsif v(2) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "10";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    elsif v(1) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "01";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(5) := (not r32) and (not is_32bit);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "00";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if sel(5) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v32 := rs(63 downto 32);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if v(0) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "00";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    elsif v(1) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "01";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    elsif v(2) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "10";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v32 := rs(31 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						return "11";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    end;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if count_right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(4) := or (v32(31 downto 16));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(4) := not (or (v32(15 downto 0)));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if sel(4) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v16 := v32(31 downto 16);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v16 := v32(15 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    zerocounter0: process(all)
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    begin
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					-- Test 4 groups of 16 bits each.
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					-- The top 2 groups are considered to be zero in 32-bit mode.
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					z(0) <= or (rs(15 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					z(1) <= or (rs(31 downto 16));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					z(2) <= or (rs(47 downto 32));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					z(3) <= or (rs(63 downto 48));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        if is_32bit = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            sel(5 downto 4) <= encoder(z, count_right);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            sel(5) <= '0';
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            if count_right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                sel(4) <= z(1);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				                sel(4) <= not z(0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				            end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				        end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if count_right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(3) := or (v16(15 downto 8));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(3) := not (or (v16(7 downto 0)));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if sel(3) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v8 := v16(15 downto 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v8 := v16(7 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					-- Select the leftmost/rightmost non-zero group of 16 bits
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					case sel(5 downto 4) is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when "00" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v16 <= rs(15 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when "01" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v16 <= rs(31 downto 16);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when "10" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v16 <= rs(47 downto 32);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when others =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v16 <= rs(63 downto 48);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					end case;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if count_right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(2) := or (v8(7 downto 4));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						sel(2) := not (or (v8(3 downto 0)));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if sel(2) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v4 := v8(7 downto 4);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v4 := v8(3 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					-- Test 4 groups of 4 bits
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					y(0) <= or (v16(3 downto 0));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					y(1) <= or (v16(7 downto 4));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					y(2) <= or (v16(11 downto 8));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					y(3) <= or (v16(15 downto 12));
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					sel(3 downto 2) <= encoder(y, count_right);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    if count_right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if v4(3) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "11";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						elsif v4(2) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "10";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						elsif v4(1) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "01";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "00";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						result <= x"00000000000000" & "00" & (not sel(5) and not is_32bit) & not sel(4 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						if v4(0) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "00";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						elsif v4(1) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "01";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						elsif v4(2) = '1' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "10";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						    sel(1 downto 0) := "11";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						result <= x"00000000000000" & "00" & sel;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					-- Select the leftmost/rightmost non-zero group of 4 bits
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					case sel(3 downto 2) is
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when "00" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v4 <= v16(3 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when "01" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v4 <= v16(7 downto 4);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when "10" =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v4 <= v16(11 downto 8);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    when others =>
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
						v4 <= v16(15 downto 12);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					end case;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					sel(1 downto 0) <= encoder(v4, count_right);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					-- sel is now the index of the leftmost/rightmost 1 bit in rs
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					if v4 = "0000" then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    -- operand is zero, return 32 for 32-bit, else 64
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    result <= x"00000000000000" & '0' & not is_32bit & is_32bit & "00000";
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					elsif count_right = '0' then
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    -- return (63 - sel), trimmed to 5 bits in 32-bit mode
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    result <= x"00000000000000" & "00" & (not sel(5) and not is_32bit) & not sel(4 downto 0);
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					else
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					    result <= x"00000000000000" & "00" & sel;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
					end if;
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				
 
			
		 
		
	
		
			
				 
				 
			
			 
			 
			
				    end process;