【hdlbits】个人学习交流分享(带答案)——sequential logic部分

hdlbits网站:HDLBits (01xz.net)

正文:

latches and filp-flop

D filp-flop

module top_module (
    input clk,    // Clocks are used in sequential circuits
    input d,
    output reg q );//
    always @(posedge clk)begin
       q<=d; 
    end
endmodule

D filp-flops

module top_module (
    input clk,
    input [7:0] d,
    output reg [7:0] q
);
    always @(posedge clk)begin
        q<=d;
    end 
endmodule

DFF with reset

module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output reg [7:0] q
);
    always @(posedge clk)begin
        if(reset)
            q<=8'b0;
        else 
            q<=d;
    end
endmodule

DFF with reset value

module top_module (
    input clk,
    input reset,
    input [7:0] d,
    output reg [7:0] q
);
    always @(negedge clk)begin
        if(reset)
            q<=8'h34;
        else 
            q<=d;
    end
endmodule

DFF with asynchronous reset

module top_module (
    input clk,
    input areset,   // active high asynchronous reset
    input [7:0] d,
    output reg [7:0] q
);
    always @(posedge clk or posedge areset)begin
        if(areset)
            q<=8'b0;
        else
            q<=d;
    end
endmodule

DFF with byte enable

module top_module (
    input clk,
    input resetn,
    input [1:0] byteena,
    input [15:0] d,
    output reg [15:0] q
);
    always @(posedge clk)begin
        if(!resetn) begin
            q<=16'b0;
        end
        else begin
            case(byteena)
                2'b00:q<=q;
                2'b01:q[7:0]<=d[7:0];
                2'b10:q[15:8]<=d[15:8];
                2'b11:q<=d;
            endcase
        end
    end
endmodule

D latch

module top_module (
    input d, 
    input ena,
    output q);
    assign q=ena?d:q;
endmodule

DFF

module top_module (
    input clk,
    input d, 
    input ar,   // asynchronous reset
    output reg q);
    always @(posedge clk or posedge ar)begin
        if(ar)
            q<=1'b0;
        else 
            q<=d;
    end
endmodule

DFF

module top_module (
    input clk,
    input d, 
    input r,   // synchronous reset
    output reg q);
        always @(posedge clk)begin
        if(r)
            q<=1'b0;
        else 
            q<=d;
    end
endmodule

DFF+gate

module top_module (
    input clk,
    input in, 
    output reg out);
    wire d;
    assign d=out^in;
    always @(posedge clk)begin
        out<=d;
    end
endmodule

Mux and DFF

module top_module (
	input clk,
	input L,
	input r_in,
	input q_in,
	output reg Q);
    wire D;
    assign D=L?r_in:q_in;
    always @(posedge clk)begin
        Q<=D;
    end
endmodule

Mux and DFF

module top_module (
    input clk,
    input w, R, E, L,
    output reg Q
);
    wire a,D;
    assign a=E?w:Q;
    assign D=L?R:a;
    always @(posedge clk)begin
        Q<=D;
    end
endmodule

DFF and gates

module top_module (
    input clk,
    input x,
    output z
); 
    wire d1,d2,d3;
    wire q1,q2,q3;
    assign d1=x^q1;
    assign d2=x&(~q2);
    assign d3=x|(~q3);
    DFF DFF_1(.clk(clk),.d(d1),.q(q1));
    DFF DFF_2(.clk(clk),.d(d2),.q(q2));
    DFF DFF_3(.clk(clk),.d(d3),.q(q3));
    assign z=~(q1|q2|q3);
endmodule
module DFF(input clk,d,output reg q);
    initial begin// initial语句可以用作初始化赋值,但是initial不能和always块嵌套
        q=0;// 题意,D触发器在机器启动之前最初复位为零。
    end
    always @(posedge clk)begin
            q<=d;
    end
endmodule

create cirucit form truth table

module top_module (
    input clk,
    input j,
    input k,
    output reg Q); 
    always @(posedge clk)begin
        case({j,k})//注意不要误写成(j,k),{j,k}才能表示j和k拼接,()是case语句的部分
            2'b00:Q<=Q;
            2'b01:Q<=0;
            2'b10:Q<=1;
            2'b11:Q<=~Q;           
       endcase
    end
endmodule

detect an edge 

上升沿检测:对输入信号打一拍,打一拍的信号取反与原信号相与就可以检测出上升沿

下降沿检测:对输入信号打一拍,打一拍的信号与原信号取反相与就可以检测出下降沿

上升或下降沿检测:监测前后电平信号是否一致,不一致则发生边沿变化,对输入信号打一拍,打一拍的信号与原信号异或就可以检测出变化。

