2021年4月30日 星期五

HDLbits筆記-Shift Registers

 HDLbits筆記-Shift Registers

4-bit shift register

题目:设计一个4-bit移位寄存器(右移),采用异步复位,同步load,enable模式。
(1)复位后,移位寄存器输出0;
(2)load为高电平,将data[3:0]数据load进移位寄存器;
(3)ena为高电平,移位寄存器右移一位;
(4)q作为移位寄存器的输出;
如果load和ena信号同时有效,load信号优先级较高。

module top_module(
    input clk,
    input areset,  // async active-high reset to zero
    input load,
    input ena,
    input [3:0] data,
    output  [3:0] q); 
    reg [3:0]	q_temp;
    always@(posedge clk or posedge areset)begin
        if(areset)
            q_temp	<=	4'd0;
        else if(load)
            q_temp	<=	data;
        else if(ena)
            q_temp	<=	(q_temp >> 1);
        else
            q_temp	<=	q_temp;
    end
    assign q = q_temp;
    
endmodule

Rotate 100

题目:设计一个带有同步load和左右使能enable的100-bit的左右旋转器。旋转器从寄存器的另一端插入已移出的位,不像移位器丢弃已移出的位而插入一个零。如果启用,旋转器会旋转这些位并且不会修改/丢弃它们。
(1)laod:加载data[99:0]到移位寄存器中;
(2)ena[1:0]选择旋转的方向:2’b01向右旋转一个bit;2’b10向左旋转一个bit;2’b00,2’b11不旋转
(3)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)
            q	<=	data;
        else begin
            case(ena)
                2'b00: q	<=	q;
                2'b01: q	<=	{q[0],q[99:1]};
                2'b10: q	<=	{q[98:0],q[99]};
                2'b11: q	<=	q;
            endcase
        end
    end
endmodule

注意移位的方法,q>>1表示将q中的最低位移除,在最高位补0;而q <= {q[0],q[99:1]}表示将q的最低位直接移到q的最高位。

Left/right arithmetic shift by 1 or 8

题目:设计一个带有同步load功能的64bit的算数移位寄存器。既可以左移又可以右移,通过amount信号选择移位的位数。算术右移在移位寄存器(在本例中是q[63])中移动数字的符号位,而不是像逻辑右移那样移动零。算术右移的另一种思考方式是假设被移动的数有符号并且保留符号,因此算术右移可以将有符号的数除以2的幂。
逻辑左移和算数左移没有区别。
(1)load为高电平将data[63:0]加载到移位寄存器中;
(2)ena选择是否移位操作;
(3)amount移位方向及移位多少位;
2’b00: shift left by 1 bit.
2’b01: shift left by 8 bits.
2’b10: shift right by 1 bit.
2’b11: shift right by 8 bits.

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)
            q	<=	data;
        else if(ena)begin
            case(amount)
                2'b00: q	<=	q << 1;
                2'b01: q	<=	q << 8;
                2'b10: q	<=	{q[63],q[63:1]};
                2'b11: q	<=	{{8{q[63]}},q[63:8]};
            endcase
        end
    end
endmodule

总结:
(1)q << n等价于乘以2^n;
(2)q >> n 等价于除以2^n;
(3) q <<< n 等价于乘以2^n;
(4)q >>> n 等价于除以2^n;
对于逻辑左移右移和算数左移,只需要把腾出的位补0;而在算数右移中,如果左操作数是无符号数,则腾出的位用0填充;如果是有符号数,则腾出的位用最高位填充。

5-bit LFSR

题目:
在这里插入图片描述

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 
    always@(posedge clk)begin
        if(reset)
            q	<=	5'd1;
        else begin
            q[4]	<=	0 ^ q[0];
            q[3]	<=	q[4];
            q[2]	<=	q[0] ^ q[3];
            q[1]	<=	q[2];
            q[0]	<=	q[1];
        end
    end
    assign q = {q[4],q[3],q[2],q[1],q[0]};
endmodule

32-bit LFSR

