HDLbits 刷题答案practice——Shift Registers

目录

3.2.3 Shift Registers

3.2.3.1 4-bit shift register(Shift4)

3.2.3.2 Left/right rotator(Rotate100)

3.2.3.3 Left/right arithmetic shift by 1 or 8(Shift18)

3.2.3.4 5-bit LFSR(Lfsr5)

3.2.3.5 3-bit LFSR(Mt2015 lfsr)

3.2.3.6 32-bit LFSR(Lfsr32)

3.2.3.7 Shift register(Exams/m2014 q4k)

3.2.3.8 Shift register(Exams/m2014 q4b)

3.2.3.9 3-input LUT(Exams/ece241 2013 q12)


3.2.3 Shift Registers

3.2.3.1 4-bit shift register(Shift4)

//构建一个 4 位移位寄存器(右移),具有异步清零,同步置位(areset)和使能(ena)的功能
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    //异步复位:因此areset需要作为敏感列表
        if(areset)begin
            q <= 4'b0;
        end
        else if(ena | load)begin                    //检测使能或者置位信号是否为1
            if(load)begin                           //优先检测load信号,置位优先级大于右移优先级
                q <= data;
            end
            else if(ena)begin
                q <= q >> 1;
            end
        end
        
    end
endmodule

3.2.3.2 Left/right rotator(Rotate100)

module top_module(
    input clk,
    input load,
    input [1:0] ena,				//2‘b01:向右、2'b10:向左、2'b00/2'b11:不进行操作 
    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: begin q <= {q[0],q[99:1]}; end
                2'b10: begin q <= {q[98:0], q[99]};end
                default: begin q <= q;end
            endcase
        end
    end

endmodule

3.2.3.3 Left/right arithmetic shift by 1 or 8(Shift18)

//构建64位算术移位寄存器,同步加载,可以向左和向右移动 1 位或 8 位位置,由amount[1:0]选择
//算术右移与逻辑右移不同,算数左移和逻辑左移相同
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 if(ena) begin
            case(amount)
                2'b00:begin q <= {q[62:0], 1'b0};end
                2'b01:begin q <= {q[55:0], 8'b0};end
                2'b10:begin 
                    if(q[63])begin
                       q <= q >> 1;
                        q[63] <= 1'b1;
                    end
                    else begin
                       q <= q >> 1; 
                    end
                end
                
                2'b11:begin
                    if(q[63])begin
                        q <= q >> 8;
                        q[63:56] <= 8'hff;			//算数右移前面符号为1,前面全部都需要置数为1
                    end
                    else begin
                       q <= q >> 8; 
                    end
                end
                default:begin q <= q;end
            endcase
        end
    end
    
endmodule

3.2.3.4 5-bit LFSR(Lfsr5)

线性反馈移位寄存器

/*********************************************
线性移位寄存器,通常带有几个异或门来产生移位寄存器的下一个状态。

*********************************************/
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output reg [4:0] q
); 
    always @(posedge clk)begin
        if(reset)begin//同步复位把q置位为00001
            q <= 5'h1;//5;b1?
        end
        else begin
            q[4] <= 1'b0 ^ q[0];
            q[3] <= q[4];
            q[2] <= q[3] ^ q[0];
            q[1] <= q[2];
            q[0] <= q[1];
        end
    end

endmodule

3.2.3.5 3-bit LFSR(Mt2015 lfsr)

//此处代码把组合逻辑和时序逻辑都写在了一起,代码阅读性上没那么好
//下面有有另外一种组合逻辑与时序逻辑分开表述的
module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q
    
    reg [2:0] q;

    always @(posedge KEY[0])begin
        q[0] <= KEY[1] ? SW[0] : q[2];
        q[1] <= KEY[1] ? SW[1] : q[0];
        q[2] <= KEY[1] ? SW[2] : (q[1] ^ q[2]);
    end
	
    assign LEDR = q;
    
endmodule