module top_module (
    input clk,
    input [7:0] in,
    output reg [7:0] pedge
);
    reg [7:0]in_1;
    always @(posedge clk)begin
        in_1<=in;//打一拍
        pedge<=in&(~in_1);//打一拍的信号取反与原信号相与,检测上升沿
    end
endmodule

detect both edges

module top_module (
    input clk,
    input [7:0] in,
    output reg[7:0] anyedge
);
    reg [7:0]in_1;
    always @(posedge clk)begin
        in_1<=in;//打一拍
        anyedge<=in^(in_1);//打一拍的信号与原信号异或就可以检测出有边沿变化
    end
endmodule

edge capture register

题目描述:对于 32 位向量中的每个位,当输入信号在一个时钟周期内从 1 变为下一个时钟周期的 0 时进行捕获(set)。“捕获”意味着输出将保持 1,直到寄存器复位(同步复位,复位为0),复位reset为上升沿有效,如果上述两个事件同时发生,则复位reset具有最高优先权。在下面示例波形的最后 4 个周期中,“reset”事件比“set”事件早一个周期发生,因此此处没有冲突。

下面的示例波形中,为清楚起见,reset、in[1] 和 out[1] 再次单独显示。

题目要求实现下降沿捕获(set),先说一个容易犯的错误写法:

module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output reg[31:0] out
);
    reg [31:0]in_1;
    always @(posedge clk )begin
       in_1<=in;//打一拍
        if(reset)
            out<=32'b0;
        else if(~in&in_1)
            out<=32'b1;//~in&in_1为1,即出现下降沿,输出置1;
        else 
            out<=out;//默认保持,是0保持0,是1保持1
    end
endmodule

问题出现在else if那一句,本题是32位输入和32位输出,每一位要进行各自的下降沿捕获,所以无法直接赋值为1。只有输入和输出都是1位,捕获后直接out赋值为1可行。改正如下:

module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output reg[31:0] out
);
    reg [31:0]in_1;
    always @(posedge clk )begin
       in_1<=in;
        if(reset)
            out<=32'b0;
        else if(~in&in_1)
            out<=(~in&in_1)|out;//每一位进行各自的下降沿捕获。当对应位出现下降沿或者对应位out已经为1下一个时钟out为1
        else 
            out<=out;//默认保持
    end
endmodule

Dual-edge triggered filp-flop

第一种语法错误:

module top_module (
    input clk,
    input d,
    output reg q
);

    always@(posedge clk or negedge clk)begin
        q<=d;
    end    
endmodule

FPGA 没有双边触发触发器,always @(posedge clk or negedge clk)是错误的语法,

第二种错误语法:

module top_module (
    input clk,
    input d,
    output reg q
);

    always@(posedge clk)begin//上升沿触发器
        q<=d;
    end
    always@(negedge clk)begin//下降沿触发器
        q<=d;
    end
endmodule

同一个变量q不应该在多个always块中被赋值,否则会出现语法错误,因为always块之间是并行的,多个always块给同一个q赋值自然会报错。

解决方法:可以声明两个中间变量pedge_q和nedge_q,最后根据clk信号选择将pedge_q或者nedge_q赋给q,答案如下:

module top_module (
    input clk,
    input d,
    output  q
);
    reg pedge_q;
    reg nedge_q;
    always@(posedge clk)begin//上升沿触发器
        pedge_q<=d;
    end
    always@(negedge clk)begin//下降沿触发器
        nedge_q<=d;
    end
    assign q=clk?pedge_q:nedge_q;//上升沿选pedge_q,下降沿选nedge_q
endmodule

Counters

four-bit binary counter

