-
Notifications
You must be signed in to change notification settings - Fork 3
/
ConvFilter.vhd
134 lines (115 loc) · 3.82 KB
/
ConvFilter.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.Types.all;
use work.OV76X0Pack.all;
entity ConvFilter is
generic (
DataW : positive;
CompDataW : positive;
Res : positive
);
port (
Clk : in bit1;
RstN : in bit1;
--
FilterSel : in word(MODESW-1 downto 0);
--
IncThreshold : in bit1;
DecThreshold : in bit1;
--
RdAddr : in word(bits(FrameW)-1 downto 0);
Vsync : in bit1;
--
PixelInVal : in bit1;
PixelIn : in PixVec2D(Res-1 downto 0);
--
PixelOut : out word(CompDataW-1 downto 0);
PixelOutVal : out bit1
);
end entity;
architecture rtl of ConvFilter is
signal PixelOut_N, PixelOut_D : word(DataW-1 downto 0);
signal PixelOutVal_N, PixelOutVal_D : bit1;
constant ColumnsToFilter : natural := 0;
constant LinesToFilter : natural := 9;
signal LineFilter_N, LineFilter_D : word(bits(LinesToFilter)-1 downto 0);
signal FirstColumn : bit1;
constant ThresholdStep : natural := 32;
signal CurThres_N, CurThres_D : word(3-1 downto 0);
begin
SyncRstProc : process (Clk, RstN)
begin
if RstN = '0' then
PixelOutVal_D <= '0';
LineFilter_D <= (others => '0');
CurThres_D <= conv_word(1, CurThres_D'length);
elsif rising_edge(Clk) then
PixelOutVal_D <= PixelOutVal_N;
LineFilter_D <= LineFilter_N;
CurThres_D <= CurThres_N;
end if;
end process;
SyncNoRstProc : process (Clk)
begin
if rising_edge(Clk) then
PixelOut_D <= PixelOut_N;
end if;
end process;
-- Filter out noise in left column
FirstColumn <= '1' when RdAddr < ColumnsToFilter else '0';
AsyncProc : process (PixelIn, PixelInVal, PixelOut_D, Vsync, LineFilter_D, FirstColumn, RdAddr, FilterSel, IncThreshold, DecThreshold, CurThres_D)
variable SumX, SumY, Sum : word(DataW+1 downto 0);
begin
PixelOut_N <= PixelOut_D;
LineFilter_N <= LineFilter_D;
-- Filter away edges
PixelOutVal_N <= PixelInVal;
CurThres_N <= CurThres_D;
if IncThreshold = '1' and DecThreshold = '1' then
null;
elsif IncThreshold = '1' then
if CurThres_D /= xt1(CurThres_D'length) then
CurThres_N <= CurThres_D + 1;
end if;
elsif DecThreshold = '1' then
if CurThres_D /= xt0(CurThres_D'length) then
CurThres_N <= CurThres_D - 1;
end if;
end if;
if Vsync = '1' then
LineFilter_N <= conv_word(LinesToFilter, LineFilter_N'length);
end if;
if PixelInVal = '1' then
-- Sobel filter
SumY := ("00" & PixelIn(0)(0)) + ('0' & PixelIn(0)(1) & '0') + ("00" & PixelIn(0)(2)) - (("00" & PixelIn(2)(0)) + ('0' & PixelIn(2)(1) & '0') + ("00" & PixelIn(2)(2)));
SumX := ("00" & PixelIn(0)(2)) + ('0' & PixelIn(1)(2) & '0') + ("00" & PixelIn(2)(2)) - (("00" & PixelIn(0)(0)) + ('0' & PixelIn(1)(0) & '0') + ("00" & PixelIn(0)(2)));
-- Convert to Absolute values
if (SumX(SumX'high) = '1') then
SumX := not SumX + 1;
end if;
if (SumY(SumY'high) = '1') then
SumY := not SumY + 1;
end if;
Sum := SumX + SumY;
if Sum > ((conv_integer(CurThres_D)+1) * ThresholdStep)-1 then
PixelOut_N <= (others => '1');
else
PixelOut_N <= Sum(PixelOut_N'length-1 downto 0);
end if;
if FirstColumn = '1' then
PixelOut_N <= (others => '0');
end if;
if LineFilter_D > 0 then
PixelOut_N <= (others => '0');
if RdAddr = FrameW-1 then
LineFilter_N <= LineFilter_D - 1;
end if;
end if;
end if;
end process;
-- Slice out the resolution we support
PixelOut <= PixelOut_D(DataW-1 downto DataW-CompDataW);
PixelOutVal <= PixelOutVal_D;
end architecture rtl;