题目:在5-bit FSR基础上,构建一个32-bit的LFSR

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output [31:0] q
); 
    integer		i,j;
    always@(posedge clk)begin
        if(reset)
            q	<=	32'd1;
        else begin
            q[31]	<=	0 ^ q[0];
            for(i = 30 ;i > 21; i = i - 1)begin
                q[i]	<=	q[i+1]; 
            end
            q[21]	<=	q[0] ^ q[22];
            for(i = 20 ;i > 1; i = i - 1)begin
                q[i]	<=	q[i+1]; 
            end            
            q[1]	<=	q[0] ^ q[2];
            q[0]	<=	q[0] ^ q[1];
        end
    end

    assign q = {q[31],q[30],q[29],q[28],q[27],q[26],q[25],q[24],q[23],q[22],q[21],q[20],q[19],q[18],q[17],q[16],q[15],
        q[14],q[13],q[12],q[11],q[10],q[9],q[8],q[7],q[6],q[5],q[4],q[3],q[2],q[1],q[0]};
endmodule

注意中间没有反馈的部分可以采用for循环的形式,还要注意是在什么地方反馈的。
或者这样写代码,简单一些:

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output [31:0] q
); 
    always@(posedge clk)begin
        if(reset)
            q	<=	32'd1;
        else
            q	<=	{0^q[0],q[31:23],q[0]^q[22],q[21:3],q[0]^q[2],q[0]^q[1]};
    end

endmodule

Shift register

题目:
在这里插入图片描述

module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //

    MUXDFF	MUXDFF0(
        .clk		(KEY[0]),
        .w			(KEY[3]),
        .R			(SW[3]),
        .E			(KEY[1]),
        .L			(KEY[2]),
        .Q			(LEDR[3])
    
    );
    MUXDFF	MUXDFF1(
        .clk		(KEY[0]),
        .w			(LEDR[3]),
        .R			(SW[2]),
        .E			(KEY[1]),
        .L			(KEY[2]),
        .Q			(LEDR[2])
    
    );
    MUXDFF	MUXDFF2(
        .clk		(KEY[0]),
        .w			(LEDR[2]),
        .R			(SW[1]),
        .E			(KEY[1]),
        .L			(KEY[2]),
        .Q			(LEDR[1])
    
    );
    MUXDFF	MUXDFF3(
        .clk		(KEY[0]),
        .w			(LEDR[1]),
        .R			(SW[0]),
        .E			(KEY[1]),
        .L			(KEY[2]),
        .Q			(LEDR[0])
    
    );  
    assign  LEDR = {LEDR[3],LEDR[2],LEDR[1],LEDR[0]};
endmodule



module MUXDFF (
    input clk,
    input w, R, E, L,
    output Q
);

    always@(posedge clk)begin
        if(L)begin
            Q <= R;
        end
        else begin
            if(E)begin
                Q <= w;
            end
            else begin
                Q <= Q;
            end
        end
    end
  
endmodule

在模块例化是的时候千万注意连线,这道题目很可能会把w信号连错,开始和KEY[3]连接,之后上一个模块的输出作为新的w输入,即和LEDR[3]连接,以此类推。

3-input LUT

题目:
首先用8个D触发器创建一个8-bit移位寄存器。每个D触发器的输出标记为Q[0]…q[7]。S作为移位寄存器的输入,Q[0]作为输入。enable信号控制是否移位。此外,电路还有三个额外的输入A,B,C和一个输出Z。当ABC为000时,Z= Q[0],当ABC为001时,Z= Q[1],以此类推。设计的电路只能包括8-bit的移位寄存器和选择器。这个电路也叫3-input的LUT。

module top_module (
    input clk,
    input enable,
    input S,
    input A, B, C,
    output Z ); 
    integer		i;
    reg		[7:0]	Q;
    always@(posedge clk)begin
        if(enable)begin
            Q	<=	{Q[6:0],S};
        end
		else
        	Q	<=	Q;
    end
    always@(*)begin
            case({A,B,C})
                3'b000:	Z	=	Q[0];
                3'b001:	Z	=	Q[1];
                3'b010:	Z	=	Q[2];
                3'b011:	Z	=	Q[3];
                3'b100:	Z	=	Q[4];
                3'b101:	Z	=	Q[5];
                3'b110:	Z	=	Q[6];
                3'b111:	Z	=	Q[7];
            endcase
    end
endmodule

这里的case 语句还可以写为:

assign Z  =  Q[{A,B,C}];

WOKWI LED + MQTT Node-Red SQLite

WOKWI LED + MQTT Node-Red SQLite const char *mqtt_broker = "broker.mqtt-dashboard.com" ; const char *topic1 = "alex9ufo/e...