?? 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 + -