⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sobel.vhd

📁 这是本人自己编写的可用于256*256大小的图像进行sobel边缘检测的vhd文件
💻 VHD
📖 第 1 页 / 共 2 页
字号:
   --This VHDL file(IP Core) realizes the function of 
   --image(bitmap 256x256) edge detection by Sobel arithmetic.
   --data:2000.11.20
    library IEEE;
    use ieee.std_logic_1164.all;

     package image is
     subtype pixel is integer range -1024 to 1024;
     end image;
   
   Library IEEE;
      USE IEEE.STD_LOGIC_1164.ALL;
      USE IEEE.STD_LOGIC_UNSIGNED.ALL;
      USE IEEE.STD_LOGIC_ARITH.ALL;
      USE work.image.all;
    --端口定义
    Entity sobel IS 
       PORT(                     
              en    : IN STD_LOGIC; 				--输入使能
              clk   : IN STD_LOGIC; 				--时钟
              i_in  : IN STD_LOGIC_VECTOR(7 DOWNTO 0);		--数据输入
              i_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)		--数据输出
              );

      END sobel;
      
    --内部行为逻辑定义
    Architecture behave OF sobel IS 
     signal ram_data1 : STD_LOGIC_VECTOR (7 DOWNTO 0);		--内部双口ram1的数据输入
     signal ram_data2 : STD_LOGIC_VECTOR (7 DOWNTO 0);		--内部双口ram2的数据输入
     signal ram_data3 : STD_LOGIC_VECTOR (7 DOWNTO 0);		--内部双口ram3的数据输入
     
     signal ram_q1 : STD_LOGIC_VECTOR (7 DOWNTO 0);		--内部双口ram1的数据输出
     signal ram_q2 : STD_LOGIC_VECTOR (7 DOWNTO 0);		--内部双口ram2的数据输出
     signal ram_q3 : STD_LOGIC_VECTOR (7 DOWNTO 0);		--内部双口ram3的数据输出
     
     signal ram_wadd1 : STD_LOGIC_VECTOR (8 DOWNTO 0);		--写内部双口ram1的地址
     signal ram_wadd2 : STD_LOGIC_VECTOR (8 DOWNTO 0);		--写内部双口ram2的地址
     signal ram_wadd3 : STD_LOGIC_VECTOR (8 DOWNTO 0);		--写内部双口ram3的地址
     
     signal ram_radd  : STD_LOGIC_VECTOR (8 DOWNTO 0);		--读内部双口ram的地址(公用同一地址信号)
     
     signal ram_wren1  : std_logic;				--内部双口ram1写使能信号
     signal ram_wren2  : std_logic;				--内部双口ram2写使能信号
     signal ram_wren3  : std_logic;				--内部双口ram3写使能信号
     
     signal nreset  : std_logic;				--内部双口ram复位信号(由外部reset控制)
     
     signal ram_in_sc_tmp       : std_logic_vector(10 downto 0);		--内部ram片选信号
     
     signal x11        : pixel;			--缓存模板矩阵X(3,3)数据
     signal x12        : pixel;			--..
     signal x13        : pixel;			--..
     signal x21        : pixel;			--..
     signal x22        : pixel;			--..
     signal x23        : pixel;			--..
     signal x31        : pixel;			--..
     signal x32        : pixel;			--..
     signal x33        : pixel;			--..
     
     signal sum1        : pixel;			--缓存一次减法运算结果
     signal sum2        : pixel;			--..
     signal sum3        : pixel;			--..
     signal sum4        : pixel;			--..
     
     signal comp_tmp1   :std_logic;		--缓存比较运算结果(0 or 1)
     signal comp_tmp2   :std_logic;             --..
     signal comp_tmp3   :std_logic;		--..
     signal comp_tmp4   :std_logic;		--..
     signal comp_tmp5   :std_logic;		--..
     

     signal Sum2x           : pixel;	--缓存自加结果
     signal Sum4x           : pixel;     --..
     
     signal Sum_SumX        : pixel;	--缓存一次加法运算结果
     signal Sum_SumY        : pixel;	--..
     
     signal X               : std_logic_vector(7 downto 0);	--缓存Y方向模板运算结果
     signal Y               : std_logic_vector(7 downto 0);     --缓存X方向模板运算结果
     
     signal add_result      : std_logic_vector(7 downto 0);	--(X+Y)加法器运算输出
     signal add_cout        : std_logic;                        --加法运算进位标志
     
     signal i_out_tmp      : std_logic_vector(7 downto 0);      --一次模板运算结果
     
     --外部定义双口ram
     component ram512x8
     PORT
   (
		data		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		wraddress		: IN STD_LOGIC_VECTOR (8 DOWNTO 0);
		rdaddress		: IN STD_LOGIC_VECTOR (8 DOWNTO 0);
		wren		: IN STD_LOGIC  := '1';
		rden		: IN STD_LOGIC  := '1';
		clock		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
	 );
     end component;
     
     --外部定义带进位标志的8位加法器
     component addc 
     PORT                                                                     
	(
		dataa		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		datab		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		result		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
		cout		: OUT STD_LOGIC 
	);
     end component;
                  
     BEGIN
     
     --应用到3个双口RAM,分别存放3行相邻的图象数据
     --新的图像数据存入并覆盖掉不再使用的数据,已达到循环使用目的
     --RAM的读写时钟一致。
     ram1 : ram512x8 port map 
            (
              ram_data1,
              ram_wadd1,
              ram_radd,
              ram_wren1,
              nreset,
              clk,
              ram_q1
            );
     ram2 : ram512x8 port map 
            (
              ram_data2,
              ram_wadd2,
              ram_radd,
              ram_wren2,
              nreset,
              clk,
              ram_q2
            );
     ram3 : ram512x8 port map 
            (
              ram_data3,
              ram_wadd3,
              ram_radd,
              ram_wren3,
              nreset,
              clk,
              ram_q3
            ); 
            
     --应用待进位的加法器,可实现加法与比较功能(加法运算结果与255比较)
     --该图像边缘检测的阈值为255。
     add   : addc port map
            (
              X,
              Y,
              add_result,
              add_cout
             );  
             
     --并行信号
     ram_data1<=i_in;
     ram_data2<=i_in;
     ram_data3<=i_in;
     nreset<=not en;
   
     i_out<=i_out_tmp;
    
    --控制读外部RAM地址计数  
    --process(clk,en)                       
    --begin
    --  if en='1'  then
    --    ram_in_addr_tmp<=(others=>'0');
    --  elsif clk'event and clk='1' then
    --    ram_in_addr_tmp<=ram_in_addr_tmp+1;
    --  end if;         
    --end process;
    
    --控制片选计数信号
    --计满三行数据时,复位片选计数信号,再下一个时钟来时,开始重新计数
    --经过测试复位片选信号好像没有问题
    process(clk,en)                       
    begin
      if en='1'   then
        ram_in_sc_tmp<=(others=>'0');
      elsif clk'event and clk='1' then
        if ram_in_sc_tmp="10000011111" then 	--三行图像象素个数768
           ram_in_sc_tmp<=(others=>'0');   	
        else ram_in_sc_tmp<=ram_in_sc_tmp+1;
        end if;
      end if;         
    end process; 
    
    --控制3个内部ram的写使能信号,保证某一时刻仅有一片ram可写
    --经过测试RAM写使能信号好像没有问题
    process(clk,en)   
    begin
      if en='1' then
        ram_wren1<='0';
        ram_wren2<='0';
        ram_wren3<='0'; 
      elsif clk'event and clk='1' then
       if   ram_in_sc_tmp="00000000000"  then
        ram_wren1<='1';
        ram_wren3<='0';
       elsif ram_in_sc_tmp="00101100000" then
        ram_wren1<='0'; 
        ram_wren2<='1';
       elsif ram_in_sc_tmp="01011000000"  then
        ram_wren2<='0';
        ram_wren3<='1';   
       end if; 
      end if;        
    end process;
    
    --控制写外部RAM地址计数信号
    --process(clk,en)
    --begin
    --  if en='1' then
    --    ram_out_addr_tmp<=(others=>'0');
    --  elsif clk'event and clk='1' then
    --    ram_out_addr_tmp<=ram_out_addr_tmp+1;
    --  end if;         
    --end process;
    
    --控制写内部ram1的地址信号计数信号
    --经过测试RAM1地址信号好像没有问题
    process(clk,ram_wren1) 
    begin
      if ram_wren1='0' then
        ram_wadd1<=(others=>'0');
      elsif clk'event and clk='1' then
        ram_wadd1<=ram_wadd1+1;
      end if;         
    end process;
    
     --控制写内部ram2的地址信号计数信号
     --经过测试RAM2地址信号好像没有问题
    process(clk,ram_wren2)                       
    begin
      if ram_wren2='0' then
        ram_wadd2<=(others=>'0');
      elsif clk'event and clk='1' then
        ram_wadd2<=ram_wadd2+1;
      end if;         
    end process;
    
     --控制写内部ram3的地址信号计数信号
     --经过测试RAM3地址信号好像没有问题
    process(clk,ram_wren3)                       
    begin
      if ram_wren3='0' then
        ram_wadd3<=(others=>'0');
      elsif clk'event and clk='1' then
        ram_wadd3<=ram_wadd3+1;
      end if;         
    end process;
    
    --控制从内部ram中读数据的地址信号
    --经过测试内部RAM的读信号地址好像没有问题,比写信号要晚一个时钟
    process(clk,en)
    begin
      if en='1' then
        ram_radd<=(others=>'0');
      elsif clk'event and clk='1' then
        if ram_wren1='1' then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -