图像边缘检测--SOBEL

1.SOBEL图像边缘检测器的设计

边缘可定义为图像中灰度发生急剧变化的区域边界,它是图像最基本的特征。边缘检测主要就是(图像的)灰度变化的度量、检测和定位,它是图像分析和模式识别的主要特征提取手段,它在计算机视觉、图像分析等应用中起着重要的作用,是图像分析与处理中研究的热点问题。在过去的20年里产生了许多边缘检测器,而Sobel算法只涉及加法操作,但却可以得到很好的划分效果,因而是图像处理系统中最常用的边缘检测算法

Sobel算法包括带4个3×3掩码的输入图像数据,即Sobel算子,它设置权重来检测水平、垂直、左对角、右对角各个不同方向上密度幅度的不同。这个过程通常被称为过滤。我们来看像素窗口(3×3),如图2所示。水平、垂直、左对角、右对角各图像方向上密度幅度的变化可以用如下算子进行计算:

Q0

Q3

Q6

Q1

[i,j]

Q7

Q2

Q5

Q8

H=(Q0+2Q3+Q6)-(Q2+2Q5+Q8);V=(Q0+2Q1+Q2)-(Q6+2Q7+Q8);

DR=(Q1+2Q0+Q3)-(Q5+2Q8+Q7);DL=(Q1+2Q2+Q5)-(Q3+2Q6+Q7);

H,V,DL,DR这四个参数用于计算梯度大小和方向。                 

对梯度大小的一个普遍估计值为:Magnitude=Max(H,V,DR,DL)。

我们通过对图像灰度作直方图分析后,便可以给出区分度阀值

Threshold,区分度阀值往往要借助一定的经验并需要反复调整。如果Magnitude大于Threshold,则该像素被声明为边界像素,否则为一般像素。

本课题就是要求使用LPM兆功能块设计和VHDL程序设计相结合的方式或全部采用VHDL程序设计方式,用FPGA/CPLD实现Sobel算法。

2 .  算法实现

    Sobel的滤波函数为:

    H=(Q0+2Q3+Q6)-(Q2+2Q5+Q8);

    V=(Q0+2Q1+Q2)-(Q6+2Q7+Q8);

    DR=(Q1+2Q0+Q3)-(Q5+2Q8+Q7);

    DL=(Q1+2Q2+Q5)-(Q3+2Q6+Q7);

    Magnitude=Max(H,V,DR,DL)

为了减少设计的复杂度,可将Sobel的滤波函数中的乘法运算可以改写成加法运算:

    H=(Q0+Q3+Q3+Q6)-(Q2+Q5+Q5+Q8);        

    V=(Q0+Q1+Q1+Q2)-(Q6+Q7+Q7+Q8);

    DR=(Q1+Q0+Q0+Q3)-(Q5+Q8+Q8+Q7);     

DL=(Q1+Q2+Q2+Q5)-(Q3+Q6+Q6+Q7);

对于以上数据的处理,我们先估算一下分别使用单片机、DSP、CPLD/FPGA所需的时间。

(1)如果使用12M的单片机:完成一次Sobel滤波操作需要的时间至少为:(24×2+20+2×3+2)×1us=72us。对于一幅600×800像素的图像,总共的时间为:600×800×72us=32s。

(2)若使用40M六级流水的DSP,他们的处理时间大概为 32s/24=1.4s。

(3)如果使用CPLD/FPGA进行自行设计,通过采用并行流水线技术假设使用50M的系统时钟,处理完一个像素点的时间为 4×1/(50M)=80ns,处理完一帧图像的时间为 800×600×80ns=38.4ms,结果处理速度比DSP高了大约两个数量级。

  从上可以看出,使用CPLD/FPGA进行自行设计有关图像处理模块,对整个系统速度的改善是很非常明显的。

3 .  总体设计方案

整个系统的实现可划分为四个大的模块,总体结构如图3所示,其中:

帧窗口接收模块(FIFO):负责接收DSP传送过来的一个帧窗口的数据,其本质为一个双端口先入先出栈FIFO,其数据宽度为8,深度等于一个帧窗口内的像素点个数(600×3=1800)。

串入并出模块(SIPO):负责把FIFO内的数据转换成为像素处理窗口的列像素向量,便于像素处理窗口的数据刷新处理。

像素窗口刷新模块(REFRESH):实现对需要处理的像素数据的刷新。

数据处理模块(PROCESSOR):它是本图形边缘处理器的核心部分,主要是实现Sobel算法,其性能的好坏对整个设计的成败有着关键的作用。本模块拟采用全硬件并行算法实现,因只有五级串行结构,所以相当于在5个时钟周期内就能完成一个像素点的边界判别。

                                  图3.图像边缘检测器总体结构图

3.1主要模块的设计思想

  1. 帧窗口接收模块FIFO

