Design of real-time image edge detection system based on FPGA

Posted by Huijari on Fri, 04 Mar 2022 02:01:04 +0100

 

Today, we bring you the design of real-time image edge detection system based on FPGA. Due to the long length, it is divided into three parts. Today, I'll bring the third and second articles. I don't talk much and deliver the goods.

Reading guide

With the rapid development of science and technology, FPGA brings new opportunities for digital image processing in system structure. The information in the image exists in parallel, so the same operation can be performed on it in parallel, which greatly improves the speed of image processing, which is just suitable for mapping to FPGA architecture and realizing it with hardware algorithm.

This paper describes the design idea and process of a digital image processing system based on FPGA, which can collect, process and display in real time, and analyzes the timing of camera interface; The capture principle of image information is described; The functions of each module of image edge detection are introduced in detail; This paper focuses on the design of median filter module with denoising function; The selection of edge detection operator is briefly described; The working principle and control mode of SDRAM are systematically introduced; VGA timing is introduced; Finally, the whole system is verified and summarized, including the verification of simulation waveform and board level verification.

Based on the solid FPGA development board, the system realizes the real-time acquisition, real-time edge detection and real-time display of image data. It runs stably and has high real-time performance, which also shows that FPGA does have the ability of massive data high-speed transmission.

This article is the collation of my graduation project in that year. You heroes can read and learn according to your own needs.

The third content summary: this chapter will introduce the system verification, conclusion and the main codes of each module, including the main codes of image real-time acquisition module, image real-time capture module, median filter module, edge detection module, image cache module and image real-time display module.

5, System verification

In the design process of this system, I mainly use the top-down hierarchical design idea to design the top-level architecture of the system, clarify the functions of each module and the handshake relationship between each module, then write and verify the code by module, debug the code to realize the functions of each module, and finally conduct simulation verification based on the top-level module, As shown in figures 5-1 and 5-2, the simulation waveforms of the top-level module of the system are shown, in which figure 5-1 is the global waveform and Figure 5-2 is the locally amplified waveform.

Figure 5-1 global simulation waveform of system top-level module

Figure 5-2 local simulation waveform of the top module of the system

Then connect the FPGA development experimental board and update its driver, allocate pins according to the configuration file of the development board, and conduct board level test after the full compilation. The development board used in the verification of this system is the physical FPGA development board.

The entity FPGA development board adopts the EP4CE10E22C8N chip of Altera Cyclone IV series. The development board is an FPGA image development board. Its core chip EP4CE10E22C8N has 6272 logic units and 150 IO pins. The development board is equipped with VGA, USB, CMOS interface, SDRAM, keys, LED and many other external devices, which can be used as hardware tools for the design and verification of the system.

The main parameters of the entity FPGA development board are shown in table 6-1 below.

Table 5-1 main parameters of FPGA development board

The results of the lower board show that the function of the digital image edge detection system I designed has been realized, which can collect images in real time, process and display them in real time. What is intercepted here is pictures, and the real scene display can be displayed in real time according to the movement of the camera.

6, Conclusion

In the design of this system, the main equipment driven by FPGA is as follows: the camera model is Ov7725; Universal VGA interface. At the same time, I studied the relevant edge detection algorithms. In order to make the data processing results more accurate, I also preprocessed the image data according to the needs of the system: first convert the color image into gray file; Then, the median filter technology is used to denoise the collected image data effectively. Through the design of this system, I deeply understand the basic principle of driving external devices based on FPGA, master the ability of driving external devices and implementing algorithms based on FPGA and Verilog language, feel the advancement of FPGA, and further determine my own development direction. During the system verification, the real-time acquisition, real-time edge detection and real-time display of image data are realized based on FPGA development board. The system has good performance and high real-time performance. The results show that FPGA can easily realize the high-speed transmission of massive data.

Attachment: some main codes

Main code of image real-time acquisition module:

1  module sccb_config_ctrl( 
2              clk,          //24Mhz input clock
3              rst_n,        //System reset
4              scl,          //iic clock line
5              sda,              //iic data line
6              config_done   //Configuration completion flag
7          );
8      //System input
9   input clk;  //External input clock 24Mhz
10    input rst_n; //System reset
11    //system output 
12    output reg scl;       //iic clock line
13    output reg config_done;       //Configuration completion flag
14 
15    
16    inout sda;                //iic data line
17    
18    reg sda_buffer;   //Intermediate register for writing data
19    reg flag;         //Does the control system have bus control
20  reg [7:0] lut_cnt;  //Pointer register counter
21  reg [15:0] lut_data; //Register address and configuration data
22  reg [3:0] s;
23    
24    assign sda = (flag) ? sda_buffer : 1'bz;//When the flag is high, the system has bus control
25                                            //And send SDA_ Data in buffer. When the flag is low,
26                                            //Release the bus.
27                                                          
28  //----------Delay 1ms counter-----------------
29  reg [31:0] delay_cnt;
30  reg delay_done;
31  
32  always @ (posedge clk or negedge rst_n)
33  begin
34      if(!rst_n)
35          begin
36              delay_done <= 0;
37              delay_cnt <= 0;
38          end
39      else if(delay_cnt == 20000) //23809
40          delay_done <= 1;
41      else
42          begin
43              delay_cnt <= delay_cnt + 1;
44              delay_done <= 0;
45          end
46  end
47  
48  //----------------Frequency division generates 400Khz clock clk_sys---------- 
49    reg [7:0] count;//Counter
50    reg clk_sys;//System clock
51  reg [5:0] state;//Status register
52 
53    always @ (posedge clk or negedge rst_n)
54    begin
55        if (!rst_n)
56            begin
57                clk_sys <= 1'b1;
58                count <= 8'd0;
59            end
60        else
61            if (count < 100)//Frequency division becomes a clock of nearly 200K
62                count <= count + 1;
63            else
64                begin
65                    count <= 8'd0;
66                    clk_sys <= ~clk_sys;
67                end
68    end  
69 
70  //------------------Output scl-------------
71    always @ (negedge clk_sys or negedge rst_n)
72    begin
73        if (!rst_n)
74            begin
75                scl <= 1'b1;//When reset, scl is high
76            end
77        else
78            begin
79                if(config_done == 1 || delay_done == 0)//When the bus is busy, scl is a clock of nearly 400K
80                    scl <= 1;
81                else
82                    scl <= ~scl;//When idle, scl is high
83            end
84    end
85 
86    reg [3:0] cnt;//Number of data sent or received
87    reg [15:0] memory;//An intermediate register that sends or receives data
88 
89  always @ (posedge clk_sys or negedge rst_n)
90    begin
91         if (!rst_n)
92             begin
93                 config_done <= 0;
94                 flag <= 1'b1;       //When reset, the system obtains control of the bus
95                 sda_buffer <= 1'b1; //Send high level to the data line of iic
96                 state <= 0;
97                   cnt <= 0;
98                   memory <= 16'd0;
99                   lut_cnt <= 2;
100                  s <= 0;
101            end
102        else    
103            case(state)
104              0 :if(scl)
105                      begin
106                      if(delay_done)//Delay flag signal pulled high
107                          begin
108                              sda_buffer <= 1'b0; //Send start signal
109                              state <= 1;
110                              memory <= 16'h0042;//Prepare ID address
111                          end
112                      else
113                          state <= 0;
114                   end
115                  else
116                     state <= 0;
117                    
118              1 :if((scl == 0) && (cnt < 8))//Send ID address
119                     begin
120                         sda_buffer <= memory[7];
121                         cnt <= cnt + 1;
122                         memory = {memory[14:0],memory[15]};
123                         state <= 1;
124                     end
125                 else
126                     begin
127                         if ((scl == 0) && (cnt == 8))
128                             begin
129                                 cnt <= 0;
130                                 flag <= 0;//Release bus control
131                                 state <= 2;
132                             end
133                         else
134                             begin
135                                 state <= 1;
136                             end
137                     end
138                                   
139                 2 : 
140                 if(scl)//Receive data during SCL high level
141                         begin
142                             if(!sda)//Detection response signal
143                                 begin 
144                                     state <= 3;
145                                     memory <= lut_data;//Pointer register address
146                                 end
147                             else
148                                 begin
149                                     state <= 0;
150                                 end
151                         end
152                     else
153                         state <= 2;
154                         
155               3 : if((scl == 0) && (cnt < 8)) //Send pointer register address
156                      begin
157                          flag <= 1;//Gain bus control
158                          sda_buffer <= memory[15];
159                          cnt <= cnt + 1;
160                          memory = {memory[14:0],memory[15]};
161                          state <= 3;
162                      end
163                   else
164                       begin
165                           if ((scl == 0) && (cnt == 8))
166                               begin
167                                   cnt <= 0;
168                                   flag <= 0;//Release bus control
169                                   state <= 4;
170                               end
171                           else
172                               begin
173                                   state <= 3;
174                               end
175                        end
176
177              4 :
178                 if(scl)
179                     begin
180                         if(!sda)//Detection response signal
181                             begin
182                                     state <= 5;
183                             end
184                         else
185                                 begin
186                                     state <= 0;
187                                 end
188                     end
189                             
190               5 : if((scl == 0) && (cnt < 8))//Send octet control word
191                     begin
192                         flag <= 1; //Gain bus control
193                         sda_buffer <= memory[15];
194                         cnt <= cnt + 1;
195                         memory <= {memory[14:0],memory[15]};
196                         state <= 5;
197                     end
198                 else
199                     begin
200                         if ((scl == 0) && (cnt == 8))
201                             begin
202                                 cnt <= 0;
203                                 flag <= 0; //Release bus control
204                                 state <= 6;
205                                         lut_cnt <= lut_cnt + 1; //Register pointer + 1
206                             end
207                         else
208                             begin
209                                 state <= 5;
210                             end
211                     end
212                                   
213              6 :  
214                 if(scl) //Receive ACK during SCL high level
215                     begin
216                         if(!sda)//Detection response signal
217                             begin
218                                 state <= 7;
219                             end
220                         else
221                             begin
222                                 state <= 0;
223                             end
224                     end
225             
226              7 : if (scl == 0)
227                        begin 
228                                  flag <= 1;     
229                            sda_buffer <= 0;//Pull down the data cable (prepare for sending stop signal)
230                            state <= 8;
231                        end
232                     else
233                        state <= 7;
234
235              8 : if (scl == 1)  //Send stop signal
236                         begin
237                             sda_buffer <= 1;
238                             begin
239                                 if (s == 8)
240                                     begin
241                                         if(lut_cnt < 70)
242                                             begin
243                                                 state <= 0;
244                                                 s <= 0;
245                                             end
246                                         else
247                                             config_done <= 1;  //Configuration complete
248                                     end
249                                 else
250                                     s <= s + 1;
251                             end
252                      end
253                  else
254                     state <= 8;
255
256                default : state <= 0;
257                endcase
258   end
259  
260 always @ (*)
261 begin
262     case (lut_cnt)
263     //  OV7725 : VGA RGB565 Config
264     //Read Data Index
265     //  0 :     LUT_DATA    =   {8'h0A, 8'h77}; //Product ID Number MSB (Read only)
266     //  1 :     LUT_DATA    =   {8'h0B, 8'h21}; //Product ID Number LSB (Read only)
267     0 :     lut_data    =   {8'h1C, 8'h7F}; //Manufacturer ID Byte - High (Read only)
268     1 : lut_data    =   {8'h1D, 8'hA2}; //Manufacturer ID Byte - Low (Read only)
269     //Write Data Index
270     2   :   lut_data    =   {8'h12, 8'h80}; // BIT[7]-Reset all the Reg 
271     3   :   lut_data    =   {8'h3d, 8'h03}; //DC offset for analog process
272     4   :   lut_data    =   {8'h15, 8'h02}; //COM10: href/vsync/pclk/data reverse(Vsync H valid)
273     5   :   lut_data    =   {8'h17, 8'h22}; //VGA:  8'h22;  QVGA:   8'h3f;
274     6   :   lut_data    =   {8'h18, 8'ha4}; //VGA:  8'ha4;  QVGA:   8'h50;
275     7   :   lut_data    =   {8'h19, 8'h07}; //VGA:  8'h07;  QVGA:   8'h03;
276     8   :   lut_data    =   {8'h1a, 8'hf0}; //VGA:  8'hf0;  QVGA:   8'h78;
277     9   :   lut_data    =   {8'h32, 8'h00}; //HREF  / 8'h80
278     10  :   lut_data =  {8'h29, 8'hA0}; //VGA:  8'hA0;  QVGA:   8'hF0
279     11  :   lut_data =  {8'h2C, 8'hF0}; //VGA:  8'hF0;  QVGA:   8'h78
280     //If the internal PLL is not used, this command is invalid
281     12  :   lut_data    =   {8'h0d, 8'h41}; //Bypass PLL 00:0 01:4x 10:6x 11:8x
282     13  :   lut_data    =   {8'h11, 8'h01}; //CLKRC,Finternal clock = Finput clk*PLL multiplier/[(CLKRC[5:0]+1)*2] = 25MHz*4/[(x+1)*2]
283                                             //00: 50fps, 01:25fps, 03:12.5fps   (50Hz Fliter)
284     14  :   lut_data    =   {8'h12, 8'h06}; //BIT[6]:   0:VGA; 1;QVGA
285                                             //BIT[3:2]: 01:RGB565
286                                             //VGA:  00:YUV; 01:Processed Bayer RGB; 10:RGB; 11:Bayer RAW; BIT[7]-Reset all the Reg  
287     15 :    lut_data    =   {8'h0C, 8'h10}; //COM3: Bit[7:6]:Vertical/Horizontal mirror image ON/OFF, Bit[0]:Color bar; Default:8'h10
288     //DSP control
289     16 :    lut_data    =   {8'h42, 8'h7f}; //BLC Blue Channel Target Value, Default: 8'h80
290     17 :    lut_data    =   {8'h4d, 8'h09}; //BLC Red Channel Target Value, Default: 8'h80
291     18  :   lut_data    =   {8'h63, 8'hf0}; //AWB Control
292     19  :   lut_data    =   {8'h64, 8'hff}; //DSP_Ctrl1:
293     20  :   lut_data    =   {8'h65, 8'h00}; //DSP_Ctrl2:    
294     21  :   lut_data    =   {8'h66, 8'h00}; //{COM3[4](0x0C), DSP_Ctrl3[7]}:00:YUYV;    01:YVYU;    [10:UYVY]   11:VYUY 
295     22 :    lut_data    =   {8'h67, 8'h00}; //DSP_Ctrl4:00/01: YUV or RGB; 10: RAW8; 11: RAW10  
296     //AGC AEC AWB
297     23  :   lut_data    =   {8'h13, 8'hff};
298     24  :   lut_data    =   {8'h0f, 8'hc5};
299     25  :   lut_data    =   {8'h14, 8'h11};
300     26  :   lut_data    =   {8'h22, 8'h98}; //Banding Filt er Minimum AEC Value; Default: 8'h09
301     27  :   lut_data    =   {8'h23, 8'h03}; //Banding Filter Maximum Step
302     28  :   lut_data    =   {8'h24, 8'h40}; //AGC/AEC - Stable Operating Region (Upper Limit)
303     29  :   lut_data    =   {8'h25, 8'h30}; //AGC/AEC - Stable Operating Region (Lower Limit)
304     30  :   lut_data    =   {8'h26, 8'ha1}; //AGC/AEC Fast Mode Operating Region
305     31  :   lut_data    =   {8'h2b, 8'h9e}; //TaiWan: 8'h00:60Hz Filter; Mainland: 8'h9e:50Hz Filter
306     32  :   lut_data    =   {8'h6b, 8'haa}; //AWB Control 3
307     33  :   lut_data    =   {8'h13, 8'hff}; //8'hff: AGC AEC AWB Enable; 8'hf0: AGC AEC AWB Disable;
308     //matrix sharpness brightness contrast UV   
309     34 :    lut_data    =   {8'h90, 8'h0a}; 
310     35 :    lut_data    =   {8'h91, 8'h01};
311     36 :    lut_data    =   {8'h92, 8'h01};
312     37 :    lut_data    =   {8'h93, 8'h01};
313     38 :    lut_data    =   {8'h94, 8'h5f};
314     39 :    lut_data    =   {8'h95, 8'h53};
315     40 :    lut_data    =   {8'h96, 8'h11};
316     41 :    lut_data    =   {8'h97, 8'h1a};
317     42 :    lut_data    =   {8'h98, 8'h3d};
318     43 :    lut_data    =   {8'h99, 8'h5a};
319     44 :    lut_data    =   {8'h9a, 8'h1e};
320     45 :    lut_data    =   {8'h9b, 8'h3f}; //Brightness 
321     46 :    lut_data    =   {8'h9c, 8'h25};
322     47 :    lut_data    =   {8'h9e, 8'h81}; 
323     48 :    lut_data    =   {8'ha6, 8'h06};
324     49 :    lut_data    =   {8'ha7, 8'h65};
325     50 :    lut_data    =   {8'ha8, 8'h65};
326     51 :    lut_data    =   {8'ha9, 8'h80};
327     52 :    lut_data    =   {8'haa, 8'h80};
328     //Gamma correction
329     53 :    lut_data    =   {8'h7e, 8'h0c};
330     54 :    lut_data    =   {8'h7f, 8'h16}; //
331     55 :    lut_data    =   {8'h80, 8'h2a};
332     56 :    lut_data    =   {8'h81, 8'h4e};
333     57 :    lut_data    =   {8'h82, 8'h61};
334     58 :    lut_data    =   {8'h83, 8'h6f};
335     59 :    lut_data    =   {8'h84, 8'h7b};
336     60 :    lut_data    =   {8'h85, 8'h86};
337     61 :    lut_data    =   {8'h86, 8'h8e};
338     62 :    lut_data    =   {8'h87, 8'h97};
339     63 :    lut_data    =   {8'h88, 8'ha4};
340     64 :    lut_data    =   {8'h89, 8'haf};
341     65 :    lut_data    =   {8'h8a, 8'hc5};
342     66 :    lut_data    =   {8'h8b, 8'hd7};
343     67 :    lut_data    =   {8'h8c, 8'he8};
344     68 :    lut_data    =   {8'h8d, 8'h20};
345     //Others
346     69  :   lut_data    =   {8'h0e, 8'h65};//night mode auto frame rate control
347     default : lut_data  =   {8'h1C, 8'h7F};
348     endcase
349 end
350 
351 endmodule 