//组合逻辑电路与时序逻辑电路分开
module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q
    
    //定义寄存器ledr_next表示clk未到前D处的逻辑
    reg [2:0] ledr_next;
    
    //组合逻辑部分
    always @(*)begin
        if(KEY[1])begin
           ledr_next <= SW;
        end
        else begin
            ledr_next[0] <= LEDR[2];
            ledr_next[1] <= LEDR[0];
            ledr_next[2] <= LEDR[1] ^ LEDR[2];
        end
    end
    
    //时序逻辑部分
    always @(posedge KEY[0])begin
       LEDR <= ledr_next; 
    end
    
endmodule

这个题目有两种解答方案,其中第一个是自己直接写出来的,查看了其他博主的答案后觉得组合逻辑与时序逻辑分开写逻辑更加清晰一点。

3.2.3.6 32-bit LFSR(Lfsr32)

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output reg [31:0] q
); 
	
    reg [31:0] q_next;
    always @(*)begin
        q_next[31:0]= {q[0], q[31:1]};//此处要先进行移位
        
        q_next[31] <= q[0] ^ 1'b0;
        q_next[21] <= q[0] ^ q[22];
        q_next[1]  <= q[0] ^ q[2];
        q_next[0]  <= q[0] ^ q[1];

    end
    
    always @(posedge clk)begin
        if(reset)begin
            q <= 32'b1;
        end
        else begin
           q <= q_next; 
        end
    end
endmodule

3.2.3.7 Shift register(Exams/m2014 q4k)

module top_module (
    input clk,
    input resetn,   // synchronous reset
    input in,
    output reg out);
    
    reg [2:0] q;
    
    always @(posedge clk)begin
        if(!resetn)begin
            out <= 1'b0;
            q <= 3'b0;
        end
        else begin
            q[2] <= in;
            q[1] <= q[2];
            q[0] <= q[1];
            out <= q[0];
        end
    end

endmodule

3.2.3.8 Shift register(Exams/m2014 q4b)

module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //
        MUXDFF S0 (
            .en(KEY[1]),
            .l(KEY[2]),
            .r(SW[3]),
            .w(KEY[3]),
            .clk(KEY[0]),
            .q(LEDR[3])
        );
        
        MUXDFF S1 (
            .en(KEY[1]),
            .l(KEY[2]),
            .r(SW[2]),
            .w(LEDR[3]),
            .clk(KEY[0]),
            .q(LEDR[2])
        );
        
        MUXDFF S2 (
            .en(KEY[1]),
            .l(KEY[2]),
            .r(SW[1]),
            .w(LEDR[2]),
            .clk(KEY[0]),
            .q(LEDR[1])
        );
        
        MUXDFF S3 (
            .en(KEY[1]),
            .l(KEY[2]),
            .r(SW[0]),
            .w(LEDR[1]),
            .clk(KEY[0]),
            .q(LEDR[0])
        );

endmodule

module MUXDFF (
    input en, l, r, w,
    input clk,
    output reg q
);
    reg mux_0, mux_1;
    
    //组合逻辑
	assign mux_0 = en ? w : q;
    assign mux_1 = l  ? r :mux_0;
    
    //时序逻辑
    always @(posedge clk)begin
        q <= mux_1;
    end
endmodule

3.2.3.9 3-input LUT(Exams/ece241 2013 q12)

module top_module (
    input clk,
    input enable,		//是否移位
    input S,			//作为移位寄存器的输入给Q[0]
    input A, B, C,		//ABC是用来选择输出哪个位的Q
    output reg Z);
    
    reg [7:0] Q;
    
    always @(posedge clk)begin
        if(enable)begin
            Q <= {Q[6:0], S};		//若en=1,则S替代原来Q[0]的位置,Q[7]被移出去
        end
        else begin
           Q <= Q; 
        end        
    end
    
    assign Z = Q[{A,B,C}];//组合逻辑输出的
    

    

endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小竹笙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值