module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output reg [3:0] q);
    always @(posedge clk)begin
        if(reset)
            q<=4'd0;
        else if(q==4'd15)
            q<=4'd0;
        else 
            q<=q+4'd1;
    end
endmodule

decade counter

module top_module (
    input clk,
    input reset,        // Synchronous active-high reset
    output reg [3:0] q);
    always @(posedge clk)begin
        if(reset)
            q<=4'd0;
        else if(q==4'd9)
            q<=4'd0;
        else 
            q<=q+4'd1;
    end
endmodule

decade counter again

module top_module (
    input clk,
    input reset,
    output reg[3:0] q);
    always @(posedge clk)begin
        if(reset)
            q<=4'h1;
        else if(q==4'd10)
            q<=4'h1;
        else
            q<=q+4'h1;
    end
endmodule

slow decade counter

module top_module (
    input clk,
    input slowena,
    input reset,
    output reg [3:0] q);
    always @(posedge clk)begin
        if(reset)//因为if-else是从上到下顺序判断,所以建议按照优先级从高到低来写if-else,本题优先级reset>!slowena>正常计数
            q<=4'd0;
        else if(!slowena)//slowena为0暂停计数
            q<=q;
        else if(q==4'd9)
            q<=4'd0;
        else
            q<=q+4'd1;
    end
endmodule

counter 1-12

题目描述:要求设计一个 1-12 计数器,要求具有以下输入和输出:

1.reset同步高电平有效复位,强制计数器为 1

2.enable设置为高电平以使计数器运行

3.clk正边沿触发时钟输入

4.Q[3:0]计数器的输出

5.c_enable、c_load、c_d[3:0]是控制信号,c_enable、c_load 和 c_d 分别是进入内部计数器count4enableload和 d 输入的信号

题目提供的组件:

1. 4 位二进制计数器 (count4),具有 enable 和同步并行load输入(load的优先级高于 enable

module count4(
	input clk,
	input enable,
	input load,
	input [3:0] d,
	output reg [3:0] Q
);

2.逻辑门

分析:要通过给的组件实现目标计数器。这里将count4的输入d设为1,控制load信号来实现计满置1,复位置1和正常计数功能。

module top_module (
    input clk,
    input reset,
    input enable,
    output reg [3:0] Q,
    output c_enable,
    output c_load,
    output [3:0] c_d
); //
    assign c_enable=enable;
    assign c_d=4'd1;// count4模块的输入d设为1
    assign c_load=(reset==1'd1||(enable==1'b1&&Q==4'd12))?1:0;//正常计数且计满12时或reset复位时触发load为1,load为1时将d的值(就是1)赋给q,实现置1;
    count4 count_1 (clk, c_enable, c_load, c_d,Q);//例化count4,接线
endmodule

counter 1000

题目描述:1000 Hz 时钟派生出一个 1 Hz 信号的分频器,称为 OneHertz,使用模 10 (BCD) 计数器和尽可能少的其他门构建分频器。此外,还输出你使用的每个 BCD 计数器的使能信号(c_enable[0] 表示最快的计数器,c_enable[2] 表示最慢的计数器)

其实就是实现1000进制的计数。每1000个clk输出一个 OneHertz

先讲一个我犯过的错误:

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); 
    reg [11:0]q;
    assign c_enable[0]=1'b1;
    assign c_enable[1]=(q[3:0]==4'd9);
    assign c_enable[2]=(q[7:0]==8'd99);
    assign OneHertz=(q[11:0]==12'd999);
    bcdcount counter0 (clk, reset, c_enable[0],q[3:0]);//个位计数,永远+1
    bcdcount counter1 (clk, reset, c_enable[1],q[7:4]);//负责十位计数,满10十位+1
    bcdcount counter2 (clk, reset, c_enable[2],q[11:8]);//负责百位计数,满100百位+1
endmodule

上面三行assign语句有错误,8'h99真值是10011001,BCD码也就是用4位二进制数代表1位十进制数,本题BCD计数器中3-0位代表个位,7-4代表十位,所以8'h99在本题计数器中代表十进制的99;8'd99真值是01100011,在本题BCD计数器规则中代表十进制63,而不是99,所以要将8'd99改为8'h99。同理8'd999改为8'h9998'd为统一进制格式也改为8'h9

正确写法如下:

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); 
    reg [11:0]q;
    assign c_enable[0]=1'b1;
    assign c_enable[1]=(q[3:0]==4'h9);
    assign c_enable[2]=(q[7:0]==8'h99);
    assign OneHertz=(q[11:0]==12'h999);//不要错写成8'd99和12'd999
    bcdcount counter0 (clk, reset, c_enable[0],q[3:0]);//个位计数,永远加1
    bcdcount counter1 (clk, reset, c_enable[1],q[7:4]);//负责十位计数,满10十位就加1
    bcdcount counter2 (clk, reset, c_enable[2],q[11:8]);//负责百位计数,满100百位就加1
endmodule

4-digit decimal counter

题目描述:构建一个 4 位 BCD计数器。每个十进制数字都使用 4 位进行编码:q[3:0] 是 1 位,q[7:4] 是十位,等等。对于数字 [3:1],还要输出一个使能信号,指示何时应增加前三位数字中的每一个。您需要实例化一位的十进制计数器。

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    assign ena[1]=(q[3:0]==4'h9);
    assign ena[2]=(q[7:0]==8'h99);
    assign ena[3]=(q[11:0]==12'h999);//类似上一题,不要错写成8'd99和12'd999
    bcdcount bcdcount_0(clk,reset,1'b1,q[3:0]);
    bcdcount bcdcount_1(clk,reset,ena[1],q[7:4]);
    bcdcount bcdcount_2(clk,reset,ena[2],q[11:8]);
    bcdcount bcdcount_3(clk,reset,ena[3],q[15:12]);
endmodule

module bcdcount (input clk,reset,enable,output reg[3:0]q);//一位十进制计数器
    always @(posedge clk)begin
        if(reset)begin
            q<=4'd0;
        end
        else if(enable)begin
            if(q==4'd9)
                q<=4'd0;
            else
                q<=q+4'd1;
        end
        else begin
            q<=q;
        end
    end
endmodule

12-hour clock

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    wire [6:1]enable;
    wire [7:0]hh_r;//从0到11,表示小时计数的中间变量
    
    assign enable[1]=ena&&(ss[3:0]==4'h9);//00:00:09→00:00:10
    assign enable[2]=enable[1]&&(ss[7:4]==4'h5);//00:00:59→00:01:00
    
    assign enable[3]=enable[2]&&(mm[3:0]==4'h9);//00:09:59→00:10:00
    assign enable[4]=enable[3]&&(mm[7:4]==4'h5);//00:59:59→01:00:00
    
    assign enable[5]=enable[4]&&(hh_r[3:0]==4'hb);//am 11:59:59→pm 00:00:00,小时进位,上午到下午或者下午到上午
    
    bcd_counter #(.START(4'h0),.END(4'h9))b0(clk,reset,ena,ss[3:0]);
    bcd_counter #(.START(4'h0),.END(4'h5))b1(clk,reset,enable[1],ss[7:4]); 
   
    bcd_counter #(.START(4'h0),.END(4'h9))b2(clk,reset,enable[2],mm[3:0]);
    bcd_counter #(.START(4'h0),.END(4'h5))b3(clk,reset,enable[3],mm[7:4]); 
    
    bcd_counter #(.START(4'h0),.END(4'hb))b4(clk,reset,enable[4],hh_r[3:0]); 
    bcd_counter #(.START(4'h0),.END(4'h1))b5(clk,reset,enable[5],hh_r[7:4]);//hh_r[7:4]为1代表是下午,为0代表是上午
   
    assign pm=(hh_r[7:4]==4'h1);//enable[5]为1,说明又过了12个小时,也就是又轮换了半天,pm+1
    assign hh=(hh_r[3:0]==4'h0)?8'h12:((hh_r[3:0]>4'h9)?{4'h1,hh_r[3:0]-4'ha}:{4'h0,hh_r[3:0]});
    //hh_r的0→11变到hh的1→12,当置0的时候变置12;
endmodule

module bcd_counter (input clk,reset,ena,output reg[3:0]q);//10进制计数器
    parameter START=4'h0,END=4'h9;    
    always @(posedge clk)begin
        if(reset)begin
            q<=START;
        end
        else if(ena)begin
            if(q==END)begin
                q<=START;
            end
            else begin 
                q<=q+4'h1;
            end
        end
        else begin
           q<=q; 
        end           
    end
endmodule

Shift registers

4-bit shift registers

这一题的移位是逻辑移位,移出的位舍弃,然后补0;

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<=4'd0;
        else if(load)
            q<=data;
        else if(ena)
            q<=q>>1'b1;
        else
            q<=q;
    end
endmodule

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) 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 to 8

这一题的移位是算术移位,按照题意介绍,逻辑左移和算术左移之间没有区别

逻辑右移高位补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
            q<=q;
        end
        else begin
            case(amount)
                2'b00:q<=q<<4'd1;
                2'b01:q<=q<<4'd8;
                2'b10:q<={{2{q[63]}},q[62:1]};//复制最高位填充高位		
                2'b11:q<={{9{q[63]}},q[62:8]};//复制最高位填充高位
            endcase
        end 
    end
endmodule

如果想要详细了解算术移位、逻辑移位、循环移位的区别,可以参考:2.2_5_定点数的移位运算_哔哩哔哩_bilibili

5-bit LFSR

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

3-bit LFSR

module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q
    wire a;
    assign a=LEDR[2]^LEDR[1];
    muxdff muxdff_0(SW[0],LEDR[2],KEY[0],KEY[1],LEDR[0]);
    muxdff muxdff_1(SW[1],LEDR[0],KEY[0],KEY[1],LEDR[1]);
    muxdff muxdff_2(SW[2],a,KEY[0],KEY[1],LEDR[2]);
endmodule
module muxdff(input r_in,q_in,clk,L,output reg q);
    wire d;
    assign d=L?r_in:q_in; 
    always @(posedge clk)begin
       q<=d; 
    end
endmodule

32-bit LFSR

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

Shift register

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

Shift register

module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //
    MUXDFF MUXDFF_0(KEY[0],KEY[1],KEY[2],LEDR[1],LEDR[0],SW[0],LEDR[0]);
    MUXDFF MUXDFF_1(KEY[0],KEY[1],KEY[2],LEDR[2],LEDR[1],SW[1],LEDR[1]);
    MUXDFF MUXDFF_2(KEY[0],KEY[1],KEY[2],LEDR[3],LEDR[2],SW[2],LEDR[2]);
    MUXDFF MUXDFF_3(KEY[0],KEY[1],KEY[2],KEY[3],LEDR[3],SW[3],LEDR[3]);
endmodule

module MUXDFF (input clk,E,L,w,q_in,r_in,output reg q);
    wire a,d;
    assign a=E?w:q_in;
    assign d=L?r_in:a;
    always @(posedge clk)begin
        q<=d; 
    end
endmodule

3-input 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)
            q<={q[6:0],S};
        else
            q<=q;
    end
    assign Z=q[{A,B,C}];//数据流写法,当 ABC 为 000 时,Z=Q[0],当 ABC 为 001 时,Z=Q[1],依此类推
endmodule

More circuits

rule 90

第一种方法:根据题意,元胞的下一个状态是该元胞的当前左右邻居的异或,q[511:0]所有位对应左邻居q[512:1],q[511:0]所有位对应右邻居q[510:-1],而q[512]和q[-1]是0,所以代码如下:

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [511:0] q );  
    always @(posedge clk)begin
        if(load) begin
            q<=data;
        end
        else begin
            q<={1'b0,q[511:1]}^{q[510:0],1'b0};//左邻居^右邻居
        end
    end
endmodule

第二种方法:要进行左右邻居的异或,将左邻居q[512:0]右移一位移到q[511:0]位置,将右邻居左移一位移到q[511:0]位置,这样将两组512位向量的所有位对齐了,然后对应位异或。因为逻辑移位是补0,所以也满足q[512]和q[-1]是0。

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg[511:0] q );  
    always @(posedge clk)begin
        if(load) begin
            q<=data;
        end
        else begin
            q<=(q>>1'b1)^(q<<1'b1);//左邻居^右邻居
        end
    end
endmodule

rule 110

一种错误写法:

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [511:0] q
); 
always @(posedge clk)begin
        if(load)begin
        	q <= data;
        end
        else begin 
            q <=(~q&q<<1)|(q&~q<<1)|(~q>>1&q);
        end
    end                       
endmodule

如果这样写,~q<<1代表将q取反后左移,~q>>1代表将q取反后右移,我们要表达的其实是~(q<<1)和~(q>>1),因为取反的优先级大于移位,所以这里要加括号:

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [511:0] q
); 
always @(posedge clk)begin
        if(load)begin
        	q <= data;
        end
        else begin 
            q <=(~q&(q<<1))|(q&~(q<<1))|(~(q>>1)&q);
        end
    end                       
endmodule

另外,(~q&(q<<1))|(q&~(q<<1))可以写成异或形式(q^q<<1),所以更简洁的代码如下:

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [511:0] q
); 
always @(posedge clk)begin
        if(load)begin
        	q <= data;
        end
        else begin 
            q <=(q^q<<1)|(~(q>>1)&q);
        end
    end                       
endmodule

Conway's game of life 16×16

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q ); 
    reg [3:0] count;
    integer i;
    
    always @(posedge clk)begin
        if(load)begin
        	q <= data;
        end
        else begin
            for(i=0;i<256;i++)begin
                if(i == 0)begin
                    count = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];
                end
                else if(i == 15)begin
                    count = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];
                end
                else if(i == 240)begin
                    count = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];
                end
                else if(i == 255)begin
                    count = q[238] + q[239] + q[224] + q[254] + q[240] + q[15] + q[0] + q[14];
                end
                else if( i>0 && i<15)begin
                    count = q[239+i]+q[240+i]+q[241+i]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];
                end
                else if(i>240 && i<255)begin
                    count = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i-239]+q[i-240]+q[i-241];
                end
                else if( i%16 == 0)begin
                    count = 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
                    count = 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
                    count = 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(count)
                    4'd2:q[i] <= q[i];
                    4'd3:q[i] <= 1'b1;
                    default:q[i] <= 1'b0;
                endcase
            end
        end
    end

endmodule

  • 33
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值