基于fpga的图像处理之3x3_5x5算子模板设计

本文的思路框架:
①本文采用支持3x3算子模块和5x5算子模块的生成,用于后一级别的算法输入
②本例程中采用的FPGA设计技巧,可用于借鉴,一是generate if参数定义;二是调用xilinx和altera的sync fifo和async fifo原语实现不同平台同步fifo和异步fifo的功能,省去ip核的调用,简化代码移植

一、算子模板基础知识

在图像处理过程中,需要对图像进行滤波操作,在进行滤波操作通常使用算子模板,即扫描窗模板,一般有 3x3、5x5 等模板形式
3x3算子模板
基于fpga的图像处理之3x3_5x5算子模板设计_第1张图片
5x5算子模板
基于fpga的图像处理之3x3_5x5算子模板设计_第2张图片

二、FPGA设计思路

使用 FIFO 来缓存图像的行数据,如果取 3x3 的模板,那么至少需要两个深度大于图像行数据的长度的 FIFO,通过首尾相连的形式来缓存两行数据,等第三行数据到来之时,同时输出三行数据。
同理如果是5x5的模板,需要四个深度大于行数据长度的FIFO,通过收尾相连的形式来缓存四行数据,等第五行数据到来之时,同时输出五行数据。其余类推即可。
3x3模板设计及部分代码分析
基于fpga的图像处理之3x3_5x5算子模板设计_第3张图片
代码实现功能分析:
基于fpga的图像处理之3x3_5x5算子模板设计_第4张图片
基于fpga的图像处理之3x3_5x5算子模板设计_第5张图片

三、FPGA设计技巧

1、generate if参数定义,未选择部分,eda软件会自动优化掉,不会造成逻辑资源浪费。

2、调用xilinx和altera的sync fifo和async fifo原语实现不同平台同步fifo和异步fifo的功能,省去ip核的调用,简化代码移植
①xilinx sync fifo和async fifo的原语调用

generate
    if(ASYNC_CLK == 1)
        begin : ASYNC_FIFO    
            xpm_fifo_async #(
                .CDC_SYNC_STAGES(3),       // DECIMAL
                .DOUT_RESET_VALUE("0"),    // String
                .ECC_MODE("no_ecc"),       // String
                .FIFO_MEMORY_TYPE(FIFO_MEMORY_TYPE), // String
                .FIFO_READ_LATENCY(FIFO_READ_LATENCY),     // DECIMAL
                .FIFO_WRITE_DEPTH(FIFO_DEPTH),   // DECIMAL
                .FULL_RESET_VALUE(1),      // DECIMAL
                .PROG_EMPTY_THRESH(5),    // DECIMAL
                .PROG_FULL_THRESH(PROG_FULL_THRESH),     // DECIMAL
                .RD_DATA_COUNT_WIDTH(COUNT_WIDTH),   // DECIMAL
                .READ_DATA_WIDTH(WRITE_DATA_WIDTH),      // DECIMAL
                .READ_MODE(FIFO_READ_MODE),         // String
                .RELATED_CLOCKS(0),        // DECIMAL
                .SIM_ASSERT_CHK(0),        // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
                .USE_ADV_FEATURES("1707"), // String
                .WAKEUP_TIME(0),           // DECIMAL
                .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH),     // DECIMAL
                .WR_DATA_COUNT_WIDTH(COUNT_WIDTH)    // DECIMAL
            )
            xpm_fifo_inst (
                .almost_empty            (),    //unused                       
                .almost_full            (),    //unused
                .data_valid                (),
                .dbiterr                (),            
                .dout                    (o_rd_data                ),                 
                .empty                    (o_rd_empty                ),                
                .full                    (o_wr_full                ),                  
                .overflow                (),          
                .prog_empty                (o_rd_arempty            ),      
                .prog_full                (o_wr_awfull            ),        
                .rd_data_count            (o_rd_cnt                ),
                .rd_rst_busy            (),    
                .sbiterr                (),            
                .underflow                (),        
                .wr_ack                    (),   //unused                
                .wr_data_count            (o_wr_cnt                ),
                .wr_rst_busy            (),    
                .din                    (i_wr_data                ),                    
                .injectdbiterr            (1'b0),
                .injectsbiterr            (1'b0),
                .rd_clk                    (i_rd_clk                ),              
                .rd_en                    (i_rd_en                ),                
                .rst                    (i_wr_rst || i_rd_rst    ),                    
                .sleep                    (1'b0),                
                .wr_clk                    (i_wr_clk                ),              
                .wr_en                    (i_wr_en                )                            
            );
        end
   // End of xpm_fifo_async_inst instantiation
    else begin : SYNC_FIFO
            xpm_fifo_sync #(
                .DOUT_RESET_VALUE("0"),    // String
                .ECC_MODE("no_ecc"),       // String
                .FIFO_MEMORY_TYPE(FIFO_MEMORY_TYPE), // String
                .FIFO_READ_LATENCY(FIFO_READ_LATENCY),     // DECIMAL
                .FIFO_WRITE_DEPTH(FIFO_DEPTH),   // DECIMAL
                .FULL_RESET_VALUE(1),      // DECIMAL
                .PROG_EMPTY_THRESH(5),    // DECIMAL
                .PROG_FULL_THRESH(PROG_FULL_THRESH),     // DECIMAL
                .RD_DATA_COUNT_WIDTH(COUNT_WIDTH),   // DECIMAL
                .READ_DATA_WIDTH(WRITE_DATA_WIDTH),      // DECIMAL
                .READ_MODE(FIFO_READ_MODE),         // String
                .SIM_ASSERT_CHK(0),        // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
                .USE_ADV_FEATURES("1707"), // String
                .WAKEUP_TIME(0),           // DECIMAL
                .WRITE_DATA_WIDTH(WRITE_DATA_WIDTH),     // DECIMAL
                .WR_DATA_COUNT_WIDTH(COUNT_WIDTH)    // DECIMAL
            )
            xpm_fifo_inst (
                .almost_empty            (),    //unused                       
                .almost_full            (),    //unused
                .data_valid                (),   
                .dbiterr                (),            
                .dout                    (o_rd_data                ),                  
                .empty                    (o_rd_empty                ),                
                .full                    (o_wr_full                ),                  
                .overflow                (),          
                .prog_empty                (o_rd_arempty            ),      
                .prog_full                (o_wr_awfull            ),        
                .rd_data_count            (o_rd_cnt                ),
                .rd_rst_busy            (),    
                .sbiterr                (),            
                .underflow                (),        
                .wr_ack                    (),    //unused                
                .wr_data_count            (o_wr_cnt                ),
                .wr_rst_busy            (),    
                .din                    (i_wr_data                ),                    
                .injectdbiterr            (1'b0),
                .injectsbiterr            (1'b0),
                .rd_en                    (i_rd_en                ),                
                .rst                    (i_wr_rst                ),                    
                .sleep                    (1'b0),                
                .wr_clk                    (i_wr_clk                ),              
                .wr_en                    (i_wr_en                )                 
            );
         end
endgenerate

②altera sync fifo和async fifo的原语调用

generate     
    if(ASYNC_CLK == 1)
        begin  : ASYNC_FIFO    
            dcfifo dcfifo_component (
                .rdclk             (i_rd_clk        ),
                .wrclk             (i_wr_clk        ),
                .wrreq             (i_wr_en        ),
                .data             (i_wr_data        ),
                .rdreq             (i_rd_en        ),
                .wrempty         (o_rd_empty        ),
                .wrfull         (o_wr_full        ),
                .q                 (o_rd_data        ),
                .rdempty         (o_rd_arempty    ),
                .rdfull         (o_wr_awfull    ),
                .wrusedw         (o_wr_cnt        ),
                .rdusedw         (o_rd_cnt        ),
                .aclr             (                )
            );
            defparam
                dcfifo_component.intended_device_family = DEVICE,
                dcfifo_component.lpm_numwords = FIFO_DEPTH,
                dcfifo_component.lpm_showahead = FIFO_READ_MODE,
                dcfifo_component.lpm_type = "dcfifo",
                dcfifo_component.lpm_width = DATA_WIDTH,
                dcfifo_component.lpm_widthu = ADDR_WIDTH,
                dcfifo_component.overflow_checking = "ON",
                dcfifo_component.rdsync_delaypipe = 3,
                dcfifo_component.underflow_checking = "ON",
                dcfifo_component.use_eab = "ON",
                dcfifo_component.wrsync_delaypipe = 3;            
        end
   // End of xpm_fifo_async_inst instantiation
    else begin : SYNC_FIFO    
            scfifo    scfifo_component(
                .clock             (i_wr_clk        ),
                .sclr             (i_wr_rst        ),
                .wrreq             (i_wr_en        ),
                .data            (i_wr_data        ),
                .rdreq             (i_rd_en        ),
                .usedw             (o_wr_cnt        ),
                .empty             (o_rd_empty        ),
                .full             (o_wr_full        ),
                .q                 (o_rd_data        ),
                .almost_empty     (o_rd_arempty    ),
                .almost_full     (o_wr_awfull    ),
                .aclr            (                )
            );
            defparam
                scfifo_component.add_ram_output_register = "OFF",
                scfifo_component.almost_empty_value = 2,
                scfifo_component.almost_full_value = PROG_FULL_THRESH,
                scfifo_component.intended_device_family = DEVICE,
                scfifo_component.lpm_numwords = FIFO_DEPTH,
                scfifo_component.lpm_showahead = FIFO_READ_MODE,
                scfifo_component.lpm_type = "scfifo",
                scfifo_component.lpm_width = DATA_WIDTH,
                scfifo_component.lpm_widthu = ADDR_WIDTH,
                scfifo_component.overflow_checking = "ON",
                scfifo_component.underflow_checking = "ON",
                scfifo_component.use_eab = "ON";    
         end
endgenerate      

③xilinx和altera平台fifo选择

generate
    if(DEVICE_CHOODE == "xilinx")
        begin : XILINX    
            xilinx_fifo #(
                .DATA_WIDTH      (DATA_WIDTH        ),
                .ASYNC_CLK         (ASYNC_CLK        ),
                .ADDR_WIDTH      (ADDR_WIDTH        ),
                .READ_MODE         (READ_MODE        )//0:STA fifo  1:FWFT
            )xilinx_fifo_init(
                .i_wr_clk        (i_wr_clk        ),
                .i_wr_rst        (i_wr_rst        ),
                .i_wr_en        (i_wr_en        ),
                .i_wr_data        (i_wr_data        ),
                .o_wr_cnt        (o_wr_cnt        ),
                .o_wr_full        (o_wr_full        ),
                .o_wr_awfull    (o_wr_awfull    ),    
                .i_rd_clk        (i_rd_clk        ),
                .i_rd_rst        (i_rd_rst        ),
                .i_rd_en        (i_rd_en        ),
                .o_rd_data        (o_rd_data        ),
                .o_rd_cnt        (o_rd_cnt        ),
                .o_rd_empty        (o_rd_empty        ),
                .o_rd_arempty    (o_rd_arempty    )    
            );        
        end
    else begin : ALTERA
                altera_fifo #(
                    .DATA_WIDTH      (DATA_WIDTH        ),
                    .ASYNC_CLK         (ASYNC_CLK        ),
                    .ADDR_WIDTH      (ADDR_WIDTH        ),
                    .READ_MODE         (READ_MODE        )//0:STA fifo  1:FWFT
                )altera_fifo_init(
                    .i_wr_clk        (i_wr_clk        ),
                    .i_wr_rst        (i_wr_rst        ),
                    .i_wr_en        (i_wr_en        ),
                    .i_wr_data        (i_wr_data        ),
                    .o_wr_cnt        (o_wr_cnt        ),
                    .o_wr_full        (o_wr_full        ),
                    .o_wr_awfull    (o_wr_awfull    ),    
                    .i_rd_clk        (i_rd_clk        ),
                    .i_rd_rst        (i_rd_rst        ),
                    .i_rd_en        (i_rd_en        ),
                    .o_rd_data        (o_rd_data        ),
                    .o_rd_cnt        (o_rd_cnt        ),
                    .o_rd_empty        (o_rd_empty        ),
                    .o_rd_arempty    (o_rd_arempty    )    
                );        
            end
endgenerate

④xilinx vivado平台开发及仿真验证
基于fpga的图像处理之3x3_5x5算子模板设计_第6张图片
基于fpga的图像处理之3x3_5x5算子模板设计_第7张图片
⑤altera quartus平台开发及仿真验证

基于fpga的图像处理之3x3_5x5算子模板设计_第8张图片
基于fpga的图像处理之3x3_5x5算子模板设计_第9张图片

你可能感兴趣的:(FPGA工程项目,fpga开发,图像处理,人工智能)