Main code of image real-time capture module:

1  module coms_capture_rgb565(clk_cmos, rst_n, pclk, vsync, href, din, xclk,
2       frame_data, frame_clk, frame_href, frame_vsync, cmos_fps_rate);
3   
4   input clk_cmos; //24Mhz drive clock input
5   input rst_n;
6   input pclk;      //Input pixel clock
7   input vsync;     //Input field synchronization signal
8   input href;      //Input line synchronization signal
9   input [7:0] din; //Input pixel data
10  
11  output xclk;        //The output CMOS Sensor's drive clock is 0.24Mhz
12  output frame_clk; //Clock for outputting pixel data after splicing
13  output [15:0] frame_data;  //Output pixel data after splicing
14  output frame_href;   //Output synchronized line synchronization signal
15  output frame_vsync;  //Output synchronous field synchronization signal
16  output reg cmos_fps_rate;  //Output frame rate
17  
18  assign xclk = clk_cmos;
19 
20  //-------------Detect field and line synchronization signals------------
21  reg href_r, vsync_r;
22  always @(posedge pclk or negedge rst_n)
23  begin
24      if (!rst_n)
25          begin
26              href_r <= 1;
27              vsync_r <= 1;
28          end
29      else
30          begin
31              href_r <= href;
32              vsync_r <= vsync;
33          end
34  end
35  //The line synchronization signal changes from low level to high level, indicating that the data is valid
36  assign pose_href = (~href_r) & href; 
37  //The field synchronization signal changes from high level to low level, indicating that one frame of data has been received
38  assign nege_vsync = vsync_r & (~vsync);
39 
40  //----------A flag number is generated by delaying 10 frames----------
41  reg frame_cnt_end; //Delayed 10 frame data end flag
42  reg [3:0] frame_cnt;         //Frame counter
43  always @(posedge pclk or negedge rst_n)
44  begin
45      if(!rst_n)
46          begin
47              frame_cnt <= 0;
48              frame_cnt_end <= 0;
49          end
50      else if (frame_cnt == 10)
51          frame_cnt_end <= 1;
52      else if(nege_vsync)
53          frame_cnt <= frame_cnt + 1;
54      else
55          frame_cnt <= frame_cnt;
56  end
57 
58  reg [15:0] din_buffer2;
59  reg [7:0] din_buffer1;
60  reg byte_flag;
61  reg [10:0] cnt;
62  always @(posedge pclk or negedge rst_n)
63  begin
64      if(!rst_n)
65          begin
66              byte_flag <= 0;
67              din_buffer1 <= 0;
68              din_buffer2 <= 0;
69              cnt <= 0;
70          end
71      else if(href)   
72          begin
73              cnt <= cnt  + 1;
74              din_buffer1 <= din;
75              if(cnt >= 1278)
76                  byte_flag <= 0;
77              else
78                  byte_flag <= ~byte_flag;
79              
80              if(byte_flag == 1)
81                  din_buffer2 <= {din_buffer1,din};   
82              else
83                  din_buffer2 <= din_buffer2;
84          end
85      else
86          begin
87              byte_flag <= 0;
88              din_buffer1 <= 0;
89              din_buffer2 <= din_buffer2;
90              cnt <= 0;
91          end
92  end
93  
94  reg byte_flag_r;
95  always@(posedge pclk or negedge rst_n)
96  begin
97      if(!rst_n)
98          byte_flag_r <= 0;
99      else
100         byte_flag_r <= byte_flag;
101 end
102 
103 assign frame_data = frame_cnt_end & href ? din_buffer2 : 0;
104 assign frame_clk = frame_cnt_end ? byte_flag_r : 0;
105 assign frame_vsync = frame_cnt_end ? vsync_r : 1'b0;
106 assign frame_href = frame_cnt_end ? href_r : 1'b0;  
107
108 reg [27:0] delay_cnt;
109 always@(posedge pclk or negedge rst_n)
110 begin
111     if(!rst_n)
112         delay_cnt <= 0;
113     else if(delay_cnt < 48000000 - 1'b1)
114         delay_cnt <= delay_cnt + 1'b1;
115     else
116         delay_cnt <= 0;
117 end
118 wire    delay_2s = (delay_cnt == 48000000 - 1'b1) ? 1'b1 : 1'b0;
119 
120 reg [8:0] cmos_fps_cnt;
121 always @(posedge pclk or negedge rst_n)
122 begin
123     if(!rst_n)
124         begin
125             cmos_fps_cnt <= 0;
126             cmos_fps_rate <= 0;
127         end
128     else if(delay_2s == 1'b0)
129         begin
130             cmos_fps_cnt <= nege_vsync ? cmos_fps_cnt + 1'b1 : cmos_fps_cnt;
131             cmos_fps_rate <= cmos_fps_rate;
132         end
133     else
134         begin
135             cmos_fps_cnt <= 0;
136             cmos_fps_rate <= cmos_fps_cnt[8:1];
137         end
138 end
139 
140 endmodule

Main code of median filter module:

1  module zhongzhilvbo (clk, rst_n, data_in, fifo_empty, data_out, wrreq, rdreq);
2  
3   input clk;
4   input rst_n;
5   input [23:0] data_in;
6   input fifo_empty;
7   
8   output [7:0] data_out;
9   output reg wrreq;
10  output reg rdreq;
11  
12  reg [7:0] data [8:0];
13  wire [7:0] data_n[8:0];
14  reg shift;
15  
16  assign data_out = data_n[4];
17  
18  always @ (posedge clk or negedge rst_n)
19      begin
20          if (!rst_n)
21              begin
22                  data [8] <= 0; 
23                  data [7] <= 0; 
24                  data [6] <= 0; 
25                  data [5] <= 0; 
26                  data [4] <= 0; 
27                  data [3] <= 0; 
28                  data [2] <= 0; 
29                  data [1] <= 0;
30                  data [0] <= 0;
31              end
32          else
33              begin
34                  if (shift)
35                      begin
36                          data[8] <= data[5];
37                          data[7] <= data[4];
38                          data[6] <= data[3];
39                          data[5] <= data[2];
40                          data[4] <= data[1];
41                          data[3] <= data[0];
42                          data[2] <= data_in[23:16];
43                          data[1] <= data_in[15:8];
44                          data[0] <= data_in[7:0];
45                      end
46              end
47      end
48  
49  reg compara_rst_n;
50  genvar i;
51  reg [7:0] temp;
52  reg temp_rst_n;
53  reg [3:0] count;
54  
55  always @ (posedge clk or negedge temp_rst_n)
56      begin
57          if (!temp_rst_n)
58              begin
59                  temp <= data [8];
60                  count <= 0;
61              end
62          else                        
63              begin
64                  temp <= data[count];
65                  count <= count + 1;
66              end
67      
68      end
69  generate 
70      for (i = 0; i < 9; i = i + 1)
71          begin : compara
72              if (i == 0)
73                  begin
74                      comparaer u1(.clk(clk), .rst_n(compara_rst_n), .ex_data(temp), .up_data(8'hff), .self_data(data_n[i]));
75                  end
76              else
77                  begin
78                      comparaer comparaer(.clk(clk), .rst_n(compara_rst_n), .ex_data(temp), .up_data(data_n[i-1]), .self_data(data_n[i]));
79                  end
80          end
81  endgenerate
82  
83  reg [2:0] state;
84  reg [3:0] cnt;
85  
86  always @ (posedge clk or negedge rst_n)
87      begin
88          if (!rst_n)
89              begin
90                  rdreq <= 0;
91                  compara_rst_n <= 0;
92                  wrreq <= 0;
93                  state <= 0;
94                  shift <= 0;
95                  cnt <= 0;
96                  temp_rst_n <= 0;
97              end
98          else
99              begin
100                 case (state)
101                     0 : begin
102                             if (fifo_empty)
103                                 begin
104                                     state <= 0;
105                                     wrreq <= 0;
106                                     compara_rst_n <= 0;
107                                 end
108                             else
109                                 begin
110                                     state <= 1;
111                                     rdreq <= 1;
112                                     wrreq <= 0;
113                                     compara_rst_n <= 0;
114                                 end
115                         end
116                         
117                     1 : begin
118                             rdreq <= 0;
119                             shift <= 1;
120                             state <= 2;
121                         end
122                         
123                     2 : begin
124                             shift <= 0;
125                             temp_rst_n <= 1;
126                             state <= 3;
127                         end
128                     
129                     3 : begin
130                             if (cnt < 8)
131                                 begin
132                                     cnt <= cnt + 1;
133                                     compara_rst_n <= 1;
134                                     state <= 3;
135                                 end
136                             else
137                                 begin
138                                     cnt <= 0;
139                                     temp_rst_n <= 0;
140                                     state <= 4;
141                                 end
142                         end
143                     
144                     4 : begin
145                             wrreq <= 1;
146                             state <= 0;
147                         end
148                 
149                 endcase
150             end
151     end
152 endmodule

Main code of edge detection module:

1  module sob (clk, rst_n, data, result, fifo_wr, shift_en);
2   
3   input clk;
4   input rst_n;
5   input [23:0] data;
6   input shift_en;
7   
8   output reg [7:0] result;
9   output reg fifo_wr;
10  
11  
12  reg [7:0]   O[-1:1][-1:1];
13  reg signed  [10:0]  Dx, Dy;
14  
15  function [10:0] abs ( input signed [10:0] x);
16      abs = x >=0 ? x : -x ;        //Take the absolute value of x
17  endfunction
18  
19  always @ (posedge clk or negedge rst_n)
20      begin
21          if (!rst_n)
22              begin
23                  result <= 8'd0;
24                  Dx <= 0;
25                  Dy <= 0;
26              end
27          else
28              begin
29                  if ( shift_en )  
30                      begin
31                          result <= (abs(Dx) + abs(Dy))>>3 ;//Shift three bits to the right to divide by 8
32                          Dx  <= -$signed({3'b000, O[-1][-1]})    //-1* O[-1][-1]
33                                  +$signed({3'b000, O[-1][+1]})   //+1* O[-1][+1]
34                                  -($signed({3'b000, O[ 0][-1]})  //-2* O[ 0][-1]
35                                  <<1)
36                                  +($signed({3'b000, O[ 0][+1]})  //+2* O[ 0][+1]
37                                  <<1)        
38                                  -$signed({3'b000, O[+1][-1]})   //-1* O[+1][-1]
39                                  +$signed({3'b000, O[+1][+1]});  //+1* O[+1][+1]
40                          Dy  <= $signed({3'b000, O[-1][-1]}) //+1* O[-1][-1]
41                                  +($signed({3'b000, O[-1][ 0]})  //+2* O[-1][0]
42                                  <<1)        
43                                  +$signed({3'b000, O[-1][+1]})   //+1* O[-1][+1]
44                                  -$signed({3'b000, O[+1][-1]})//-1* O[+1][-1]
45                                  -($signed({3'b000, O[+1][ 0]})  //-2* O[+1][ 0]
46                                  <<1)    
47                                  -$signed({3'b000, O[+1][+1]});  //-1* O[+1][+1]
48                          O[-1][-1]   <=  O[-1][0];
49                          O[-1][ 0]   <=  O[-1][+1];
50                          O[-1][+1]   <=  data[23:16];
51                          O[ 0][-1]   <=  O[0][0];                
52                          O[ 0][ 0]   <=  O[0][+1];
53                          O[ 0][+1]   <=  data[15:8];
54                          O[+1][-1]   <=  O[+1][0];
55                          O[+1][ 0]   <=  O[+1][+1];
56                          O[+1][+1]   <=  data[7:0];
57              end
58          end
59      end
60 
61  
62 
63  reg [2:0] state;
64  
65  always @ (posedge clk or negedge rst_n) 
66      begin
67          if (!rst_n)
68              begin
69                  fifo_wr <= 1'b0;
70                  state <= 0;
71              end
72          else
73              begin
74                  case (state)
75                      0 : begin
76                              if (shift_en)
77                                  begin
78                                      state <= 2;
79                                      fifo_wr <= 0;
80                                  end
81                              else
82                                  begin
83                                      state <= 0;
84                                      fifo_wr <= 0;
85                                  end
86                      end
87                      
88                      1 : begin
89                                  if (shift_en)
90                                      begin
91                                          fifo_wr <= 1'b1;
92                                      end
93                                  else
94                                      fifo_wr <= 0;
95                          end
96                      
97                      2 : state <= 3;
98                      
99                      3 : state <= 4;
100                     
101                     4 : state <= 1;
102                     
103                     default : state <= 0;
104                     
105                 endcase
106             end
107     end
108     
109 endmodule

Main code of image cache module:

1  `include "sdram_head.v"
2  
3  module sdr_fsm(soft_rst_n, sys_clk, init_done, ref_done, rd_done, wr_done, ref_time, mux_sel,
4           init_rst_n, ref_rst_n, rd_rst_n, wr_rst_n, time_rst_n, int_addr,
5            local_rdreq, local_wrreq, local_ready,wr_ddr,rd_ddr,rd_finish, wr_finish,local_finish);
6  
7   input soft_rst_n;
8   input sys_clk;
9   input init_done;
10  input ref_done;
11  input rd_done;
12  input wr_done;
13  input [9:0] ref_time;
14  input [24:0] wr_ddr;
15  input [24:0] rd_ddr;
16  
17 //   input [24:0] local_addr;
18 //   output reg [31:0] local_rdata;
19 //   input [31:0] local_wdata;
20  input local_rdreq, local_wrreq;
21  output reg local_ready,local_finish;
22  output reg rd_finish;
23  output reg wr_finish;
24  
25  output reg [1:0] mux_sel;
26  output reg init_rst_n;
27  output reg ref_rst_n;
28  output reg rd_rst_n;
29  output reg wr_rst_n;
30  output reg time_rst_n;
31 //   output reg [31:0] wr_data;
32  output reg [24:0] int_addr;
33  
34  localparam s0 = 3'b000;
35  localparam s1 = 3'b001;
36  localparam s2 = 3'b010;
37  localparam s3 = 3'b011;
38  localparam s4 = 3'b100;
39 
40  reg [2:0] state;
41  
42  reg rd,rd_en;
43  
44  always @ (posedge sys_clk)
45      begin
46          if (!soft_rst_n)
47              begin
48                  rd <= 0;
49              end
50          else
51              begin
52                  if (local_rdreq && rd_en)
53                      rd <= local_rdreq;
54                  else
55                      if (!rd_en)
56                          rd <= 0;
57                      else
58                          rd <= rd;
59              end
60      end
61  
62      reg wr,wr_en;
63  
64  always @ (posedge sys_clk)
65      begin
66          if (!soft_rst_n)
67              begin
68                  wr <= 0;
69              end
70          else
71              begin
72                  if (local_wrreq && wr_en)
73                      wr <= local_wrreq;
74                  else
75                      if (!wr_en)
76                          wr <= 0;
77                      else
78                          wr <= wr;
79              end
80      end
81  
82  
83  always @ (posedge sys_clk)
84  begin
85      if (!soft_rst_n)
86          begin
87              mux_sel <= `INIT;
88              init_rst_n <= 0;
89              ref_rst_n <= 0;
90              wr_rst_n <= 0;
91              rd_rst_n <= 0;
92              time_rst_n <= 0;
93              state <= s0;
94 //               local_rdata <= 32'd0;
95              local_ready <= 0;       
96              rd_finish <= 0;  
97              wr_finish <= 0;
98 //               wr_data <= 32'd0;
99              int_addr <= 25'd0;
100             wr_en <= 1;
101             rd_en <= 1;
102             local_finish <= 0;
103         end
104     else
105         case (state)
106         s0 :  if (!init_done)
107                     init_rst_n <= 1;
108                 else  
109                     begin
110                         init_rst_n <= 0;
111                         mux_sel <= `REF;
112                         time_rst_n <= 1;
113                         state <= s1;
114                         local_ready <= 1;
115                         wr_en <= 1;
116                         rd_en <= 1;
117                     end
118                     
119         s1 :  if ((ref_time < `ctREFR) && (!wr) && (!rd)) 
120                     state <= s1;
121                 else if (rd)    
122                     begin
123                         int_addr <= rd_ddr;
124                         rd_rst_n <= 1;
125                         mux_sel <= `READ;
126                         local_ready <= 0;
127                         rd_finish <= 0;
128                         state <= s3;
129                         rd_en <= 0;
130                     end 
131                 else if (wr)    
132                     begin
133                         int_addr <= wr_ddr;
134//                           wr_data <= local_wdata;
135                         wr_rst_n <= 1;
136                         mux_sel <= `WRITE;
137                         local_ready <= 0;
138                         wr_finish <= 0;
139                         state <= s4;
140                         wr_en <= 0;
141                     end                         
142                 else if (ref_time >= `ctREFR)
143                     begin
144                         ref_rst_n <= 1;                                     
145                         time_rst_n <= 0;    
146                         mux_sel <= `REF;
147                         state <= s2;
148                         local_ready <= 0;   
149                         local_finish <= 0;                      
150                     end
151         
152         s2 :    if (!ref_done)
153                     state <= s2;
154                 else
155                     begin
156                         state <= s1;
157                         time_rst_n <= 1;
158                         ref_rst_n <= 0;
159                         local_finish <= 1;
160                         local_ready <= 1;   
161                     end
162         
163         s3 :    if (!rd_done)
164                     state <= s3;
165                 else
166                     begin
167                         local_ready <= 1;
168                         rd_finish <= 1;
169                         rd_rst_n <= 0;
170//                           local_rdata <= rd_data;
171                         state <= s1;
172                         rd_en <= 1;
173                     end
174         
175         s4 :    if (!wr_done)
176                     state <= s4;
177                 else
178                     begin
179                         local_ready <= 1;
180                         wr_finish <= 1;
181                         wr_rst_n <= 0;
182                         state <= s1;
183                         wr_en <= 1;
184                     end
185         
186         default : state <= s0;
187         endcase
188 end
189 endmodule

Main code of image real-time display module:

1 module lcd_driver
2 (     
3   //global clock
4   input           clk,            //system clock
5   input           rst_n,          //sync reset
6   
7   //lcd interface
8   output          lcd_dclk,       //lcd pixel clock
9   output          lcd_blank,      //lcd blank
10  output          lcd_sync,       //lcd sync
11  output          lcd_hs,         //lcd horizontal sync
12  output          lcd_vs,         //lcd vertical sync
13  output          lcd_en,         //lcd display enable
14  output  [15:0]  lcd_rgb,        //lcd display data
15
16  //user interface
17  output          lcd_request,    //lcd data request
18  output  [10:0]  lcd_xpos,       //lcd horizontal coordinate
19  output  [10:0]  lcd_ypos,       //lcd vertical coordinate
20  input   [15:0]  lcd_data        //lcd data
21);     
22`include "lcd_para.v"  
23
24/*******************************************
25      SYNC--BACK--DISP--FRONT
26*******************************************/
27//------------------------------------------
28//h_sync counter & generator
29 reg [10:0] hcnt; 
30 always @ (posedge clk or negedge rst_n)
31 begin
32  if (!rst_n)
33      hcnt <= 11'd0;
34  else
35      begin
36        if(hcnt < `H_TOTAL - 1'b1)        //line over         
37            hcnt <= hcnt + 1'b1;
38        else
39            hcnt <= 11'd0;
40      end
41 end 
42 assign   lcd_hs = (hcnt <= `H_SYNC - 1'b1) ? 1'b0 : 1'b1;
43
44//------------------------------------------
45//v_sync counter & generator
46 reg [10:0] vcnt;
47 always@(posedge clk or negedge rst_n)
48 begin
49  if (!rst_n)
50      vcnt <= 11'b0;
51  else if(hcnt == `H_TOTAL - 1'b1)        //line over
52      begin
53      if(vcnt < `V_TOTAL - 1'b1)      //frame over
54          vcnt <= vcnt + 1'b1;
55      else
56          vcnt <= 11'd0;
57      end
58 end
59 assign   lcd_vs = (vcnt <= `V_SYNC - 1'b1) ? 1'b0 : 1'b1;
60
61//------------------------------------------
62//LCELL   LCELL(.in(clk),.out(lcd_dclk));
63 assign   lcd_dclk = ~clk;
64 assign   lcd_blank = lcd_hs & lcd_vs;        
65 assign   lcd_sync = 1'b0;
66
67//-----------------------------------------
68 assign   lcd_en      =   (hcnt >= `H_SYNC + `H_BACK  && hcnt < `H_SYNC + `H_BACK + `H_DISP) &&
69                      (vcnt >= `V_SYNC + `V_BACK  && vcnt < `V_SYNC + `V_BACK + `V_DISP) 
70                      ? 1'b1 : 1'b0;
71 assign   lcd_rgb     =   lcd_en ? (lcd_data > 5) ? 16'd0 : 16'hffff : 16'd0;
72////assign    lcd_rgb     =   lcd_en ? {lcd_data[10:6],lcd_data[10:5],lcd_data[10:6]} : 16'd0;
73//assign  lcd_rgb     =   lcd_en ? {lcd_data[7:3],lcd_data[7:2],lcd_data[7:3]} : 16'd0;
74//assign  lcd_rgb     =   lcd_en ? lcd_data : 16'd0;
75
76//------------------------------------------
77//ahead x clock
78 localparam   H_AHEAD = 2'd1;
79 assign   lcd_request =   (hcnt >= `H_SYNC + `H_BACK - H_AHEAD && hcnt < `H_SYNC + `H_BACK + `H_DISP - H_AHEAD) &&
80                      (vcnt >= `V_SYNC + `V_BACK && vcnt < `V_SYNC + `V_BACK + `V_DISP) 
81                      ? 1'b1 : 1'b0;
82//-----------------------------------------
83//lcd xpos & ypos
84 assign   lcd_xpos    =   lcd_request ? (hcnt - (`H_SYNC + `H_BACK - 1'b1)) : 11'd0;
85 assign   lcd_ypos    =   lcd_request ? (vcnt - (`V_SYNC + `V_BACK - 1'b1)) : 11'd0;
86 endmodule

This is the end of this article. The design of real-time image edge detection system based on FPGA is introduced. Great Xia, pay attention and don't get lost. Goodbye.

[QQ communication group]

Group number: 173560979, group entry code: Jianghu fans of FPGA technology.

With many years of FPGA enterprise development experience, various easy to understand learning materials and methods, and a strong exchange and learning atmosphere, QQ group has more than 1000 like-minded partners. There is no advertising pure mode, which provides a pure land for technical exchange, from novice Xiaobai to elite industry leaders, from military industry to civil enterprises, from communication It has everything from image processing to artificial intelligence.

[wechat communication group]

Now WeChat communication group has established 09 groups, with a total of thousands of people. Welcome to pay attention to the WeChat official account of FPGA technology, and get access to the group.

finish

The follow-up will be continuously updated, bringing installation related design tutorials such as Vivado, ISE, Quartus II and candence, learning resources, project resources, good article recommendations, etc. I hope you will continue to pay attention.

The Jianghu is so big. Continue to wander. I wish you all the best. Goodbye!

Topics: image processing