FPGA开发实战:使用Altera IP核实现图像处理中的移位寄存器功能
FPGA开发实战:使用Altera IP核实现图像处理中的移位寄存器功能
移位寄存器是数字电路中一种重要的数据存储和移动组件,在图像处理等领域有着广泛的应用。本文通过一个具体的项目需求(图像处理中的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开始输出。
参考资料
移位寄存器存储器