[Verilog24]HDLBits习题_Shift Registers

HDLBits习题_Shift Registers

4-bit shift register

  • 题目要求,构建一个4bit的移位寄存器(右移),含异步复位、同步加载和使能功能,其中,areset可让寄存器复位为0;load可加载4bit数据到移位寄存器中,不移位;ena信号使能数据右移;q为移位寄存器的内容输出。
  • 具体代码如下:
module top_module(
    input clk,
    input areset,  // async active-high reset to zero
    input load,
    input ena,
    input [3:0] data,
    output reg [3:0] q); 
    
    always @(posedge clk or posedge areset)begin
        if(areset)begin
            q <= 4'b0;
        end
        else if(load) begin
            q <= data;
        end
        else if(ena)begin
            q <= {1'b0,q[3:1]};
        end
        else begin
            q <= q;
        end
    end

endmodule

Left/right rotator

  • 题目要求,构建一个100位的循环移位寄存器,load为数据加载使能信号,ena[1:0]为左右循环移位使能信号,当ena[1:0]==2'b01时,右移1bit;当ena[1:0]==2'b10时,左移1bit;其他情况进行数据保持。q为循环移位寄存器的数据输出。
  • 具体代码如下:
module top_module(
    input clk,
    input load,
    input [1:0] ena,
    input [99:0] data,
    output reg [99:0] q);
    
    always @(posedge clk) begin
        if(load) begin
            q <= data;
        end
        else begin
            case (ena)
                2'b01:q <= {q[0],q[99:1]};
                2'b10:q <= {q[98:0],q[99]};
                default:q <= q;
            endcase
        end
    end

endmodule

Left/right arithmetic shift by 1 or 8

  • 题目要求,建立一个64位算术移位寄存器,同步加载。移位器可以左右移位,并按数量选择1位或8位的移位。其中,load为数据加载使能信号,ena为移位使能信号,amount决定移位方向与数量,其值为2'b00时,左移1位;2'b01时,左移8位;2'b10时,右移1位;2'b11时,右移8位。q为移位寄存器的数据输出。
  • 具体代码如下:
module top_module(
    input clk,
    input load,
    input ena,
    input [1:0] amount,
    input [63:0] data,
    output reg [63:0] q); 
    
    always @(posedge clk)begin
        if(load)begin
            q <= data;
        end
        else begin
            if(ena)begin
                case(amount)
                    2'b00: q <= {q[62:0],1'b0};
                    2'b01: q <= {q[55:0],8'b0};
                    2'b10: q <= {q[63],q[63:1]};
                    2'b11: q <= {{8{q[63]}},q[63:8]};
                endcase
            end
            else begin
                q <= q;
            end
        end
    end

endmodule

5-bit LFSR

  • 题目要求,构造一个如图所示的线性反馈移位寄存器,reset复位信号可使LFSR归1。
  • 具体代码如下:
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 
   
    reg [4:0] q_r;
    assign q = q_r;
    always@(posedge clk)begin
        if(reset) begin
            q_r<=5'h1;
        end
        else begin
            q_r <= {q_r[0]^1'b0,q_r[4],q_r[3]^q_r[0],q_r[2],q_r[1]};
        end
    end

endmodule

3-bit LFSR

  • 题目要求,构建一个如上图所示的电路,SW即为信号R,KEY[1]为L,KEY[0]为时钟CLK,LEDR为Q。
  • 具体代码如下:
module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q

    wire clk,L;
    assign clk = KEY[0];
    assign L = KEY[1];
    
    always @(posedge clk)begin
        if(L)begin
            LEDR[0] <= SW[0];
            LEDR[1] <= SW[1];
            LEDR[2] <= SW[2];
        end
        else begin
            LEDR[0] <= LEDR[2];
            LEDR[1] <= LEDR[0];
            LEDR[2] <= LEDR[2] ^ LEDR[1];
        end
    end

endmodule

32-bit LFSR

  • 构建一个32位的伽罗瓦线性移位寄存器(Galois LFSR),其taps位置为32、22、2和1。
  • 伽罗瓦LFSR是一到多型的LFSR,即最后一个触发器的输出与抽头序列对应位置触发器前一级触发器的输出相异或逻辑后再用于驱动下一级触发器,多个抽头序列对应位置触发器的输入。
  • 具体代码如下:
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output [31:0] q
); 
    integer i;
    always @(posedge clk)begin
        if(reset)begin
            q <= 32'h1;
        end
        else begin
            for(i=0;i<32;i++)begin
                if((i==21)||(i==1)||(i==0))begin
                    q[i] <= q[i+1] ^ q[0];
                end
                else if(i==31)begin
                    q[31] <= 1'b0 ^ q[0];
                end
                else begin
                    q[i] <= q[i+1];
                end  
            end
        end
    end

endmodule

Shift register

  • 题目要求,构建一个如上图所示的电路。
  • 具体代码如下:
module top_module (
    input clk,
    input resetn,   // synchronous reset
    input in,
    output out);

    reg [3:0] tmp;
    assign out = tmp[3];
    
    always @(posedge clk)begin
        if(!resetn)begin
            tmp <= 4'h0;
        end
        else begin
            tmp <= {tmp[3:1],in};
        end
    end
    
endmodule

Shift register

  • 上图所示的电路为一n比特线性移位寄存器。题目要求,假设n=4,为移位寄存器写一个顶级Verilog模块(名为top_模块),在顶层模块中实例化MUXDFF子电路的四个副本。假设您将在DE2板卡上实现该电路,其中,KEY[0]clkKEY[1]EKEY[2]LKEY[3]w
  • 具体代码如下:
module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); 
    
    MUXDFF u1(.clk(KEY[0]),
               .w(KEY[3]),
               .R(SW[3]),
               .E(KEY[1]),
               .L(KEY[2]),
               .Q(LEDR[3]));
    
    MUXDFF u2(.clk(KEY[0]),
               .w(LEDR[3]),
               .R(SW[2]),
               .E(KEY[1]),
               .L(KEY[2]),
               .Q(LEDR[2]));
    
    MUXDFF u3(.clk(KEY[0]),
               .w(LEDR[2]),
               .R(SW[1]),
               .E(KEY[1]),
               .L(KEY[2]),
               .Q(LEDR[1]));
    
    MUXDFF u4(.clk(KEY[0]),
               .w(LEDR[1]),
               .R(SW[0]),
               .E(KEY[1]),
               .L(KEY[2]),
               .Q(LEDR[0]));
    
endmodule

module MUXDFF (
    input clk,
    input w,R,E,L,
    output Q
);
    wire tmp;
    assign tmp = E ? w : Q;
    always @(posedge clk)begin
        Q <= L? R : tmp;
    end

endmodule

3-input LUT

  • 题目要求,为一个8x1存储器设计一个电路,在这个电路中,写入到存储器是通过移位来完成的,读取是可进行随机访问的,就像在一个典型的RAM中一样。首先,用8个d类型触发器创建一个8位移位寄存器。标记为Q[0]到Q[7]。移位寄存器输入称为S,输入Q[0] (MSB先移位)。使能输入enable控制是否移位,扩展电路使其有3个额外的输入A,B,C和一个输出Z。电路的行为应该如下:当ABC为000时,Z=Q[0],当ABC为001时,Z=Q[1],以此类推。你的电路应该只包含8位移位寄存器和多路复用器。(这个电路称为3输入查找表(LUT))。
  • 具体代码如下:
module top_module (
    input clk,
    input enable,
    input S,
    input A, B, C,
    output Z ); 
    
    reg [7:0] Q;
    always @(posedge clk)begin
        if(enable)begin
            Q <= {Q[6:0],S};
        end
        else begin
            Q <= Q;
        end
    end
    assign Z = Q[{A,B,C}];

endmodule

参考:
HDLBits
HDLBits答案(12)_Verilog移位寄存器