【 FPGA 】设计一个通用移位寄存器

版权声明:本博客内容来自于个人学习过程中的总结,参考了互联网、数据手册、帮助文档、书本以及论文等上的内容,仅供学习交流使用,如有侵权,请联系,我会重写!转载请注明地址! https://blog.csdn.net/Reborn_Lee/article/details/85694054

通用移位寄存器可以加载并行数据,将其内容向左移位(向高位移)、向右移位(向低位移)或保持原有状态。它可以实现并转串(首先加载并行输入,然后移位)或串转并(首先移位,然后并行输出)。实现这种操作需要两位控制信号ctrl,如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/01/03 14:24:23
// Design Name: 
// Module Name: univ_shift_reg
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module univ_shift_reg
#(parameter N = 8)
(
    input clk,
    input reset,
    input [1:0] ctrl,
    input [N - 1 : 0] d,
    output [N - 1 : 0] q
    );
    reg [N - 1 : 0] r_reg,r_next;
    
    always @(posedge clk, posedge reset)
    begin
        if(reset)
            r_reg <= 0;
        else
            r_reg <= r_next;
    end
    
    always @*
    begin
       case(ctrl)
       2'b00: r_next = r_reg; //无操作
       2'b01: r_next = {r_reg[N-2:0],r_reg[N-1]}; //循环左移
       2'b10: r_next = {r_reg[0],r_reg[N-1:1]}; //循环右移
       default: r_next = d;  //载入
       endcase
    end   
    assign q = r_reg; 
    
endmodule

RTL电路:

测试文件:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/01/03 14:47:01
// Design Name: 
// Module Name: univ_shift_reg_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module univ_shift_reg_tb;
    parameter N = 8;
    reg [1:0] ctrl;
    reg reset;
    reg clk;
    reg [N-1:0] d;
    wire [N-1:0] q;
    
    univ_shift_reg uu1(
    .clk(clk), .reset(reset),
    .ctrl(ctrl),.d(d),.q(q)
    );
    
    
       // Note: CLK must be defined as a reg when using this method
       
       parameter PERIOD = 10;
    
       always begin
          clk = 1'b0;
          #(PERIOD/2) clk = 1'b1;
          #(PERIOD/2);
       end  
       
       initial begin
       reset = 1'b1;
       d = 8'b01010101;
       ctrl = 2'b00;
       # 20
       reset = 1'b0;
       ctrl = 2'b11;  //载入
       # 40 
       ctrl = 2'b01;  //左移
       
       
       
       end
                    
                
    
    
endmodule

仿真波形:

实用不实用关系不大,唯一的一点意义就是记住这种使用多路复用器来控制移位寄存器的操作。

猜你喜欢

转载自blog.csdn.net/Reborn_Lee/article/details/85694054