问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

FPGA开发实战:使用Altera IP核实现图像处理中的移位寄存器功能

创作时间:
作者:
@小白创作中心

FPGA开发实战:使用Altera IP核实现图像处理中的移位寄存器功能

引用
CSDN
1.
https://blog.csdn.net/m0_66619666/article/details/140622130

移位寄存器是数字电路中一种重要的数据存储和移动组件,在图像处理等领域有着广泛的应用。本文通过一个具体的项目需求(图像处理中的3x3模板运算),详细介绍了如何使用Altera提供的IP核来实现数据移位功能,包括系统架构设计、代码实现和仿真验证过程。

前言

移位寄存器(Shift Register)是一种数字电路组件,广泛用于计算机和电子系统中。它主要用于在数字电路中存储和移动数据。移位寄存器可以在其内部存储多个二进制位,并通过串行或并行方式将数据移位(即向左或向右移动)到寄存器的不同位置。在进行图像算法处理时,如Sobel图像边缘检测、中值滤波、均值滤波等,经常需要用到模板运算,这时可以借用Altera提供的移位寄存器IP核来简化设计,提高设计效率。

正文

一、移位寄存器

1.项目需求

假设图像数据存储在一个ROM中。比如下图所示的排列方式,行加列的值作为该数据的地址。
在图像处理领域,要实现Sobel或者均值滤波等算法,需要按照3*3矩形的格式提取数据。

2.技术介绍

这里可以使用Shift_register的IP核来实现功能

In[7:0]是从ROM中读出的数据,用一个计数器作为ROM的地址,每次地址加1,将移位寄存器比作“FIFO”,在计数器记到16时,In[7:0]当前数据为地址16的数据,此时在Shiftout0[7:0]输出该数据,在Shiftout1[7:0]输出地址为8的数据,Shiftout2[7:0]输出地址为0的数据。在后续计数会依次输出1、9、17地址上的数据,直到扫描完整个ROM。
IP核调用参考上图数据,选择shift register(RAM-based)
设置位宽8位,需要2个taps,并勾选生成inst文件。

3.顶层架构

Counter模块产生ROM地址,En在计数器记到16后拉高,Shift_register中调用IP核Shift_register,对ROM的数据进行移位并输出,计数器16之前Shift_register的输出未定,故此时En拉低,16之后输出稳定,En使能。

4.端口描述

Clk 系统时钟
Rst_n 复位按键(低电平有效)
Shiftout0[7:0] 地址16、17、18...数据
Shiftout1[7:0] 地址8、9、10...数据
Shiftout2[7:0] 地址0、1、2、3...数据

二、代码验证

Counter模块:产生ROM地址数据,计数16时En拉高。

module counter(
    input Clk,
    input Rst_n,
    
    output reg [7:0]Cnt,//ROM地址
    output reg Shift_en//Shift_register使能信号
    
);
always @(posedge Clk,negedge Rst_n)
begin
    if(Rst_n == 0)
        begin
            Cnt <= 8'd0;
            Shift_en <= 1'b0;
        end
    else
        begin
            if(Cnt >= 16)//地址>16时Shift_register开始输出
                begin 
                    Cnt <= Cnt + 8'd1;
                    Shift_en <= 1'b1;
                end
            else
                Cnt <= Cnt + 8'd1;
        end
end
endmodule  

Shift_register模块:调用IP核Shift_register进行数据处理。

module shift_register(
    input Clk,
    input Rst_n,
    input [7:0]In,
    input Shift_en,
    
    output [7:0]Shifout1,
    output [7:0]Shifout2,
    output [7:0]Shifout3
);
wire [15:0]Taps;
assign Shifout1 = Shift_en?In	:8'd0;//16、17、18...地址数据
assign Shifout2 = Shift_en?Taps[ 7:0]:8'd0;//8、9、10...地址数据
assign Shifout3 = Shift_en?Taps[15:8]:8'd0;//0、1、2...地址数据
my_shift	my_shift_inst (
    .Clock ( Clk ),
    .Shiftin ( In ),
    .Shiftout (  ),
    .Taps ( Taps )
    );
endmodule  

Shift_reg模块:顶层连线

module shift_reg(
    input Clk,
    input Rst_n,
    
    output [7:0]Shiftout1,
    output [7:0]Shiftout2,
    output [7:0]Shiftout3
    
);
wire [7:0]Cnt;
wire [7:0]In;
wire Shift_en;
my_rom	my_rom_inst (
    .Address ( Cnt ),
    .Clock ( Clk ),
    .Q ( In )
    );
counter counter_inst(
    .Clk(Clk),
    .Rst_n(Rst_n),
    .Cnt(Cnt),
    .Shift_en(Shift_en)
    
);
shift_register shift_register_inst(
    .Clk(Clk),
    .Rst_n(Rst_n),
    .In(In),
    .Shift_en(Shift_en),
    
    .Shifout1(Shiftout1),
    .Shifout2(Shiftout2),
    .Shifout3(Shiftout3)
);
endmodule  

仿真模块

`timescale 1ns/1ps
module shift_reg_tb;
    reg Clk;
    reg Rst_n;
    
    wire [7:0]Shiftout1;
    wire [7:0]Shiftout2;
    wire [7:0]Shiftout3;
shift_reg shift_reg_inst(
    .Clk(Clk),
    .Rst_n(Rst_n),
    
    .Shiftout1(Shiftout1),
    .Shiftout2(Shiftout2),
    .Shiftout3(Shiftout3)
    
);
    
initial Clk = 1;
always #10 Clk = ~Clk;
    
initial begin
    Rst_n = 0;
    #20
    Rst_n = 1;
    #1000
    $stop;
end
endmodule  

三、仿真验证

运行Modelsim进行仿真,可以看到有数据产生,对照ROM的MIF文件,产生数据正确,调出其他模块信号进行观察。
可以看到在Cnt=16的时钟上升沿,En拉高,Shift_register开始输出。

参考资料

移位寄存器存储器

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号