由于高速设备与慢速设备之间处理速度的差别,本系统数据传输选择了帧同步方式。存储器的类型拟选用FIFO,堆栈空时向主机发出准备好信号,主机检测到它的数据传输请求时,传送一帧数据,由于FIFO的大小与一帧图像的大小是一致的,所以接收完毕后,堆栈满,Sobel处理器启动边缘检测进程,处理完一帧数据后,堆栈重新变为空,为下一帧数据处理作准备。

2.串入并出模块SIPO

串入并出模块的主要功能是负责一列像素的刷新,也就是把主处理器传送过来的像素值转换成3×3像素窗口的一列。该模块的实现主要是通过六个D触发器和一个三进制的计数器组成,当计数器产生进位溢出时,串行输入的三个像素点并行输出。

3.像素窗口刷新模块REFRESH

像素刷新窗口的主要功能是接收串入并出模块的3个并行像素,把窗口中原有的第二列像素推入第三列,第一列推入第二列,新到的并行像素填入第一列。其本质为一个移位寄存器。

4.滤波模块FILTER

对于SOBEL算法的各个滤波器,经变换后可得到:

H=(Q0+Q3+Q3+Q6)-(Q2+Q5+Q5+Q8); 

V=(Q0+Q1+Q1+Q2)-(Q6+Q7+Q7+Q8);

DR=(Q1+Q0+Q0+Q3)-(Q5+Q8+Q8+Q7);

DL=(Q1+Q2+Q2+Q5)-(Q3+Q6+Q6+Q7);

5.数据处理模块PROCESSOR

数据处理模块PROCESSOR的主要功能是求出四个方向的图像梯度数据绝对值的最大值,同时判别最大值出现的方向。

3.2系统源程序

