赞
踩
移位寄存器(Shift Register)是一种数字电路组件,广泛用于计算机和电子系统中。它主要用于在数字电路中存储和移动数据。移位寄存器可以在其内部存储多个二进制位,并通过串行或并行方式将数据移位(即向左或向右移动)到寄存器的不同位置。做很多图像算法时,经常需要用到模板运算,如Sobel图像边缘检测、中值滤波、均值滤波的处理这些问题时,可以借用Altera提供的移位寄存器ip核来简化设计,提高设计效率。
假设图像数据在一个rom中。比如下图所示排放,行加列的值作为该数据的地址。
在图像处理邻域,要实现Sobel或者均值滤波等算法,需要按照3*3矩形的格式提取数据。
这里可以使用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文件。
counter模块产生rom地址,en在计数器记到16后拉高,shift_register中调用ip核Shift_register,对rom的数据进行移位并输出,计数器16之前shift_register的输出未定,故此时en拉低,16之后输出稳定,en使能。
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开始输出。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。