HDLBits学习笔记:Sequential Logic

99. Four-bit binary counter

没什么说的

module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output [3:0] q);
    initial q = 4'b0;
    always @(posedge clk)
        begin
            if(reset) q <= 4'h0;
            else
                begin
                    if(q == 4'hf) q = 4'h0;
                    else q = q + 1'b1;
                end
              
        end
endmodule

102. Count slow

if和else if

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);
    initial q = 4'h0;
    always @(posedge clk)
        begin
            if(reset) q <= 4'h0;
            else if(slowena)
                begin
                q <= q + 1'b1;
            	if(q == 4'd9) q <= 4'h0;
                end
        end
endmodule 

103.Counter 1-12

错误代码:

module top_module (
    input clk,
    input reset,
    input enable,
    output [3:0] Q,
    output reg c_enable,
    output reg c_load,
    output reg [3:0] c_d
); 
    
    initial
        begin
            c_load = 1'b0;
            c_enable = 1'b1;
            Q = 4'd0;
        end
    always @(posedge clk)
        begin
            if(reset) 
                begin
                    c_load <= 1'b1;
                	c_d <= 4'd1;
                end
            else if(enable)
                begin

                        begin
                            c_load = 1'b0;
                            c_enable = 1'b1;
                        end
                end
            else
                c_enable = 1'b0;
        end
        count4 the_counter (clk, c_enable, c_load, c_d, Q);
endmodule

错误分析:总是滞后一个周期,是因为always在clk上升沿改变状态,因此下个上升沿才会改变the_counter状态。因此需要用assign 直接连接电路,实时改变状态,在第一个上升沿到来时就改变counter 状态。

正确代码:

module top_module (
    input clk,
    input reset,
    input enable,
    output [3:0] Q,
    output c_enable,
    output c_load,
    output [3:0] c_d
); //
    
    assign c_enable = enable;
    assign c_load = reset | ((Q == 4'd12) && enable == 1'b1);
    assign c_d = c_load ? 4'd1 : 4'dz;
 
    count4 u_counter (clk, c_enable, c_load, c_d, Q);
 
endmodule

20210412:

104.Counter 1000

c_enable[1] , c_enable[2] 务必与低位相与。先画出想象中的4路Q输出,对应个十百千位,再写enable.

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    wire [3:0] Q0, Q1, Q2, Q3;
    assign c_enable[0] = 1'b1;
    assign c_enable[1] = Q0[0] & Q0[3];
    assign c_enable[2] = (Q1[0] & Q1[3]) & c_enable[1];
    assign OneHertz = (Q2[0] & Q2[3]) & c_enable[2];
    bcdcount counter0 (clk, reset, c_enable[0], Q0);
    bcdcount counter1 (clk, reset, c_enable[1], Q1);
    bcdcount counter2 (clk, reset, c_enable[2], Q2);
    bcdcount counter3 (clk, reset, OneHertz, Q3);
endmodule

105.4-digital decimal counter

always中clk不写posedge会报错:

Error (23031): Evaluation of Tcl script /home/h/hdlbits/compile.tcl unsuccessful
Error: Quartus Prime Shell was unsuccessful. 1 error, 6 warnings
module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    
    assign ena[1] = q[3] & q[0];
    assign ena[2] = (q[7] & q[4]) & ena[1];
    assign ena[3] = (q[11] & q[8]) & ena[2];
    
    cnt cnt0(clk, reset, 1'b1, q[3:0]);
    cnt cnt1(clk, reset, ena[1], q[7:4]);
    cnt cnt2(clk, reset, ena[2], q[11:8]);
    cnt cnt3(clk, reset, ena[3], q[15:12]);
    
endmodule

module cnt(
	input clk,
    input reset,
    input enable,
    output reg [3:0]q
);
    always@(posedge clk)
        begin
            if(reset) q = 4'd0;
            else if(enable)
                begin
                    if(q == 4'd9) q = 4'd0;
                    else q = q + 4'd1;
                end
        end
endmodule

20210413

106.12-hour clock

分秒和时针分开写,分秒:59-00;时针:01-09-12-01;因为是十六进制,用低四位高四位表示,进位信息作为输入。

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    wire ena1, ena2, ena3, ena4;
    assign ena1 = (ss[3:0] == 4'h9) & ena;
    assign ena2 = (ss[7:4] == 4'h5) & ena1;
    assign ena3 = (mm[3:0] == 4'h9) & ena2;
    assign ena4 = (mm[7:4] == 4'h5) & ena3;
    cnt cnt0 (clk, reset, ena, 4'd0, 4'd0, 4'd9, ss[3:0]);
    cnt cnt1 (clk, reset, ena1, 4'd0, 4'd0, 4'd5, ss[7:4]);
    cnt cnt2 (clk, reset, ena2, 4'd0, 4'd0, 4'd9, mm[3:0]);
    cnt cnt3 (clk, reset, ena3, 4'd0, 4'd0, 4'd5, mm[7:4]);
    cnthh cnt4 (clk, reset, ena4, hh[7:0]);
    always@(posedge clk)
        begin
            if(reset) pm = 1'b0;
            else if(ena4 & (hh == 8'h11))
                pm = ~pm;
        end
endmodule

module cnt(
	input clk,
    input reset,
    input ena,
    input [3:0] start,
    input [3:0] renum,
    input [3:0] radix,
    output reg [3:0] q
);
    always@(posedge clk)
        begin
            if(reset) q = renum;
            else if(ena)
                begin
                    if(q == radix) q = start;
                    else q = q + 1'b1;
                end
        end
endmodule

module cnthh(
    input clk,
    input reset,
    input ena,
    output reg [7:0] q
);
    
    always@(posedge clk)
        begin
            if(reset) q = 8'h12;
            else if(ena)
                begin
                    if(q[7:4] == 0)
                        begin
                            if(q[3:0] == 4'd9) 
                                begin
                                    q[3:0] = 4'd0;
                                    q[7:4] = 4'd1;
                                end
                                
                            else q[3:0] = q[3:0] + 4'b1;
                        end
                    else
                        begin
                            if(q[3:0] == 4'd2) 
                                begin
                                    q[3:0] = 4'd1;
                                    q[7:4] = 4'd0;
                                end
                            else q[3:0] = q[3:0] + 4'b1;
                        end
                end
        end
endmodule

107.4-bit shift register

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) q = 0;
            else if(load)
                q = data;
            else if(ena)
                begin
                    q = {1'b0, q[3], q[2], q[1]};
                end
        end
endmodule

108. Left/right rotator

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'b01 : q = {q[0], q[99:1]};
                        2'b10 : q = {q[98:0], q[99]};
                        default;
                        endcase
                end
               
        end
endmodule

109.Left/right arthimetic shift by 1 or 8

算数右移保留符号位,移动后左侧全为符号位。

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[62:0], 1'b0};
                        2'b01 : q = {q[55:0], 8'd0};
                        2'b10 : q = {q[63], q[63:1]};
                        2'b11 : q = {{8{q[63]}}, q[63:8]};
                        default;
                    endcase
                end
               
        end
endmodule

110. 5-bit LFSR(linear feedback shift register )

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'h1;
            else 
                begin
                    q = {(q[0] ^ 1'b0), q[4], (q[3] ^ q[0]), q[2], q[1]};
                end
        end

endmodule

111. 3-bit LFSR

module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q
    always@(posedge KEY[0])
        begin
            if(KEY[1])
                LEDR = {SW};
            else
                LEDR = {LEDR[1] ^ LEDR[2], LEDR[0], LEDR[2]};
        end

endmodule

112. 32-bit LFSR

为什么右移? position32指什么?

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

113.Shift register

module top_module (
    input clk,
    input resetn,   // synchronous reset
    input in,
    output out);
    reg q2, q1, q0;
    always@(posedge clk)
        begin
            if(!resetn)
                    {out, q2, q1, q0} = 4'b0;
            else
                    {out, q2, q1, q0} = {q2, q1, q0, in};
        end
endmodule

20210414

114.Shift register

module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //
    MUXDFF mux0(KEY[0], KEY[1], KEY[2], KEY[3], SW[3], LEDR[3]);
    MUXDFF mux1(KEY[0], KEY[1], KEY[2], LEDR[3], SW[2], LEDR[2]);
    MUXDFF mux2(KEY[0], KEY[1], KEY[2], LEDR[2], SW[1], LEDR[1]);
    MUXDFF mux3(KEY[0], KEY[1], KEY[2], LEDR[1], SW[0], LEDR[0]);
    
endmodule

module MUXDFF (
    input clk,
	input e,
    input l,
    input w,
    input r,
    output reg q
);
    always@(posedge clk)
        begin
            if(e)
                begin
                    if(l) q = r;
                    else q = w;
                end
            else
                begin
                    if(l) q = r;
                    else q = q;
                end
        end
endmodule

115. 3-input LUT( look-up-table 查找表)

分清楚组合电路和时序电路,其中Z的查找是组合电路,要么按笔者assign写,要么用always@(*)来写,切忌用clk边沿触发写组合电路,会出现延时。笔者刚开始就犯了这个错误。

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)
                    q <= {q[6:0], S};
            else q <= q;
        end
    assign Z = q[{A, B, C}];
endmodule

116. Rule90(元胞自动机)

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [511:0] q ); 
    integer i;
    always@(posedge clk)
        begin
            if(load) q <= data;
            else
                begin
                    q[0] <= q[1] ^ 0;
                    q[511] <= q[510] ^ 0;
                    for(i = 1; i < 511; i = i + 1)
                        begin
                            q[i] <= q[i - 1] ^ q[i + 1];
                        end
                end
        end
endmodule

        

116. Rule 110

这道题应该先卡诺图化简的,笔者做的比较繁琐。

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [511:0] q
); 
    integer i;
    always@(posedge clk)
        begin
            if(load) q = data;
            else
                begin
                    case ({q[1], q[0], 1'b0})
                        3'b000 : q[0] <= 1'b0;
                                3'b001 : q[0] <= 1'b1;
                                3'b010 : q[0] <= 1'b1;
                                3'b011 : q[0] <= 1'b1;
                                3'b100 : q[0] <= 1'b0;
                                3'b101 : q[0] <= 1'b1;
                                3'b110 : q[0] <= 1'b1;
                                3'b111 : q[0] <= 1'b0;
                                default;
            		endcase
                    case ({1'b0, q[511], q[510]})
                        3'b000 : q[511] <= 1'b0;
                        3'b001 : q[511] <= 1'b1;
                                3'b010 : q[511] <= 1'b1;
                                3'b011 : q[511] <= 1'b1;
                                3'b100 : q[511] <= 1'b0;
                                3'b101 : q[511] <= 1'b1;
                                3'b110 : q[511] <= 1'b1;
                                3'b111 : q[511] <= 1'b0;
                                default;
            		endcase
                    for(i = 1; i < 511; i = i + 1)
                        begin
                            case ({q[i + 1], q[i], q[i - 1]})
                                3'b000 : q[i] <= 1'b0;
                                3'b001 : q[i] <= 1'b1;
                                3'b010 : q[i] <= 1'b1;
                                3'b011 : q[i] <= 1'b1;
                                3'b100 : q[i] <= 1'b0;
                                3'b101 : q[i] <= 1'b1;
                                3'b110 : q[i] <= 1'b1;
                                3'b111 : q[i] <= 1'b0;
                                default;
            				endcase
                        end
                end
        end
endmodule

117. Game

抄的,处理好四边即可,数学运算。

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output [255:0] q ); 
    
    reg [3:0]	sum;
    integer i;
 
    always@(posedge clk)begin
        if(load)begin
            q <= data;
        end
        else begin
            for(i = 0; i <= 255; i = i + 1)begin
                if(i == 0)begin
                    sum = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];
                end
                else if(i == 15)begin
                    sum = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];
                end
                else if(i == 240)begin
                    sum = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];
                end
                else if(i == 255)begin
                    sum = q[238] + q[239] + q[224] + q[254] + q[240] + q[14] + q[15] + q[0];
                end
                else if(i > 0 && i < 15)begin
                    sum = q[i + 239] + q[i + 240] + q[i + 241] + q[i - 1] + q[i + 1] + q[i + 15] + q[i + 16] + q[i + 17];
                end
                else if(i > 240 && i < 255)begin
                    sum = q[i -17] + q[i - 16] + q[i - 15] + q[i - 1] + q[i + 1] + q[i - 241] + q[i - 240] + q[i - 239];
                end
                else if(i % 16 == 0)begin
                    sum = q[i -1] + q[i - 16] + q[i - 15] + q[i + 15] + q[i + 1] + q[i + 31] + q[i + 16] + q[i + 17];
                end
                else if(i % 16 == 15)begin
                    sum = q[i -17] + q[i - 16] + q[i - 31] + q[i - 1] + q[i - 15] + q[i + 15] + q[i + 16] + q[i + 1];
                end
                else begin
                    sum = q[i - 17] + q[i - 16] + q[i - 15] + q[i - 1] + q[i + 1] + q[i + 15] + q[i + 16] + q[i + 17];
                end
                case(sum)
                    4'd2:begin
                        q[i] <= q[i];
                    end
                    4'd3:begin
                        q[i] <= 1'b1;
                    end
                    default:begin
                        q[i] <= 1'b0;
                    end
                endcase
            end
        end
    end       
 
endmodule
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值