--SOBEL.VHD  顶层
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SOBEL IS 
  PORT(CLK1,CLK2:IN STD_LOGIC;
LIBRARY IEEE;
       K1:IN STD_LOGIC;
		 K2:IN STD_LOGIC;
		 K3:IN STD_LOGIC;
		 K4:IN STD_LOGIC;
		 COM:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 SEG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY SOBEL;
ARCHITECTURE ART OF SOBEL IS
   COMPONENT  CNT13 IS
	 PORT(CLK:IN STD_LOGIC;
	      CO:OUT STD_LOGIC_VECTOR(12 DOWNTO 0));
	END COMPONENT CNT13;
   COMPONENT  SOBELROM IS 
    PORT(CLOCK:IN STD_LOGIC;
	      ADDRESS:IN STD_LOGIC_VECTOR(12 DOWNTO 0);
         Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
   END COMPONENT SOBELROM;
	COMPONENT SIPO IS
    PORT(CLK:IN STD_LOGIC;
        PIXEL:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		  QA:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		  QB,QC:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
   END COMPONENT SIPO;
	COMPONENT REFRESH IS
    PORT(CLK:IN STD_LOGIC;
       DATA0,DATA1,DATA2:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 Q0,Q1,Q2,Q3,Q5,Q6,Q7,Q8:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
   END COMPONENT REFRESH;
	COMPONENT PROCESSOR IS 
  PORT( CLK:IN STD_LOGIC;
        Q0,Q1,Q2,Q3,Q5,Q6,Q7,Q8:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		  O0,O1,O2,O3,O5,O6,O7,O8:BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0);
		  MAGOUT:OUT STD_LOGIC;
		  MAX,H,V,DL,DR:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
   END COMPONENT PROCESSOR;
	COMPONENT CHOOSE IS
    PORT(K1:IN STD_LOGIC;
	      K2:IN STD_LOGIC;
			K3:IN STD_LOGIC;
			K4:IN STD_LOGIC;
       A1,A2,A3,A4,A5:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 DOUT1:OUT STD_LOGIC_VECTOR(10 DOWNTO 0);
		 DOUT2:OUT STD_LOGIC_VECTOR(10 DOWNTO 0);
		 I0,I1,I2,I3,I5,I6,I7,I8:IN STD_LOGIC_VECTOR(7 DOWNTO 0));
   END COMPONENT CHOOSE;
	COMPONENT CTRLS IS
   PORT(CLK: IN STD_LOGIC;      
       SEL: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
  END COMPONENT CTRLS;
  COMPONENT DISPLAY IS
  PORT(SEL: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
       MAGIN:IN STD_LOGIC;
		 K1:IN STD_LOGIC;
		 K2:IN STD_LOGIC;
		 K3:IN STD_LOGIC;
		 K4:IN STD_LOGIC;
       DATA1: IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 DATA2: IN STD_LOGIC_VECTOR(10 DOWNTO 0);
       COM: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
       SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
  END COMPONENT DISPLAY;
   SIGNAL R1:STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL A1,A2,A3:STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL B0,B1,B2,B3,B5,B6,B7,B8:STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL C0,C1,C2,C3,C5,C6,C7,C8:STD_LOGIC_VECTOR(7 DOWNTO 0);
	SIGNAL P0,P1,P2,P3,P4:STD_LOGIC_VECTOR(10 DOWNTO 0);
	SIGNAL X1,X2:STD_LOGIC_VECTOR(10 DOWNTO 0);
	SIGNAL S0:STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL S1:STD_LOGIC_VECTOR(12 DOWNTO 0);
	SIGNAL S2:STD_LOGIC;
	BEGIN
	U0:CNT13 PORT MAP(CLK=>CLK1,CO=>S1);
	U1:SOBELROM PORT MAP(CLOCK=>CLK1,ADDRESS=>S1,Q=>R1);
	U2:SIPO PORT MAP(CLK=>CLK1,PIXEL=>R1,QA=>A1,QB=>A2,QC=>A3);
	U3:REFRESH PORT MAP(CLK1,A1,A2,A3,B0,B1,B2,B3,B5,B6,B7,B8);
	U4:PROCESSOR PORT MAP(CLK1,B0,B1,B2,B3,B5,B6,B7,B8,C0,C1,C2,C3,C5,C6,C7,C8,S2,P0,P1,P2,P3,P4);
	U5:CHOOSE PORT MAP(K1=>K1,K2=>K2,K3=>K3,K4=>K4,A1=>P1,A2=>P2,A3=>P3,A4=>P4,A5=>P0,DOUT1=>X1,DOUT2=>X2,I0=>C0,I1=>C1,I2=>C2,I3=>C3,I5=>C5,I6=>C6,I7=>C7,I8=>C8);
	U6:CTRLS PORT MAP(CLK=>CLK2,SEL=>S0);
	U7:DISPLAY PORT MAP(SEL=>S0,MAGIN=>S2,K1=>K1,K2=>K2,K3=>K3,K4=>K4,DATA1=>X1,DATA2=>X2,COM=>COM,SEG=>SEG);
END ARCHITECTURE ART;
--SIPO.VHD   串入并出
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY SIPO IS
  PORT( CLK:IN STD_LOGIC;
        PIXEL:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		  QA:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		  QB,QC:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY SIPO;
ARCHITECTURE ART OF SIPO IS
  COMPONENT REG IS
  PORT(CLK:IN STD_LOGIC;
       D:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
   END COMPONENT REG;
	COMPONENT  CNT3 IS
   PORT(CLK:IN STD_LOGIC;
	     CO:OUT STD_LOGIC);
   END COMPONENT CNT3;
	SIGNAL S0:STD_LOGIC;
	SIGNAL S1,S2,S3:STD_LOGIC_VECTOR(7 DOWNTO 0);
	BEGIN
	U0:REG PORT MAP(CLK=>CLK,D=>PIXEL,Q=>S1);
	U1:REG PORT MAP(CLK=>CLK,D=>S1,Q=>S2);
	U2:REG PORT MAP(CLK=>CLK,D=>S2,Q=>S3);
	U3:CNT3 PORT MAP(CLK=>CLK,CO=>S0);
	U4:REG PORT MAP(CLK=>S0,D=>S1,Q=>QA);
	U5:REG PORT MAP(CLK=>S0,D=>S2,Q=>QB);
	U6:REG PORT MAP(CLK=>S0,D=>S3,Q=>QC);
END ARCHITECTURE ART;
 --REG.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY REG IS
  PORT(CLK:IN STD_LOGIC;
       D:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY REG;
ARCHITECTURE ART OF REG IS
  BEGIN 
  PROCESS(CLK,D) IS
  BEGIN
  IF(CLK'EVENT AND CLK='1') THEN
  Q<=D;
  END IF;
END PROCESS;
END ARCHITECTURE ART;      
--CNT3.VHD  计数器模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT3 IS
   PORT(CLK:IN STD_LOGIC;
	     CO:OUT STD_LOGIC);
END ENTITY CNT3;
ARCHITECTURE ART OF CNT3 IS
  SIGNAL CQ:STD_LOGIC_VECTOR(1 DOWNTO 0);
  BEGIN 
  PROCESS(CLK) IS
  BEGIN
  IF(CLK'EVENT AND CLK='1') THEN
    IF CQ="10" THEN
	 CQ<="00";CO<='1';
	 ELSE
	 CQ<=CQ+'1';
	 CO<='0';
	 END IF;
  END IF;
END PROCESS;
END ARCHITECTURE ART;
--REFRESH.VHD  像素刷新
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY REFRESH IS
  PORT(CLK:IN STD_LOGIC;
       DATA0,DATA1,DATA2:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 Q0,Q1,Q2,Q3,Q5,Q6,Q7,Q8:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY REFRESH;
ARCHITECTURE ART OF REFRESH IS
  COMPONENT REG IS
  PORT(CLK:IN STD_LOGIC;
       D:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
  END COMPONENT REG;
  SIGNAL A1,A2:STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL B1,B2:STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL C1,C2:STD_LOGIC_VECTOR(7 DOWNTO 0);
  BEGIN
  U1:REG PORT MAP(CLK=>CLK,D=>DATA0,Q=>A1);
  U2:REG PORT MAP(CLK=>CLK,D=>A1,Q=>A2);
  U3:REG PORT MAP(CLK=>CLK,D=>A2,Q=>Q6);
  U4:REG PORT MAP(CLK=>CLK,D=>DATA1,Q=>B1);
  U5:REG PORT MAP(CLK=>CLK,D=>B1,Q=>B2);
  U6:REG PORT MAP(CLK=>CLK,D=>B2,Q=>Q7);
  U7:REG PORT MAP(CLK=>CLK,D=>DATA2,Q=>C1);
  U8:REG PORT MAP(CLK=>CLK,D=>C1,Q=>C2);
  U9:REG PORT MAP(CLK=>CLK,D=>C2,Q=>Q8);
  Q3<=A2;Q0<=A1;
  Q1<=B1;Q2<=C1;
  Q5<=C2;
END ARCHITECTURE ART;
--ADD.VHD(加法器)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ADD IS 
  PORT (A,B:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
        SUM:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY ADD;
ARCHITECTURE ART OF ADD IS
  SIGNAL A1:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL B1:STD_LOGIC_VECTOR(10 DOWNTO 0);
  BEGIN
  A1<="000"&A;
  B1<="000"&B;
  SUM<=A1+B1;
END ARCHITECTURE ART;
--REG2.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY REG2 IS
  PORT(CLK:IN STD_LOGIC;
       D:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 Q:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY REG2;
ARCHITECTURE ART OF REG2 IS
  BEGIN 
  PROCESS(CLK,D) IS
  BEGIN
  IF(CLK'EVENT AND CLK='1') THEN
  Q<=D;
  END IF;
END PROCESS;
END ARCHITECTURE ART;
--ADD2.VHD(加法器)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ADD2 IS 
  PORT (A,B:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
        SUM:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY ADD2;
ARCHITECTURE ART OF ADD2 IS
  BEGIN
  SUM<=A+B;
END ARCHITECTURE ART;
--FILTER.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY FILTER IS 
  PORT(CLK:IN STD_LOGIC;
       QA,QB,QC,QD,QE,QF:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 DOUT:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY FILTER;
ARCHITECTURE ART OF FILTER IS
  COMPONENT ADD IS 
  PORT (A,B:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
        SUM:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
  END COMPONENT ADD;
  COMPONENT ADD2 IS 
  PORT (A,B:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
        SUM:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
  END COMPONENT ADD2;
  COMPONENT  REG2 IS
  PORT(CLK:IN STD_LOGIC;
       D:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 Q:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
  END COMPONENT REG2;
  SIGNAL D0,D1,D2,D3:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL A0,A1,A2,A3:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL B1,B2,C1,C2:STD_LOGIC_VECTOR(10 DOWNTO 0);
  BEGIN
  U1:ADD PORT MAP(A=>QA,B=>QB,SUM=>D0);
  U2:ADD PORT MAP(A=>QB,B=>QC,SUM=>D1);
  U3:ADD PORT MAP(A=>QD,B=>QE,SUM=>D2);
  U4:ADD PORT MAP(A=>QE,B=>QF,SUM=>D3);
  U5:REG2 PORT MAP(CLK=>CLK,D=>D0,Q=>A0);
  U6:REG2 PORT MAP(CLK=>CLK,D=>D1,Q=>A1);
  U7:REG2 PORT MAP(CLK=>CLK,D=>D2,Q=>A2);
  U8:REG2 PORT MAP(CLK=>CLK,D=>D3,Q=>A3);
  U9:ADD2 PORT MAP(A=>D0,B=>D1,SUM=>B1);
  U10:ADD2 PORT MAP(A=>D2,B=>D3,SUM=>B2);
  U11:REG2 PORT MAP(CLK=>CLK,D=>B1,Q=>C1);
  U12:REG2 PORT MAP(CLK=>CLK,D=>B2,Q=>C2);
  DOUT<=C1-C2;
END ARCHITECTURE ART;
--ZFIFO.VHD  帧窗口接收模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ZFIFO IS
  PORT(CLK:IN STD_LOGIC;
       WR:IN STD_LOGIC;
		 Q:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		 READY:OUT STD_LOGIC;
		 PROCESS_EN:OUT STD_LOGIC);
END ENTITY ZFIFO;
ARCHITECTURE ART OF ZFIFO IS
  COMPONENT SOBELROM IS
  	   PORT(ADDRESS:IN STD_LOGIC_VECTOR(12 DOWNTO 0);
		     CLOCK:IN STD_LOGIC:= '1';
		     Q:OUT STD_LOGIC_VECTOR (7 DOWNTO 0));
  END COMPONENT SOBELROM;
  COMPONENT CNT13 IS
      PORT(CLK:IN STD_LOGIC;
	        CO:OUT STD_LOGIC_VECTOR(12 DOWNTO 0));
  END COMPONENT CNT13;
  COMPONENT D IS
      PORT(CLK:IN STD_LOGIC;
		     ENA:IN STD_LOGIC;
		     CLR:IN STD_LOGIC;
		     Q:OUT STD_LOGIC);
  END COMPONENT D;
  COMPONENT YUMEN IS
      PORT(A,B:IN STD_LOGIC;
           Y:OUT STD_LOGIC);
  END COMPONENT YUMEN;
  COMPONENT FEIMEN IS
      PORT(A:IN STD_LOGIC;
           Y:OUT STD_LOGIC);
  END COMPONENT FEIMEN;
  COMPONENT FIFO IS
    	PORT(CLOCK:IN STD_LOGIC;
		     DATA:IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		     RDREQ:IN STD_LOGIC;
		     WRREQ:IN STD_LOGIC;
		     EMPTY:OUT STD_LOGIC;
		     FULL:OUT STD_LOGIC;
		     Q:OUT STD_LOGIC_VECTOR (7 DOWNTO 0));
  END COMPONENT FIFO;
  SIGNAL A1,A2,A3:STD_LOGIC; 
  SIGNAL B1:STD_LOGIC_VECTOR(12 DOWNTO 0);  
  SIGNAL B2,B3:STD_LOGIC_VECTOR(7 DOWNTO 0);                   
  SIGNAL C1,D1:STD_LOGIC;                                  
  BEGIN
  U1:CNT13 PORT MAP(CLK=>CLK,CO=>B1);
  U2:SOBELROM PORT MAP(ADDRESS=>B1,CLOCK=>CLK,Q=>B2);
  U3:D PORT MAP(CLK=>CLK,ENA=>A1,CLR=>A2,Q=>A3);
  U4:FIFO PORT MAP(CLOCK=>CLK,DATA=>B2,RDREQ=>A3,WRREQ=>D1,EMPTY=>A2,FULL=>A1,Q=>B3);
  U5:FEIMEN PORT MAP(A=>A3,Y=>C1);
  U6:YUMEN PORT MAP(A=>C1,B=>WR,Y=>D1);
  Q<=B3;
  READY<=A3;
  PROCESS_EN<=C1;
END ARCHITECTURE ART;
--CNT2.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT2 IS
  PORT(CLK:IN STD_LOGIC;
       CO:OUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END ENTITY CNT2;
ARCHITECTURE ART OF CNT2 IS
  SIGNAL CNT:STD_LOGIC_VECTOR(1 DOWNTO 0);
  BEGIN
   PROCESS(CLK)IS
	BEGIN
    IF(CLK'EVENT AND CLK='1')THEN
      IF CNT="11" THEN
		  CNT<="00";
		ELSE
		  CNT<=CNT+'1';
		END IF;
	 END IF;
	END PROCESS;
 CO<=CNT;
END ARCHITECTURE ART;
--D.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY D IS
  PORT(CLK:IN STD_LOGIC;
       D:IN STD_LOGIC;
		 ENA:IN STD_LOGIC;
		 CLR:IN STD_LOGIC;
		 Q:OUT STD_LOGIC);
END ENTITY D;
ARCHITECTURE ART OF D IS
  BEGIN
  PROCESS(CLK,CLR,ENA)IS
  BEGIN
    IF(CLR='1')THEN
	  Q<='0';
	 ELSIF(ENA='1')THEN
	   IF(CLK'EVENT AND CLK='1')THEN
	  Q<='1';
	 END IF;
	END IF;
  END PROCESS;
END ARCHITECTURE;
--YUMEN.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY YUMEN IS
  PORT(A,B:IN STD_LOGIC;
       Y:OUT STD_LOGIC);
END ENTITY YUMEN;
ARCHITECTURE ART OF YUMEN IS
  BEGIN
   Y<=A AND B;
END ARCHITECTURE ART;

 

--FEIMEN.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY FEIMEN IS
  PORT(A:IN STD_LOGIC;
       Y:OUT STD_LOGIC);
END ENTITY FEIMEN;
ARCHITECTURE ART OF FEIMEN IS
  BEGIN
   Y<=NOT A;
END ARCHITECTURE ART;
--CNT13.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT13 IS
   PORT(CLK:IN STD_LOGIC;
	     CO:OUT STD_LOGIC_VECTOR(12 DOWNTO 0));
END ENTITY CNT13;
ARCHITECTURE ART OF CNT13 IS
  SIGNAL CNT:STD_LOGIC_VECTOR(12 DOWNTO 0);
  BEGIN
   PROCESS(CLK)IS
	BEGIN
	 IF(CLK'EVENT AND CLK='1') THEN
	   IF CNT="1111111111111" THEN
		CNT<="0000000000000";
		ELSE
		CNT<=CNT+'1';
		END IF;
	 END IF;
	END PROCESS;
	CO<=CNT;
END ARCHITECTURE ART;
--COMPARE.VHD   比较模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY COMPARE IS
  PORT (DATA1,DATA2:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
        MAX:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY COMPARE;
ARCHITECTURE ART OF COMPARE IS
  BEGIN 
  PROCESS(DATA1,DATA2) IS
  BEGIN
  IF(DATA1(10 DOWNTO 0)>DATA2(10 DOWNTO 0))THEN
  MAX<=DATA1;
  ELSE
  MAX<=DATA2;
  END IF;
  END PROCESS;
END ARCHITECTURE ART;

 

--RELUST.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY RELUST IS
  PORT(CLK:IN STD_LOGIC;
		 MAX:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 MAGOUT:OUT STD_LOGIC);
END ENTITY RELUST;
ARCHITECTURE ART OF RELUST IS
  BEGIN 
  PROCESS(CLK) IS
  BEGIN
  IF(CLK'EVENT AND CLK='1')THEN
    IF(MAX(10 DOWNTO 0)>"00010000000") THEN
	 MAGOUT<='1';
	 ELSE MAGOUT<='0';
	 END IF;
	 END IF;
  END PROCESS;
END ARCHITECTURE ART;

 

--PROCESSOR.VHD 进程处理模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY PROCESSOR IS 
  PORT( CLK:IN STD_LOGIC;
       Q0,Q1,Q2,Q3,Q5,Q6,Q7,Q8:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 O0,O1,O2,O3,O5,O6,O7,O8:BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0);
		  MAGOUT:OUT STD_LOGIC;
		  MAX,H,V,DL,DR:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY PROCESSOR;
ARCHITECTURE ART OF PROCESSOR IS
  COMPONENT FILTER IS 
  PORT(CLK:IN STD_LOGIC;
       QA,QB,QC,QD,QE,QF:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 DOUT:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
  END COMPONENT FILTER;
  COMPONENT REG2 IS
  PORT(CLK:IN STD_LOGIC;
       D:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 Q:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
  END COMPONENT REG2;
  COMPONENT COMPARE IS
  PORT (DATA1,DATA2:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
        MAX:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
  END COMPONENT COMPARE;
  COMPONENT RELUST IS
  PORT(CLK:IN STD_LOGIC;
		 MAX:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 MAGOUT:OUT STD_LOGIC);
  END COMPONENT RELUST;
  SIGNAL A1,A2,A3,A4:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL B1,B2,B3,B4:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL C1,C2:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL D1,D2:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL F1:STD_LOGIC_VECTOR(10 DOWNTO 0);
  SIGNAL M1:STD_LOGIC_VECTOR(10 DOWNTO 0);
  BEGIN
  U0:FILTER PORT MAP(CLK,Q0,Q3,Q6,Q2,Q5,Q8,A1);
  U1:FILTER PORT MAP(CLK,Q0,Q1,Q2,Q6,Q7,Q8,A2);
  U2:FILTER PORT MAP(CLK,Q1,Q0,Q3,Q5,Q8,Q7,A3);
  U3:FILTER PORT MAP(CLK,Q1,Q2,Q5,Q3,Q6,Q7,A4);
  U4:REG2 PORT MAP(CLK,A1,B1);
  U5:REG2 PORT MAP(CLK,A2,B2);
  U6:REG2 PORT MAP(CLK,A3,B3);
  U7:REG2 PORT MAP(CLK,A4,B4);
  U8:COMPARE PORT MAP(B1,B2,C1);
  U9:COMPARE PORT MAP(B3,B4,C2);
  U10:REG2 PORT MAP(CLK,C1,D1);
  U11:REG2 PORT MAP(CLK,C2,D2);
  U12:COMPARE PORT MAP(D1,D2,F1);
  U13:REG2 PORT MAP(CLK,F1,M1);
  U14:RELUST PORT MAP(CLK=>CLK,MAX=>M1,MAGOUT=>MAGOUT);
  MAX<=M1;H<=A1;V<=A2;DR<=A3;DL<=A4;
  O0<=Q0;O1<=Q1;O2<=Q2;O3<=Q3;O5<=Q5;O6<=Q6;O7<=Q7;O8<=Q8;
END ARCHITECTURE ART;
--SOBELROM.VHD  存储模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
LIBRARY ALTERA_MF;
USE ALTERA_MF.ALTERA_MF_COMPONENTS.ALL;

ENTITY SOBELROM IS
	PORT
	(
		ADDRESS		: IN STD_LOGIC_VECTOR (12 DOWNTO 0);
		CLOCK		: IN STD_LOGIC  := '1';
		Q		: OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
	);
END SOBELROM;
ARCHITECTURE SYN OF SOBELROM IS

	SIGNAL SUB_WIRE0	: STD_LOGIC_VECTOR (7 DOWNTO 0);

BEGIN
	Q    <= SUB_WIRE0(7 DOWNTO 0);

	ALTSYNCRAM_COMPONENT : ALTSYNCRAM
	GENERIC MAP (
		ADDRESS_ACLR_A => "NONE",
		CLOCK_ENABLE_INPUT_A => "BYPASS",
		CLOCK_ENABLE_OUTPUT_A => "BYPASS",
		INIT_FILE => "GRAY_IMAGE.MIF",
		INTENDED_DEVICE_FAMILY => "CYCLONE III",
		LPM_HINT => "ENABLE_RUNTIME_MOD=NO",
		LPM_TYPE => "ALTSYNCRAM",
		NUMWORDS_A => 6400,
		OPERATION_MODE => "ROM",
		OUTDATA_ACLR_A => "NONE",
		OUTDATA_REG_A => "UNREGISTERED",
		WIDTHAD_A => 13,
		WIDTH_A => 8,
		WIDTH_BYTEENA_A => 1
	)
	PORT MAP (
		ADDRESS_A => ADDRESS,
		CLOCK0 => CLOCK,
		Q_A => SUB_WIRE0
	);
END SYN;
--CHOOSE.VHD  选择模块
--在kk等于0100时DOUT1输出H,DOUT2输出V;在kk等于1000时DOUT1输出DL,DOUT2输出DR;当kk等于1100时,DOUT1输出四者中最大值MAX,DOUT2输出空。KK=0000时,DOUT1为I0,DOUT2为I1;...
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CHOOSE IS
  PORT(K1:IN STD_LOGIC;
		 K2:IN STD_LOGIC;
		 K3:IN STD_LOGIC;
		 K4:IN STD_LOGIC;
       A1,A2,A3,A4,A5:IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 I0,I1,I2,I3,I5,I6,I7,I8:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
		 DOUT1:OUT STD_LOGIC_VECTOR(10 DOWNTO 0);
		 DOUT2:OUT STD_LOGIC_VECTOR(10 DOWNTO 0));
END ENTITY CHOOSE;
ARCHITECTURE ART OF CHOOSE IS
  SIGNAL KK:STD_LOGIC_VECTOR(3 DOWNTO 0);
  BEGIN
  KK<=K1&K2&K3&K4;
  PROCESS(KK,A1,A2,A3,A4,A5) IS
  BEGIN
  CASE KK IS
  WHEN "0100"=>DOUT1<=A1;DOUT2<=A2;                    
  WHEN "1000"=>DOUT1<=A3;DOUT2<=A4;
  WHEN "1100"=>DOUT1<=A5;DOUT2<="00000000000";
  WHEN "0000"=>DOUT1<="000"&I0;DOUT2<="000"&I1;
  WHEN "0001"=>DOUT1<="000"&I2;DOUT2<="000"&I3;
  WHEN "0010"=>DOUT1<="000"&I5;DOUT2<="000"&I6;
  WHEN "0011"=>DOUT1<="000"&I7;DOUT2<="000"&I8;
  WHEN OTHERS=>NULL;
  END CASE;
  END PROCESS;
END ARCHITECTURE ART;
--CTRLS.VHD
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CTRLS IS
  PORT(CLK: IN STD_LOGIC;      
  SEL: OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END ENTITY CTRLS;
ARCHITECTURE ART OF CTRLS IS
  SIGNAL CNT: STD_LOGIC_VECTOR(2 DOWNTO 0);
  BEGIN
  PROCESS(CLK) IS
    BEGIN
    IF CLK'EVENT AND CLK='1' THEN
      IF CNT="111" THEN 
         CNT<="000";
       ELSE 
         CNT<=CNT+'1';
      END IF ;
   END IF;
  END PROCESS;
  SEL<=CNT;
END ARCHITECTURE ART; 
--DISPLAY.VHD  动态显示模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DISPLAY IS
  PORT(SEL:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
       MAGIN:IN STD_LOGIC;
       K1:IN STD_LOGIC;
		 K2:IN STD_LOGIC;
		 K3:IN STD_LOGIC;
		 K4:IN STD_LOGIC;
       DATA1: IN STD_LOGIC_VECTOR(10 DOWNTO 0);
		 DATA2: IN STD_LOGIC_VECTOR(10 DOWNTO 0);
       COM: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
       SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY DISPLAY;
ARCHITECTURE ART OF DISPLAY IS
  SIGNAL DATA:STD_LOGIC_VECTOR(3 DOWNTO 0);
  SIGNAL CONTROL:STD_LOGIC_VECTOR(6 DOWNTO 0);
  BEGIN
    CONTROL<=K1&K2&K3&K4&SEL;
  PROCESS(SEL) IS
    BEGIN
    CASE SEL IS
      WHEN "000" => COM<="11111110";
      WHEN "001" => COM<="11111101";
      WHEN "010" => COM<="11111011";
      WHEN "011" => COM<="11110111";
      WHEN "100" => COM<="11101111";
      WHEN "101" => COM<="11011111";
      WHEN "110" => COM<="10111111";
      WHEN "111" => COM<="01111111";
      WHEN OTHERS => COM<="11111111";
    END CASE ;
  END PROCESS;
  PROCESS(SEL) IS
    BEGIN
    CASE CONTROL IS
      WHEN "0100000" =>DATA<=DATA1(3 DOWNTO 0); --H
      WHEN "0100001" =>DATA<=DATA1(7 DOWNTO 4);
		WHEN "0100010" =>DATA<="0"&DATA1(10 DOWNTO 8);
		WHEN "0100011" =>DATA<=DATA2(3 DOWNTO 0); --V
		WHEN "0100100" =>DATA<=DATA2(7 DOWNTO 4);
		WHEN "0100101" =>DATA<="0"&DATA2(10 DOWNTO 8);
		WHEN "0100110" =>DATA<="000"&MAGIN;  --边缘检测
	
     	WHEN "1000000" =>DATA<=DATA1(3 DOWNTO 0); --DL
		WHEN "1000001" =>DATA<=DATA1(7 DOWNTO 4);
		WHEN "1000010" =>DATA<="0"&DATA1(10 DOWNTO 8); 
		WHEN "1000011" =>DATA<=DATA2(3 DOWNTO 0); --DR
		WHEN "1000100" =>DATA<=DATA2(7 DOWNTO 4);
		WHEN "1000101" =>DATA<="0"&DATA2(10 DOWNTO 8);
		WHEN "1000110" =>DATA<="000"&MAGIN;  --边缘检测
		
		WHEN "1100000" =>DATA<=DATA1(3 DOWNTO 0); --MAX
		WHEN "1100001" =>DATA<=DATA1(7 DOWNTO 4);
		WHEN "1100010" =>DATA<="0"&DATA1(10 DOWNTO 8);
		WHEN "1100110" =>DATA<="000"&MAGIN;  --边缘检测
		
		WHEN "0000000" =>DATA<=DATA1(3 DOWNTO 0); --Q0
		WHEN "0000001" =>DATA<=DATA1(7 DOWNTO 4);
		WHEN "0000010" =>DATA<="0"&DATA1(10 DOWNTO 8);
		WHEN "0000011" =>DATA<=DATA2(3 DOWNTO 0); --Q1
		WHEN "0000100" =>DATA<=DATA2(7 DOWNTO 4);
		WHEN "0000101" =>DATA<="0"&DATA2(10 DOWNTO 8);
		WHEN "0000110" =>DATA<="000"&MAGIN;
		
		WHEN "0001000" =>DATA<=DATA1(3 DOWNTO 0); --Q2
		WHEN "0001001" =>DATA<=DATA1(7 DOWNTO 4);
		WHEN "0001010" =>DATA<="0"&DATA1(10 DOWNTO 8);
		WHEN "0001011" =>DATA<=DATA2(3 DOWNTO 0); --Q3
		WHEN "0001100" =>DATA<=DATA2(7 DOWNTO 4);
		WHEN "0001101" =>DATA<="0"&DATA2(10 DOWNTO 8);
		WHEN "0001110" =>DATA<="000"&MAGIN;
		
		WHEN "0010000" =>DATA<=DATA1(3 DOWNTO 0); --Q5
		WHEN "0010001" =>DATA<=DATA1(7 DOWNTO 4);
		WHEN "0010010" =>DATA<="0"&DATA1(10 DOWNTO 8);
		WHEN "0010011" =>DATA<=DATA2(3 DOWNTO 0); --Q6
		WHEN "0010100" =>DATA<=DATA2(7 DOWNTO 4);
		WHEN "0010101" =>DATA<="0"&DATA2(10 DOWNTO 8);
		WHEN "0010110" =>DATA<="000"&MAGIN;
		
		WHEN "0011000" =>DATA<=DATA1(3 DOWNTO 0); --Q7
		WHEN "0011001" =>DATA<=DATA1(7 DOWNTO 4);
		WHEN "0011010" =>DATA<="0"&DATA1(10 DOWNTO 8);
		WHEN "0011011" =>DATA<=DATA2(3 DOWNTO 0); --Q8
		WHEN "0011100" =>DATA<=DATA2(7 DOWNTO 4);
		WHEN "0011101" =>DATA<="0"&DATA2(10 DOWNTO 8);
		WHEN "0011110" =>DATA<="000"&MAGIN;
		
      WHEN OTHERS=>DATA<="0000";
    END CASE;
       CASE DATA IS
      WHEN "0000" => SEG<="00111111";--0
      WHEN "0001" => SEG<="00000110";--1
      WHEN "0010" => SEG<="01011011";--2
      WHEN "0011" => SEG<="01001111";--3
      WHEN "0100" => SEG<="01100110";--4
      WHEN "0101" => SEG<="01101101";--5
      WHEN "0110" => SEG<="01111101";--6
      WHEN "0111" => SEG<="00000111";--7
      WHEN "1000" => SEG<="01111111";--8
      WHEN "1001" => SEG<="01101111";--9
		WHEN "1010" => SEG<="01110111";--A
		WHEN "1011" => SEG<="01111100";--b
		WHEN "1100" => SEG<="00111001";--C
		WHEN "1101" => SEG<="01011110";--d
		WHEN "1110" => SEG<="01111001";--E
		WHEN "1111" => SEG<="01110001";--F
   END CASE ;
 END PROCESS;
END ARCHITECTURE ART;

   4 软硬件实验系统构建与测试结果

                                                          processor模块仿真 

                                                              整体RTL视图 

 

                                                                    实物验证

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值