当前位置:   article > 正文

移位寄存器

移位寄存器

前言

        移位寄存器(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拉高。

  1. module counter(
  2. input clk,
  3. input rst_n,
  4. output reg [7:0]cnt,//rom地址
  5. output reg shift_en//Shift_register使能信号
  6. );
  7. always @(posedge clk,negedge rst_n)
  8. begin
  9. if(rst_n == 0)
  10. begin
  11. cnt <= 8'd0;
  12. shift_en <= 1'b0;
  13. end
  14. else
  15. begin
  16. if(cnt >= 16)//地址>16时Shift_register开始输出
  17. begin
  18. cnt <= cnt + 8'd1;
  19. shift_en <= 1'b1;
  20. end
  21. else
  22. cnt <= cnt + 8'd1;
  23. end
  24. end
  25. endmodule

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

  1. module shift_register(
  2. input clk,
  3. input rst_n,
  4. input [7:0]in,
  5. input shift_en,
  6. output [7:0]shifout1,
  7. output [7:0]shifout2,
  8. output [7:0]shifout3
  9. );
  10. wire [15:0]taps;
  11. assign shifout1 = shift_en?in :8'd0;//16、17、18...地址数据
  12. assign shifout2 = shift_en?taps[ 7:0]:8'd0;//8910...地址数据
  13. assign shifout3 = shift_en?taps[15:8]:8'd0;//0、1、2...地址数据
  14. my_shift my_shift_inst (
  15. .clock ( clk ),
  16. .shiftin ( in ),
  17. .shiftout ( ),
  18. .taps ( taps )
  19. );
  20. endmodule

        shift_reg模块:顶层连线

  1. module shift_reg(
  2. input clk,
  3. input rst_n,
  4. output [7:0]shiftout1,
  5. output [7:0]shiftout2,
  6. output [7:0]shiftout3
  7. );
  8. wire [7:0]cnt;
  9. wire [7:0]in;
  10. wire shift_en;
  11. my_rom my_rom_inst (
  12. .address ( cnt ),
  13. .clock ( clk ),
  14. .q ( in )
  15. );
  16. counter counter_inst(
  17. .clk(clk),
  18. .rst_n(rst_n),
  19. .cnt(cnt),
  20. .shift_en(shift_en)
  21. );
  22. shift_register shift_register_inst(
  23. .clk(clk),
  24. .rst_n(rst_n),
  25. .in(in),
  26. .shift_en(shift_en),
  27. .shifout1(shiftout1),
  28. .shifout2(shiftout2),
  29. .shifout3(shiftout3)
  30. );
  31. endmodule

        仿真模块

  1. `timescale 1ns/1ps
  2. module shift_reg_tb;
  3. reg clk;
  4. reg rst_n;
  5. wire [7:0]shiftout1;
  6. wire [7:0]shiftout2;
  7. wire [7:0]shiftout3;
  8. shift_reg shift_reg_inst(
  9. .clk(clk),
  10. .rst_n(rst_n),
  11. .shiftout1(shiftout1),
  12. .shiftout2(shiftout2),
  13. .shiftout3(shiftout3)
  14. );
  15. initial clk = 1;
  16. always #10 clk = ~clk;
  17. initial begin
  18. rst_n = 0;
  19. #20
  20. rst_n = 1;
  21. #1000
  22. $stop;
  23. end
  24. endmodule

三、仿真验证

运行modelsim进行仿真,可以看到有数据产生,对照rom的mif文件,产生数据正确,调出其他模块信号进行观察。

可以看到在cnt=16的时钟上升沿,en拉高,Shift_register开始输出。

参考资料

移位寄存器存储器

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/961021
推荐阅读
相关标签
  

闽ICP备14008679号