📄 sobel.vhd
字号:
--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 + -