移位寄存器
移位寄存器内的数据可以在移位脉冲(时钟信号)的作用下依次左移或右移。移位寄存器不仅可以存储数据,还可以用来实现数据的串并转换、分频,构成序列码发生器、序列码检测器,进行数值运算以及数据处理等,它也是数字系统中应用非常广泛的时序逻辑部件之一。
移位寄存器按数据移位方向可以分为左移寄存器、右移寄存器、也可以根据数据输入、输出方式分为并行输入/串行输出、串行输入/并行输出、串行输入/串行输出、并行输入/并行输出。
下图是一个4位右移位寄存器的逻辑电路图。其工作原理为:串行数据从触发器DI端输入,触发器FA的状态方程为:。其余触发器的状态方程分别为,,。可见,右移位寄存器的特点是右边寄存器的次态等于左边触发器的现态。串行输出数据从触发器FD的QD端输出,并行数据从个触发器的QA~QD端输出,两种输出方式都属于同向输出。各触发器都采用同一时钟信号,所以它们工作在同步状态。如果将FD的输出端QD接到FA的输入端DI,则可以构成循环移位的右移位寄存器。
4位右移位寄存器逻辑电路
1、 16位右移位寄存器
下面描述的是一个位宽为16位的右移位寄存器,实际具有环形移位的功能,是在右移位寄存器的基础上将最低位的输出端接到最高位的输入端构成的。其功能为当时钟上升沿到达时,输入信号的最低位移位到最高位,其余各位依次向右移动一位。
其verilog HDL设计代码如下:
1. module register_right(clk, din, dout); 2. input clk; 3. input [15:0] din; 4. output [15:0] dout; 5. reg [15:0] dout; 6. 7. always @(posedge clk) 8. begin 9. dout <= {din[0], din[15:1]}; 10. end 11. endmodule
其测试文件为:
1. `timescale 1ns/1ps 2. module register_right_tb; 3. reg clk; 4. reg [15:0] din; 5. wire [15:0] dout; 6. always 7. begin 8. #10 clk = ~clk; 9. end 10. initial 11. begin 12. clk = 1'b0; 13. din = 16'b0000_0000_0000_0000; 14. #10 din = 16'b0000_0000_0000_1011; 15. #20 din = 16'b0000_0000_0111_0000; 16. #20 din = 16'b0000_0000_0000_0011; 17. #100; 18. end 19. register_right U1(.clk(clk), .din(din), .dout(dout)); 20. 21. endmodule
在Modelsim中仿真得到的波形图如下:
2、 16位左移寄存器
同右移位寄存器原理一致,下面直接给出verilog HDL 设计代码:
1. module register_left(clk, din, dout); 2. input clk; 3. input [15:0] din; 4. output [15:0] dout; 5. reg [15:0] dout; 6. 7. always @(posedge clk) 8. begin 9. dout <= {din[14:0], din[15]}; 10. end 11. endmodule
测试文件为:
1. `timescale 1ns/1ps 2. module register_left_tb; 3. reg clk; 4. reg [15:0] din; 5. wire [15:0] dout; 6. 7. always 8. #10 clk = ~clk; 9. 10. initial 11. begin 12. clk = 1'b0; 13. din = 16'b0000_0000_0000_0000; 14. #10 din = 16'b0000_0000_0000_0011; 15. #20 din = 16'b0000_0000_0011_0000; 16. #100; 17. end 18. 19. register_left U1(.clk(clk), .din(din), .dout(dout)); 20. endmodule
在Modelsim中仿真所得波形图如下:
3、 串行输入并行输出寄存器
下面描述一个位宽为8的串行输入并行输出的寄存器,其实现的功能为:1位数据的串行输入,8位数据的并行输出。当时钟上升沿到达时,1位输入数据din进入qtemp的最低位,qtemp的其余各位依次向左移动1位,在assign 赋值语句中,将qtemp连续赋值给dout,实现8位的数据并行输出。
其verilog HDL设计代码为:
1. module left_shifter_reg(clk, din, dout); 2. input clk; 3. input din; 4. output [7:0] dout; 5. wire [7:0] dout; 6. reg [7:0] qtemp; 7. always @ (posedge clk) 8. begin 9. qtemp <= {qtemp[6:0], din}; //每次输入一位 10. end 11. assign dout = qtemp; //并行输出 12. 13. endmodule
测试文件为:
1. module left_shifter_reg_tb; 2. reg din; 3. reg clk; 4. wire [7:0] dout; 5. 6. always 7. #10 clk = ~clk; 8. 9. initial 10. begin 11. clk = 1'b0; 12. #100 din = 1'b1; 13. #100 din = 1'b1; 14. #100 din = 1'b0; 15. end 16. 17. left_shifter_reg U1(.din(din), .clk(clk), .dout(dout)); 18. endmodule
在Modelsim中仿真所得波形图:
4、 并行输入串行输出移位寄存器
下面描述一个位宽为8的并行输入串行输出的寄存器,其实现的功能为:当使能端 en = 1时,将输入数据din存入一个8位的中间变量,然后在每个时钟上升沿到来时,将qtemp的最低端输出,然后再将qtemp右移一位,从而实现将din输入数据从最低位到最高位依次串行输出。
其verilog HDL设计代码为:
1. module right_shifter_reg(clk, en, din, dout); 2. input [7:0] din; 3. input en,clk; 4. output dout; 5. reg dout; 6. reg [7:0] qtemp; 7. always @(posedge clk) 8. begin 9. if(en == 1) 10. qtemp <= din; 11. else 12. begin 13. dout <= qtemp[0]; 14. qtemp <= {qtemp[0], qtemp[7:1]}; 15. end 16. end 17. 18. endmodule
测试文件为:
1. `timescale 1ns/1ps 2. module right_shifter_reg_tb; 3. reg [7:0] din; 4. reg clk; 5. reg en; 6. wire dout; 7. 8. always 9. #10 clk = ~clk; 10. 11. initial 12. begin 13. clk = 0; 14. en = 1'b0; 15. #10 en = 1'b1; 16. din = 8'b1110_0010; 17. #20 en = 1'b0; 18. #100; 19. end 20. right_shifter_reg U1(.clk(clk), .en(en), .din(din), .dout(dout)); 21. 22. endmodule
在Modelsim中仿真所得波形图如下: