------------------------------------------------------------------- -- -- Fichero: -- videoEdgeDetector.vhd 21/06/2023 -- -- (c) J.M. Mendias -- Diseño Automático de Sistemas -- Facultad de Informática. Universidad Complutense de Madrid -- -- Propósito: -- Configura una camara a traves del bus SBBC -- -- Notas de diseño: -- ------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity videoEdgeDetector is port ( -- host side clk : in std_logic; start : in std_logic; filterOn : in std_logic; sel : in std_logic; thold : in std_logic_vector (3 downto 0); -- frame buffers side y : out std_logic_vector (7 downto 0); x : out std_logic_vector (8 downto 0); dataIn : in std_logic_vector (3 downto 0); dataOut : out std_logic_vector (3 downto 0); dataRdy : out std_logic ); end videoEdgeDetector; --------------------------------------------------------------------- library ieee; use ieee.numeric_std.all; architecture syn of videoEdgeDetector is function max( a : signed; b : signed ) return signed is begin i... end function; function min( a : signed; b : signed ) return signed is begin ... end function; function multAdd( acc : signed; dataIn : std_logic_vector; coeff : integer ) return signed is variable result : signed (acc'range); begin result := ...; return result; end function; procedure mac( signal dataIn : in std_logic_vector; variable gx, gy : inout signed; constant xCoeff : integer; constant yCoeff : integer ) is begin gx := multAdd( gx, dataIn, xCoeff ); gy := multAdd( gy, dataIn, yCoeff ); end procedure; function sqrta( a : signed; b : signed ) return unsigned is variable maxab, minab : signed (a'range); variable result : unsigned (a'range); begin maxab := ...; minab := ...; result := ...; return result; end function; constant PIXELSxLINE : natural := 640/2; constant LINESxFRAME : natural := 480/2; type integerMatrix is array (-1 to 1, -1 to 1) of integer; constant xPrewitt : integerMatrix := ( ( +1, 0, -1 ), ( +1, 0, -1 ), ( +1, 0, -1 ) ); constant yPrewitt : integerMatrix := ( ( +1, +1, +1 ), ( 0, 0, 0 ), ( -1, -1, -1 ) ); constant xSobel : integerMatrix := ( ( -1, 0, +1 ), ( -2, 0, +2 ), ( -1, 0, +1 ) ); constant ySobel : integerMatrix := ( ( -1, -2, -1 ), ( 0, 0, 0 ), ( +1, +2, +1 ) ); signal xKernel : integerMatrix; signal yKernel : integerMatrix; begin xKernel <= xSobel when sel='1' else xPrewitt; yKernel <= ySobel when sel='1' else yPrewitt; process( clk ) variable state : natural range 0 to 12 := 0; variable xCnt : unsigned(8 downto 0) := (others => '0'); variable yCnt : unsigned(7 downto 0) := (others => '0'); variable gx, gy : signed (7 downto 0 ); variable g : unsigned (7 downto 0); begin if rising_edge(clk) then case state is when 0 => if start='1' then state := state+1; end if; when 1 => x <= std_logic_vector( xCnt - 1 ); y <= std_logic_vector( yCnt - 1 ); gx := ( others => '0' ); gy := ( others => '0' ); state := state+1; when 2 => x <= ...; y <= ...; mac( ... ); state := ...; ... when 11 => dataRdy <= '1'; if filterOn='1' then g := sqrta( ... ); if g <= unsigned( thold ) then dataOut <= (others => '0'); else dataOut <= std_logic_vector( g(3 downto 0) ); end if; else dataOut <= dataIn; end if; state := state+1; when 12 => dataRdy <= '0'; state := 1; xCnt := (xCnt + 1) mod PIXELSxLINE; if xCnt=0 then yCnt := (yCnt + 1) mod LINESxFRAME; if yCnt=0 then state := 0; end if; end if; end case; end if; end process; end syn;