2021年5月3日 星期一

HDLBits答案(3 Combinational logic + 4 Sequential logic)

HDLBits答案(3 Combinational logic + 4 Sequential logic)_Lpznuaa的博客 

目录

3 Combinational logic

3.1 Basic Gates

module top_module (
    input in,
    output out);

    assign out = in;
    
endmodule

3.1.1 Wire(Exams/m2014 q4h)

module top_module (
    input in,
    output out);

    assign out = 1'b0;
    
endmodule

3.1.2 GND(Exams/m2014 q4i)

module top_module (
    input in1,
    input in2,
    output out);

    assign out = ~ (in1 | in2);
    
endmodule

3.1.3 NOR(Exams/m2014 q4e)

module top_module (
    input in1,
    input in2,
    output out);

    assign out = ~ (in1 | in2);
    
endmodule

3.1.4 Another gate(Exams/m2014 q4f)

module top_module (
    input in1,
    input in2,
    output out);

    assign out = in1 & (~in2);
    
endmodule

3.1.5 Two gates(Exams/m2014 q4g)

module top_module (
    input in1,
    input in2,
    input in3,
    output out);
	
    wire  w1;
    
    assign w1 = in1 ~^ in2;
    assign out = w1 ^ in3;
    
endmodule

3.1.6 More logic gates(Gates)

module top_module( 
    input a, b,
    output out_and,
    output out_or,
    output out_xor,
    output out_nand,
    output out_nor,
    output out_xnor,
    output out_anotb
);
    
    assign out_and = a & b; 
    assign out_or = a | b;
    assign out_xor = a ^ b;
    assign out_nand = ~ (a & b);
    assign out_nor = ~ (a | b);
    assign out_xnor = a ~^ b; 
    assign out_anotb = a & ~b;

endmodule

3.1.7 7420 chip(7420)

module top_module ( 
    input p1a, p1b, p1c, p1d,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );

    assign p1y = ~ (p1a & p1b & p1c & p1d);
    assign p2y = ~ (p2a & p2b & p2c & p2d);

endmodule

3.1.8 Truth tables(Truthtable1)

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);

    
    assign f = x3 & x1 | x2 & x1 | ~x3 & x2;
    
endmodule

3.1.9 Two-bit equality(Mt2015 eq2)

module top_module ( input [1:0] A, input [1:0] B, output z ); 

    assign z = (A == B) ? 1'b1 : 1'b0;
    
endmodule

3.1.1.10 Simple circuit A(Mt2015 q4a)

module top_module (input x, input y, output z);

    assign z = (x^y) & x;
    
endmodule

3.1.11 Simple circuit B(Mt2015 q4b)

module top_module ( input x, input y, output z );

    assign z = x ~^ y;
    
endmodule

3.1.12 Combine circuit A and B(Mt2015 q4)

module top_module (input x, input y, output z);

    wire w1,w2,w3,w4,w5,w6;
    
    assign w1 = (x^y) & x;
    assign w2 = x ~^ y;
    assign w3 = (x^y) & x;
    assign w4 = x ~^ y;
    assign w5 = w1 | w2;
    assign w6 = w3 & w4;
    assign z = w5 ^ w6;
    
endmodule

3.1.13 Ring or vibrate?(Ringer)

module top_module (
    input ring,
    input vibrate_mode,
    output ringer,       // Make sound
    output motor         // Vibrate
);

    assign ringer = ~vibrate_mode & ring;	//非震动模式+来电=响铃
    assign motor = vibrate_mode & ring;		//震动模式+来电=震动

endmodule

3.1.14 Thermostat(Thermostat)

module top_module (
    input too_cold,
    input too_hot,
    input mode,
    input fan_on,
    output heater,
    output aircon,
    output fan
); 
    
    assign heater = mode & too_cold;
    assign aircon = ~mode & too_hot;
    assign fan = fan_on | heater | aircon;

endmodule

3.1.15 3-bit population count(Popcount3)

module top_module( 
    input [2:0] in,
    output [1:0] out );
	
    reg [1:0] sum;
    integer i;
	
    always@(*)begin
        sum = 2'd0;
        for(i = 0; i <= 2; i = i + 1)begin
            sum = sum + in[i];
        end
    end
    
    assign out = sum;
    
endmodule

3.1.16 Gates and vectors(Gatesv)

module top_module( 
    input [3:0] in,
    output [2:0] out_both,
    output [3:1] out_any,
    output [3:0] out_different );
	
    integer i;
    always@(*)begin
        for (i = 0; i <3 ; i = i + 1)begin
            out_both[i] = in[i] & in[i+1];
        end            
    end
    
    always@(*)begin
        for (i = 1; i <=3; i = i + 1)begin
            out_any[i] = in[i] | in[i-1];
        end            
    end

    always@(*)begin
        for (i = 0; i <3; i = i + 1)begin
            out_different[i] = in[i] ^ in[i+1];
        end            
    end
    
    assign out_different[3] = in[3] ^ in[0];        
    
endmodule

3.1.17 Even longer vectors(Gatesv100)

module top_module( 
    input [99:0] in,
    output [98:0] out_both,
    output [99:1] out_any,
    output [99:0] out_different );
    
    integer i;
    always@(*)begin
        for (i = 0; i <99 ; i = i + 1)begin
            out_both[i] = in[i] & in[i+1];
        end            
    end
    
    always@(*)begin
        for (i = 1; i <=99; i = i + 1)begin
            out_any[i] = in[i] | in[i-1];
        end            
    end

    always@(*)begin
        for (i = 0; i <99; i = i + 1)begin
            out_different[i] = in[i] ^ in[i+1];
        end            
    end
    
    assign out_different[99] = in[99] ^ in[0]; 
    
endmodule

3.2 Multiplexers

3.2.1 2-to-1 multiplexer(Mux2to1)

module top_module( 
    input a, b, sel,
    output out ); 
    
	assign out = sel ? b : a;
      
endmodule

3.2.2 2-to-1 bus multiplexer(Mux2to1v)

module top_module( 
    input [99:0] a, b,
    input sel,
    output [99:0] out );

	assign out = sel ? b : a;
    
endmodule

3.2.3 9-to-1 multiplexer(Mux9to1v)

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output [15:0] out );

    always@(*)begin
    	case(sel)
        	4'b0000:begin
        		out = a;
        	end
       	 	4'b0001:begin
        		out = b;
        	end
            4'b0010:begin
        		out = c;
        	end
       	 	4'b0011:begin
        		out = d;
        	end
        	4'b0100:begin
        		out = e;
        	end
       	 	4'b0101:begin
        		out = f;
            end
       	 	4'b0110:begin
        		out = g;
        	end
        	4'b0111:begin
        		out = h;
        	end
       	 	4'b1000:begin
        		out = i;
        	end
            default:begin
        		out = 16'hffff;
        	end
    	endcase
    end
    
endmodule

3.2.4 256-to-1 multiplexer(Mux256to1)

module top_module( 
    input [255:0] in,
    input [7:0] sel,
    output out );
	
    assign out = in[sel];	//sel对应in的标号
    
endmodule

3.2.5 256-to-1 4bit multiplexer(Mux256to1v)

module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
	
    assign out = in [ sel * 4 +: 4];	//取起点为4*sel,长度为4的字段
    
endmodule

3.3 Arithmetic Circuits

3.3.1 Half adder(Hadd)

module top_module( 
    input a, b,
    output cout, sum );

    assign cout = a & b;
    assign sum = a ^ b;
    
endmodule

3.3.2 Full adder(Fadd)

module top_module( 
    input a, b, cin,
    output cout, sum );
	
    wire [1:0] temp;
    assign temp = a + b + cin;		//直接使用加法,结果正确。实际需要通过逻辑关系得到sumcout;
    assign cout = temp[1];
    assign sum = temp[0];
    
endmodule

3.3.3 3-bit binary adder(Adder3)

module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
    
    Fadd Fadd1(a[0],b[0],cin,cout[0],sum[0]);			//三个级联的全加器构成行波进位加法器
    Fadd Fadd2(a[1],b[1],cout[0],cout[1],sum[1]);
    Fadd Fadd3(a[2],b[2],cout[1],cout[2],sum[2]);
    
endmodule

module Fadd( 						//一位全加器
    input a, b, cin,
    output cout, sum );
	
    wire [1:0] temp;
    assign temp = a + b + cin;		//直接使用加法,结果正确。实际需要通过逻辑关系得到sumcout;
    assign cout = temp[1];
    assign sum = temp[0];
    
endmodule

3.3.4 Adder(Exams/m2014 q4j)

module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
    
    wire [2:0] cout;
    
    FA Fadd1(x[0],y[0],1'b0,cout[0],sum[0]);			//四个级联的全加器构成行波进位加法器
    FA Fadd2(x[1],y[1],cout[0],cout[1],sum[1]);
    FA Fadd3(x[2],y[2],cout[1],cout[2],sum[2]);
    FA Fadd4(x[3],y[3],cout[2],sum[4],sum[3]);
    
endmodule

module FA( 						//一位全加器
    input a, b, cin,
    output cout, sum );
	
    wire [1:0] temp;
    assign temp = a + b + cin;		//直接使用加法,结果正确。实际需要通过逻辑关系得到sumcout;
    assign cout = temp[1];
    assign sum = temp[0];
    
endmodule

3.3.5 Signed addition overflow(Exams/ece241 2014 q1c)

module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); //
 
    assign s = a + b;
    assign overflow = a[7] & b[7] & ~s[7] | ~a[7] & ~b[7] & s[7];    //最高位与次高位状态不同有溢出

endmodule

3.3.6 100-bit binary adder(Adder100)

module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    
    assign {
    cout, sum} = a + b + cin;
    
endmodule

3.3.7 4-digit BCD adder(Bcdadd4)

module top_module( 
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );

    wire [2:0] cout_tmp;
    
    bcd_fadd bcd_fadd1(
        .a		(a[3:0]		),
        .b		(b[3:0]		),
        .cin	(cin		),
        .cout	(cout_tmp[0]),
        .sum	(sum[3:0]	)
    );

    bcd_fadd bcd_fadd2(
        .a		(a[7:4]		),
        .b		(b[7:4]		),
        .cin	(cout_tmp[0]),
        .cout	(cout_tmp[1]),
        .sum	(sum[7:4]	)
    );
    bcd_fadd bcd_fadd3(
        .a		(a[11:8]	),
        .b		(b[11:8]	),
        .cin	(cout_tmp[1]),
        .cout	(cout_tmp[2]),
        .sum	(sum[11:8]	)
    );
   bcd_fadd bcd_fadd4(
        .a		(a[15:12]	),
        .b		(b[15:12]	),
        .cin	(cout_tmp[2]),
        .cout	(cout		),
        .sum	(sum[15:12]	)
   );
    
endmodule

3.4 Karnaugh Map to Circuit

3.4.1 3-variable(Kmap1)

module top_module(
    input a,
    input b,
    input c,
    output out  ); 

    assign out = a | b | c;
    
endmodule

3.4.2 4-variable(Kmap2)

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = ~a & ~d | ~b & ~c | b & c & d | a & c & d;		//卡诺图化简
 
endmodule

3.4.3 4-variable(Kmap3)

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = ~b & c | a & c | a & ~d;		//卡诺图化简
 
endmodule

3.4.4 4-variable(Kmap4)

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = ~a & b & ~c & ~d | a & ~b & ~c & ~d | 
        		 ~a & ~b & ~c & d | a & b & ~c & d | 
        		 ~a & b & c & d | a & ~b & c & d | 
        		 ~a & ~b & c & ~d | a & b & c & ~d;
 
endmodule

3.4.5 Minimum SOP and POS(Exams/ece241 2013 q3)

module top_module (
    input a,
    input b,
    input c,
    input d,
    output out_sop,
    output out_pos
); 
	//最大项与最小项
    assign out_sop = c & d | ~a & ~b & c;
    assign out_pos = ~((~c | ~d) & (a | b | ~c));
    
endmodule

3.4.6 Karnaugh map(Exams/m2014 q3)

module top_module (
    input [4:1] x, 
    output f );

    assign f = ~x[1] & x[3] | x[1] & x[2] & ~x[3];
    
endmodule

3.4.7 Karnaugh map(Exams/2012 q1g)

module top_module (
    input [4:1] x,
    output f
); 
 
    assign f = ~x[1] & x[3] | x[2] & x[3] & x[4] | ~x[2] & ~x[4];
    
endmodule

3.4.8 K-map implemented with a multiplexer(Exams/ece241 2014 q3)

module top_module (
    input c,
    input d,
    output [3:0] mux_in
); 
    //判断卡诺图中abcd的关系即可
    assign mux_in[0] = c | d;
    assign mux_in[1] = 1'b0;
    assign mux_in[2] = ~d;
    assign mux_in[3] = c & d;

endmodule

4 Sequential logic

4.1 Latches and Flip-Flops

4.1.1 D flip-flop(Dff)

module top_module (
    input clk,    // Clocks are used in sequential circuits
    input d,
    output reg q );//

    // Use a clocked always block
    //   copy d to q at every positive edge of clk
    //   Clocked always blocks should use non-blocking assignments
    
    always@(posedge clk)begin
    	q <= d;
    end

endmodule

4.1.2 D flip-flop(Dff8)

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

4.1.3 DFF with reset(Dff8r)

module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output [7:0] q
);

    always@(posedge clk)begin
        if(reset)begin
        	q <= 8'd0;
        end
        else begin
    	q <= d;
        end
    end

endmodule

4.1.4 DFF with reset value(Dff8p)

module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output [7:0] q
);

    always@(negedge clk)begin
        if(reset)begin
        	q <= 8'h34;
        end
        else begin
    	q <= d;
        end
    end

endmodule

4.1.5 DFF with asynchronous reset(Dff8ar)

module top_module (
    input clk,
    input areset,   // active high asynchronous reset
    input [7:0] d,
    output [7:0] q
);

    always@(posedge clk or posedge areset)begin
        if(areset)begin
        	q <= 8'd0;
        end
        else begin
    	q <= d;
        end
    end

endmodule

4.1.6 DFF with byte enable(Dff16e)

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

endmodule

4.1.7 D Latch(Exams/m2014 q4a)

module top_module (
    input d, 
    input ena,
    output q);

    always@(*)begin
        if(ena)begin
        	q = d;
        end
        else begin
        	q = q;
        end
    end
    
endmodule

4.1.8 DFF(Exams/m2014 q4b)

module top_module (
    input clk,
    input d, 
    input ar,   // asynchronous reset
    output q);

    always@(posedge clk or posedge ar)begin
        if(ar == 1'b1)begin			//异步复位,高电平有效
        	q <= 1'b0;
        end
        else begin
        	q <= d;
        end  
    end
        
endmodule

4.1.9 DFF (Exams/m2014 q4c)

module top_module (
    input clk,
    input d, 
    input r,   // synchronous reset
    output q);
    
    always@(posedge clk)begin
        if(r == 1'b1)begin			//同步复位,高电平有效
        	q <= 1'b0;
        end
        else begin
        	q <= d;
        end  
    end
    
endmodule

4.1.10 DFF+gate(Exams/m2014 q4d)

module top_module (
    input clk,
    input in, 
    output out);

    always@(posedge clk)begin
    	out <= in ^ out;
    end
    
endmodule

4.1.11 Mux and DFF(Mt2015 muxdff)

module top_module (
	input clk,
	input L,
	input r_in,
	input q_in,
	output reg Q);

    always@(posedge clk)begin
        if(L)begin		//判断数据选择器的输出
        	Q <= r_in;		
        end
        else begin
            Q <= q_in;
        end
    end
    
endmodule

4.1.12 Mux and DFF(Exams/2014 q4a)

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

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

4.1.13 DFFs and gates(Exams/ece241 2014 q4)

module top_module (
    input clk,
    input x,
    output z
);
    
  	reg [2:0]	Q;
    always@(posedge clk)begin
        Q[0] <= Q[0] ^ x;
        Q[1] <= ~Q[1] & x;
        Q[2] <= ~Q[2] | x;
    end
    
    assign z = ~(| Q);
    
endmodule

4.1.14 Creat circuit from truth table(Exams/ece241 2013 q7)

module top_module (
    input clk,
    input j,
    input k,
    output Q); 

    always@(posedge clk)begin
        case({
    j,k})					//使用case进行条件匹配
            2'b00:begin
                Q <= Q;
            end
            2'b01:begin
                Q <= 1'b0;
            end
            2'b10:begin
                Q <= 1'b1;
            end
            2'b11:begin
                Q <= ~Q;
            end
        endcase
    end
    
endmodule

4.1.15 Detect an edge(Edgedetect)

//上升沿检测器,对比输入信号在相邻两个clk处的值进行判断
module top_module (
    input clk,
    input [7:0] in,
    output [7:0] pedge
);

    reg [7:0]	in_reg;
    always@(posedge clk)begin
        in_reg <= in;		//寄存器状态更新
    end
  
    always@(posedge clk)begin
        pedge <= in & ~in_reg;	//前后状态对比,输出正边沿检测结果
    end

endmodule

4.1.16 Detect both edge(Edgedetect2)

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] anyedge
);
    reg [7:0]	in_reg;
    always@(posedge clk)begin
        in_reg <= in;
    end
  
    always@(posedge clk)begin
        anyedge <= in ^ in_reg;		//判断前后值是否相同,即边沿检测
    end
    
endmodule

4.1.17 Edge capture register(Edgecapture)

module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output [31:0] out
);
    reg [31:0]	in_reg;
    always@(posedge clk)begin
        in_reg <= in;
    end
  
    always@(posedge clk)begin
        if(reset)begin
            out <= 32'd0;
        end
        else begin
            out <= ~in & in_reg | out; //由时序图可得此关系式
        end
    end

endmodule

4.1.18 Dual-edge triggered flip-flop(Dualedge)

module top_module (
    input clk,
    input d,
    output q
);
    
    reg q_d1,q_d2;
    //上升沿检测
	always@(posedge clk)begin
        q_d1 <= d ^ q_d2;
    end
    //下降沿检测
    always@(negedge clk)begin
        q_d2 <= d ^ q_d1;
    end
    
    assign q = q_d1 ^ q_d2;

endmodule

4.2 Counters

4.2.1 Four-bit binary counter(Count15)

module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output [3:0] q);

    always@(posedge clk)begin
        if(reset)begin
        	q <= 4'd0;
        end
        else begin
        	q <= q + 1'd1;
        end
    end
    
endmodule

4.2.2 Decade counter(Count10)

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

4.2.3 Decade counter again(Count1to10)

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

4.2.4 Show decade counter(Countslow)

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);
    
    //先判断reset,其次判断slowena,在slowena有效情况下进行0-9计数
    always@(posedge clk)begin
        if(reset==1'b1)begin
        	q <= 4'd0;
        end
        else if(slowena) begin
            if(q==4'd9)begin
            	q <= 4'd0;
            end
            else begin
            	q <= q + 1'b1;
            end
        end
    end
    
endmodule

4.2.5 Counter 1-12(Exams/ece241 2014 q7a)

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'd0;
    count4 the_counter (clk, c_enable, c_load, c_d ,Q);

endmodule

4.2.6 Counter 1000(Exams/ece241 2014 q7b)

module top_module (
    input clk,
    input reset,
    output OneHertz,
    output [2:0] c_enable
); //
    
    wire[3:0]	one, ten, hundred; 
    
    bcdcount counter0 (clk, reset, c_enable[0], one);
    bcdcount counter1 (clk, reset, c_enable[1], ten);
    bcdcount counter2 (clk, reset, c_enable[2], hundred);
    
    assign c_enable =  {
    one == 4'd9 && ten == 4'd9, one == 4'd9, 1'b1};
  	assign OneHertz = (one == 4'd9 && ten == 4'd9 && hundred == 4'd9);
    
endmodule

4.2.7 4-digit decimal counter(Countbcd)

module top_module (
    input clk,
    input reset,   // Synchronous active-high reset
    output [3:1] ena,
    output [15:0] q);
    
    reg [3:0]	ones;
    reg [3:0]	tens;
    reg [3:0]	hundreds;
    reg [3:0]	thousands;
    
    //个位清零加一
    always@(posedge clk)begin
        if(reset)begin
            ones <= 4'd0;
        end
        else if(ones == 4'd9)begin
            ones <= 4'd0;
        end
        else begin
            ones <= ones + 1'b1;
        end
    end
    //十位清零加一
    always@(posedge clk)begin
        if(reset)begin
            tens <= 4'd0;
        end
        else if(tens == 4'd9 && ones == 4'd9)begin
            tens <= 4'd0;
        end
        else if(ones == 4'd9) begin
            tens <= tens + 1'b1;
        end
    end
    //百位清零加一
    always@(posedge clk)begin
        if(reset)begin
            hundreds <= 4'd0;
        end
        else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)begin
            hundreds <= 4'd0;
        end
        else if(tens == 4'd9 && ones == 4'd9) begin
            hundreds <= hundreds + 1'b1;
        end
    end
    //千位清零加一
    always@(posedge clk)begin
        if(reset)begin
            thousands <= 4'd0;
        end
        else if(thousands == 4'd9 && hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)begin
            thousands <= 4'd0;
        end
        else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9) begin
            thousands <= thousands + 1'b1;
        end
    end
    
	//输出
    assign q = {
    thousands, hundreds, tens, ones};		    
    assign ena[1] = (ones == 4'd9) ? 1'b1 : 1'b0;
    assign ena[2] = (tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
    assign ena[3] = (hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
 
endmodule

4.2.8 12-hour clock(Count clock)

待完成

4.3 Shift Registers

4.3.1 4-bit shift register(Shift4)

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

endmodule

4.3.2 Left/right rotator(Rotate100)

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: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

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

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

4.3.4 5-bit LFSR(Lfsr5)

module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 

    always@(posedge clk)begin
        if(reset)begin
        	q <= 5'h1;
        end
        else begin
            q[4] <= q[0] ^ 1'b0;
            q[3] <= q[4];
            q[2] <= q[3] ^ q[0];
            q[1] <= q[2];
            q[0] <= q[1];
        end
    end
    
endmodule

4.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

    always@(posedge KEY[0])begin
        if(KEY[1])begin
        	LEDR <= SW;
        end
        else begin
            LEDR[0] <= LEDR[2];
            LEDR[1] <= LEDR[0];
            LEDR[2] <= LEDR[1] ^ LEDR[2];
        end
    end
endmodule

4.3.6 32-bit LFSR(Lfsr32)

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

endmodule

4.3.7 Shift register(Exams/m2014 q4k)

module top_module (
    input clk,
    input resetn,   // synchronous reset
    input in,
    output out);

    reg [2:0] q;
    always@(posedge clk or negedge resetn)begin
        if(resetn==1'b0)begin
        	out <= 1'b0;
        end
        else begin
            q[0] <= in;
            q[1] <= q[0];
            q[2] <= q[1];
            out <= q[2];
        end
    end
    
endmodule

4.3.8 Shift register(Exams/m2014 q4b)

module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //
    MUXDFF u1_MUXDFF(
        .clk            (KEY[0]	),
        .w		(KEY[3]	),
        .R		(SW[3]	),
        .E		(KEY[1]	),
        .L		(KEY[2]	),
        .Q		(LEDR[3])
    );
    MUXDFF u2_MUXDFF(
        .clk	(KEY[0]	),
        .w		(LEDR[3]),
        .R		(SW[2]	),
        .E		(KEY[1]	),
        .L		(KEY[2]	),
        .Q		(LEDR[2])
    );
    MUXDFF u3_MUXDFF(
        .clk	(KEY[0]	),
        .w		(LEDR[2]),
        .R		(SW[1]	),
        .E		(KEY[1]	),
        .L		(KEY[2]	),
        .Q		(LEDR[1])
    );
    MUXDFF u4_MUXDFF(
        .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
);

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

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

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

4.4 More Circuits

4.4.1 Rule 90(Rule90)

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [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

4.4.2 Rule 110(Rule110)

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q
); 
    
     always@(posedge clk)begin
        if(load)begin
            q <= data;
        end
        else begin
            //真值表可得出q的逻辑表达式
            q <= ~q & {
    q[510:0], 1'b0} | 
            	~{
    1'b0, q[511:1]} & {
    q[510:0], 1'b0} | 
            	~{
    1'b0, q[511:1]} & q | 
            	q & ~{
    q[510:0], 1'b0};			

        end
    end

endmodule

4.4.3 Conway’s Game of Life 16x16(Conwaylife)

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	//load=1时加载数据
            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
                //判断邻居的数量更新自身状态,邻居状态为0/1从而可通过邻居求和结果来判断
                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

4.5 Finite State Machines

4.5.1 Simple FSM 1(asynchronous reset)

module top_module(
    input clk,
    input areset,    // Asynchronous reset to state B
    input in,
    output out);//  
	
    //状态机三段法
    
    //参数声明
    parameter A=1'b0, B=1'b1; 
    
    //内部信号声明
    reg state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk, posedge areset) begin  
        if(areset)begin
        	state <= B;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            A:begin
                if(in == 1'b1)begin
                	next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            B:begin
                if(in == 1'b1)begin
                	next_state = B;
                end
                else begin
                    next_state = A;
                end
            end 
        endcase
    end

	//输出逻辑
     always@(*)begin 
        if(state == B)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end
    
endmodule

4.5.2 Simple FSM 1(synchronous reset)

// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
    input clk;
    input reset;    // Synchronous reset to state B
    input in;
    output out;//  
    reg out;

    //状态机三段法
    
    //参数声明
    parameter A=1'b0, B=1'b1; 
    
    //内部信号声明
    reg state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk) begin  
        if(reset)begin
        	state <= B;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            A:begin
                if(in == 1'b1)begin
                	next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            B:begin
                if(in == 1'b1)begin
                	next_state = B;
                end
                else begin
                    next_state = A;
                end
            end 
        endcase
    end

	//输出逻辑
     always@(*)begin 
        if(state == B)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end

endmodule

4.5.3 Simple FSM 2(asynchronous reset)

module top_module(
    input clk,
    input areset,    // Asynchronous reset to OFF
    input j,
    input k,
    output out); //  

   //状态机三段法
        
    //参数声明
    parameter OFF=0, ON=1; 
    
    //内部信号声明
    reg state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk, posedge areset) begin  
        if(areset)begin
        	state <= OFF;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            OFF:begin
                if(j == 1'b0)begin
                	next_state = OFF;
                end
                else begin
                    next_state = ON;
                end
            end
            ON:begin
                if(k == 1'b0)begin
                	next_state = ON;
                end
                else begin
                    next_state = OFF;
                end
            end 
        endcase
    end

	//输出逻辑
     always@(*)begin 
         if(state == ON)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end
    

endmodule

4.5.4 Simple FSM 2(synchronous reset)

module top_module(
    input clk,
    input reset,    // synchronous reset to OFF
    input j,
    input k,
    output out); 

   //状态机三段法
        
    //参数声明
    parameter OFF=0, ON=1; 
    
    //内部信号声明
    reg state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk) begin  
        if(reset)begin
        	state <= OFF;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            OFF:begin
                if(j == 1'b0)begin
                	next_state = OFF;
                end
                else begin
                    next_state = ON;
                end
            end
            ON:begin
                if(k == 1'b0)begin
                	next_state = ON;
                end
                else begin
                    next_state = OFF;
                end
            end 
        endcase
    end

	//输出逻辑
     always@(*)begin 
         if(state == ON)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end
   
endmodule

4.5.5 Simple state transitions 3(Fsm3comb)

module top_module(
    input in,
    input [1:0] state,
    output [1:0] next_state,
    output out); //
	

        
    //参数声明
    parameter A=0, B=1, C=2, D=3;
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            A:begin
                if(in == 1'b0)begin
                	next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            B:begin
                if(in == 1'b0)begin
                	next_state = C;
                end
                else begin
                    next_state = B;
                end
            end 
            C:begin
                if(in == 1'b0)begin
                	next_state = A;
                end
                else begin
                    next_state = D;
                end
            end
            D:begin
                if(in == 1'b0)begin
                	next_state = C;
                end
                else begin
                    next_state = B;
                end
            end 
        endcase
    end

    /*  if else 可用三目运算符?替换
    always@(*)begin
        case(state)
            A:begin
                next_state = in ? B : A;
            end
            B:begin
                next_state = in ? B : C;
            end
            C:begin
                next_state = in ? D : A;
            end
            D:begin
                next_state = in ? B : C;
            end
        endcase
    end

    */
    
	//输出逻辑
     always@(*)begin 
         if(state == D)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end

endmodule

4.5.6 Simple one-hot state transitions 3(Fsm3onehot)

module top_module(
    input in,
    input [3:0] state,
    output [3:0] next_state,
    output out); //

    parameter A=0, B=1, C=2, D=3;

    // State transition logic: Derive an equation for each state flip-flop.
    assign next_state[A] = state[A] & ~in | state[C] & ~in;
    assign next_state[B] = state[A] & in | state[B] & in | state[D] & in;
    assign next_state[C] = state[B] & ~in | state[D] & ~in;
    assign next_state[D] = state[C] & in;

    // Output logic: 
    assign out = state[D];

endmodule

4.5.7 Simple FSM 3 (asynchronous reset)(Fsm3)

module top_module(
    input clk,
    input in,
    input areset,
    output out); //

    //状态机三段法
        
    //参数声明
    parameter A=0, B=1, C=2, D=3; 
    
    //内部信号声明
    reg [1:0] state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk, posedge areset) begin  
        if(areset)begin
        	state <= A;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            A:begin
                if(in == 1'b0)begin
                	next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            B:begin
                if(in == 1'b0)begin
                	next_state = C;
                end
                else begin
                    next_state = B;
                end
            end 
            C:begin
                if(in == 1'b0)begin
                	next_state = A;
                end
                else begin
                    next_state = D;
                end
            end
            D:begin
                if(in == 1'b0)begin
                	next_state = C;
                end
                else begin
                    next_state = B;
                end
            end 
        endcase
    end


	//输出逻辑
     always@(*)begin 
         if(state == D)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end

endmodule

4.5.8 Simple FSM 3 (synchronous reset)(Fsm3s)

module top_module(
    input clk,
    input in,
    input reset,
    output out); //

    //状态机三段法
        
    //参数声明
    parameter A=0, B=1, C=2, D=3; 
    
    //内部信号声明
    reg [1:0] state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk) begin  
        if(reset)begin
        	state <= A;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            A:begin
                if(in == 1'b0)begin
                	next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            B:begin
                if(in == 1'b0)begin
                	next_state = C;
                end
                else begin
                    next_state = B;
                end
            end 
            C:begin
                if(in == 1'b0)begin
                	next_state = A;
                end
                else begin
                    next_state = D;
                end
            end
            D:begin
                if(in == 1'b0)begin
                	next_state = C;
                end
                else begin
                    next_state = B;
                end
            end 
        endcase
    end


	//输出逻辑
     always@(*)begin 
         if(state == D)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end

endmodule

4.5.9 Design a Moore FSM (Exams/ece241 2013 q4)

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
    
    parameter IDLE = 3'd0, SENSOR_1 = 3'd1;
    parameter SENSOR_2 = 3'd2, SENSOR_3 = 3'd3;
    reg	[2:0]	state;
    reg [2:0]	next_state;
    
    always@(posedge clk)begin
        if(reset)begin
            state <= 'd0;
        end
        else begin
            state <= next_state;
        end
    end
    
    always@(*)begin
        case(state)
            IDLE:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b001) ? SENSOR_1 : IDLE;
            end
            SENSOR_1:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b011) ? SENSOR_2 : IDLE;
            end
            SENSOR_2:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b111) ? SENSOR_3 : IDLE;
            end
            SENSOR_3:begin
                case(s)
                    3'b001:begin
                        next_state = SENSOR_1;
                    end
                    3'b011:begin
                        next_state = SENSOR_2;
                    end
                    3'b111:begin
                        next_state = SENSOR_3;
                    end
                    default:begin
                        next_state = IDLE;
                    end
                endcase
                //next_state = (s == 3'b011) ? SENSOR_2 : ( (s == 3'b001) ? SENSOR_1 : IDLE );
            end
            default:begin
                next_state = IDLE;
            end
        endcase
    end
    
    assign fr3 = (state == IDLE);
    assign fr2 = (state == IDLE || state == SENSOR_1);
    assign fr1 = (state == IDLE || state == SENSOR_1 || state == SENSOR_2);
    //assign dfr = (state == SENSOR_2 && next_state == SENSOR_1 || state == SENSOR_3 && next_state == SENSOR_1 || state == SENSOR_3 && next_state == SENSOR_2);
 
    
    reg fr3_reg;
    reg fr2_reg;
    reg fr1_reg;
    always@(posedge clk)begin
        fr3_reg <= fr3;
    end
    always@(posedge clk)begin
        fr2_reg <= fr2;
    end
    always@(posedge clk)begin
        fr1_reg <= fr1;
    end
    
    //assign dfr = ~fr3 & fr3_reg | ~fr2 & fr2_reg | ~fr1 & fr1_reg ? 1'b0 : 1'b1;
    
    always@(*)begin
        if(~fr3 & fr3_reg | ~fr2 & fr2_reg | ~fr1 & fr1_reg)begin
        	dfr = 1'b0;
    	end
        else if(fr3 & ~fr3_reg | fr2 & ~fr2_reg | fr1 & ~fr1_reg)begin
            dfr = 1'b1;
        end
    end  
    
endmodule

4.5.10 Lemmings 1(Lemmings1)

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    output walk_left,
    output walk_right); //  
    
    //状态机三段法
        
    //参数声明
    parameter LEFT=0, RIGHT=1;
    reg state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk, posedge areset) begin  
        if(areset)begin
        	state <= LEFT;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            LEFT:begin
                if(bump_left)begin
                    next_state = RIGHT;
                end
                else begin
                    next_state = LEFT;
                end
            end
            RIGHT:begin
                if(bump_right)begin
                	next_state = LEFT;
                end
                else begin
                    next_state = RIGHT;
                end
            end 
        endcase
    end


	//输出逻辑
     always@(*)begin 
         if(state == LEFT)begin
            walk_left = 1'b1;
            walk_right = 1'b0;
        end
        else begin
            walk_left = 1'b0;
            walk_right = 1'b1;
        end
    end

endmodule

4.5.11 Lemmings 2(Lemmings2)

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    output walk_left,
    output walk_right,
    output aaah ); 
    
    //状态机三段法
        
    //参数声明
    parameter LEFT=0, RIGHT=1, GROUND_LEFT=2, GROUND_RIGHT = 3;
    reg [1:0]state, next_state;
    
    //状态寄存器(时序)
    always @(posedge clk, posedge areset) begin  
        if(areset)begin
        	state <= LEFT;
        end
        else begin
        	state <= next_state;
        end
    end
    
	//次态的组合逻辑
    always@(*) begin    
        case(state)
            LEFT:begin
                if(ground)begin
                    if(bump_left)begin
                    	next_state = RIGHT;
                    end
                    else begin
                        next_state = LEFT;
                    end
                end
                else begin
                    next_state = GROUND_LEFT;
                end
            end
            RIGHT:begin
                if(ground)begin
                    if(bump_right)begin
                    	next_state = LEFT;
                    end
                    else begin
                        next_state = RIGHT;
                    end
                end
                else begin
                    next_state = GROUND_RIGHT;
                end
            end
            GROUND_LEFT:begin
                if(ground)begin
                	next_state = LEFT;
                end
                else begin
                    next_state = GROUND_LEFT;
                end
            end
            GROUND_RIGHT:begin
                if(ground)begin
                	next_state = RIGHT;
                end
                else begin
                    next_state = GROUND_RIGHT;
                end
            end
        endcase
    end

	//输出逻辑
	assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = (state == GROUND_LEFT || state == GROUND_RIGHT);

endmodule

4.5.12 Lemmings 3(Lemmings3)

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    input dig,
    output walk_left,
    output walk_right,
    output aaah,
    output digging ); 
        
    //状态机三段法
        
    //参数声明
    parameter LEFT = 4'd0, RIGHT = 4'd1, GROUND_LEFT = 4'd2, GROUND_RIGHT = 4'd3, DIGGING_LEFT = 4'd4, DIGGING_RIGHT = 4'd5;
    reg	[3:0]	state;
    reg [3:0]	next_state;
    
	//状态寄存器(时序)
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            state <= LEFT;
        end
        else begin
            state <= next_state;
        end
    end
    //次态的组合逻辑(可使用if-else或三目运算符?进行处理,此处使用三目运算符)
    always@(*)begin
        case(state)
            LEFT:begin
                next_state = ground ? (dig ? DIGGING_LEFT : (bump_left ? RIGHT : LEFT)) : GROUND_LEFT;
            end
            RIGHT:begin
                next_state = ground ? (dig ? DIGGING_RIGHT : (bump_right ? LEFT : RIGHT)) : GROUND_RIGHT;
            end
            GROUND_LEFT:begin
                next_state = ground ? LEFT : GROUND_LEFT;
            end
            GROUND_RIGHT:begin
                next_state = ground ? RIGHT : GROUND_RIGHT;
            end
            DIGGING_LEFT:begin
                next_state = ground ? DIGGING_LEFT : GROUND_LEFT;
            end
            DIGGING_RIGHT:begin
                next_state = ground ? DIGGING_RIGHT : GROUND_RIGHT;
            end
            default:begin
                next_state = LEFT;
            end
        endcase
    end    
    
	//输出逻辑
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign digging = (state == DIGGING_LEFT || state == DIGGING_RIGHT);
    assign aaah = (state == GROUND_LEFT || state == GROUND_RIGHT);
 
endmodule

4.5.13 Lemmings 4(Lemmings4)

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    input dig,
    output walk_left,
    output walk_right,
    output aaah,
    output digging ); 
    
	//状态机三段法(较上一题多了一个计数器,用以统计跌落时间,判断是否飞溅)
        
    //参数声明
    parameter LEFT = 4'd0, RIGHT = 4'd1, GROUND_LEFT = 4'd2, GROUND_RIGHT = 4'd3;
    parameter DIGGING_LEFT = 4'd4, DIGGING_RIGHT = 4'd5, SPLATTER = 4'd6, AAAH_END = 4'd7;
    reg	[3:0]	state;
    reg [3:0]	next_state;
    
    //状态寄存器(时序)
    reg [4:0]	counter;
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            counter <= 5'd0;
        end
        else if(next_state == GROUND_LEFT || next_state == GROUND_RIGHT)begin
            counter <= counter + 1'b1;
        end
        else begin
            counter <= 5'd0;
        end
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            state <= LEFT;
        end
        else begin
            state <= next_state;
        end
    end
	
    //次态的组合逻辑
    always@(*)begin
        case(state)
            LEFT:begin
                next_state = ground ? (dig ? DIGGING_LEFT : (bump_left ? RIGHT : LEFT)) : GROUND_LEFT;
            end
            RIGHT:begin
                next_state = ground ? (dig ? DIGGING_RIGHT : (bump_right ? LEFT : RIGHT)) : GROUND_RIGHT;
            end
            GROUND_LEFT:begin
                next_state = ground ? LEFT : (counter == 5'd20 ? SPLATTER : GROUND_LEFT);
            end
            GROUND_RIGHT:begin
                next_state = ground ? RIGHT : (counter == 5'd20 ? SPLATTER : GROUND_RIGHT);
            end
            DIGGING_LEFT:begin
                next_state = ground ? DIGGING_LEFT : GROUND_LEFT;
            end
            DIGGING_RIGHT:begin
                next_state = ground ? DIGGING_RIGHT : GROUND_RIGHT;
            end
            SPLATTER:begin
                next_state = ground ? AAAH_END : SPLATTER;
            end
            AAAH_END:begin
                next_state = AAAH_END;
            end
            default:begin
                next_state = LEFT;
            end
        endcase
    end    
    //输出逻辑
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign digging = (state == DIGGING_LEFT || state == DIGGING_RIGHT);
    assign aaah = (state == GROUND_LEFT || state == GROUND_RIGHT || state == SPLATTER);   
 
endmodule

4.5.14 One-hot FSM(Fsm onehot)

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
    
	//状态机三段法
        
    //参数声明
    parameter S0 = 4'd0, S1 = 4'd1, S2 = 4'd2, S3 = 4'd3, S4= 4'd4,S5 = 4'd5,S6= 4'd6, S7 = 4'd7, S8 =4'd8, S9 = 4'd9;
    
	assign next_state[S0] = ~in & (state[S0] | state[S1] | state[S2] | state[S3] | state[S4] | state[S7] | state[S8] | state[S9]);
    assign next_state[S1] = in & (state[S0] | state[S8] | state[S9]);
    assign next_state[S2] = in & state[S1];
    assign next_state[S3] = in & state[S2];
    assign next_state[S4] = in & state[S3];
    assign next_state[S5] = in & state[S4];
    assign next_state[S6] = in & state[S5];
    assign next_state[S7] = in & (state[S6] | state[S7]);
    assign next_state[S8] = ~in & state[S5];
    assign next_state[S9] = ~in & state[S6];
	
    assign out1 = state[S8] | state[S9];
    assign out2 = state[S7] | state[S9];

endmodule

4.5.15 PS/2 packet parser(Fsm ps2)

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output done); //
 
    //状态机三段式
    //参数定义
	parameter S1 = 3'd0, S2 = 3'd1, S3 = 3'd2, DONE = 3'd3;
    reg [2:0]	state;
    reg [2:0]	next_state;
    
    //状态寄存器(时序)
    always@(posedge clk)begin
        if(reset)begin
            state <= S1;
        end
        else begin
            state <= next_state;
        end
    end
    //次态的组合逻辑
    always@(*)begin
        case(state)
            S1:begin
                next_state = in[3] ? S2 : S1;
            end
            S2:begin
                next_state = S3;
            end
            S3:begin
                next_state = DONE;
            end
            DONE:begin
                next_state = in[3] ? S2 : S1;
            end 
            default:begin
                next_state = S1;
            end
        endcase
    end
    
    //组合逻辑输出
    assign done = (state == DONE);
 
endmodule

4.5.16 PS/2 packet parser and datapath(Fsm ps2data)

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output [23:0] out_bytes,
    output done); //
 
    //状态机三段式
    //参数声明
    parameter S1 = 3'd0, S2 = 3'd1, S3 = 3'd2, DONE = 3'd3;
    
    //状态寄存器
    reg [2:0]	state;
    reg [2:0]	next_state;
    reg	[23:0]	out_bytes_reg;
    
   //状态寄存器(时序) 
    always@(posedge clk)begin
        if(reset)begin
            state <= S1;
        end
        else begin
            state <= next_state;
        end
    end
    
    //次态的组合逻辑
    always@(*)begin
        case(state)
            S1:begin
                next_state = in[3] ? S2 : S1;
            //    out_bytes_reg[23:16] = in;
            end
            S2:begin
                next_state = S3;
            //    out_bytes_reg[15:8] = in;
            end
            S3:begin
                next_state = DONE;
            //    out_bytes_reg[7:0] = in;
            end
            DONE:begin
                next_state = in[3] ? S2 : S1;
            //    out_bytes_reg[23:16] = in;
            end 
            default:begin
                next_state = S1;
            end
        endcase
    end
    
    always@(posedge clk)begin
        if(next_state == S2)begin
            if(state == S1)begin
                out_bytes_reg[23:16] <= in;
            end
            else if(state == DONE)begin
                out_bytes_reg[23:16] <= in;
            end
        end
    end
    
    always@(posedge clk)begin
        if(next_state == S3)begin
            out_bytes_reg[15:8] = in;
        end
    end
    
    always@(posedge clk)begin
        if(next_state == DONE)begin
            out_bytes_reg[7:0] = in;
        end
    end   
    
    //输出逻辑
    assign done = (state == DONE);
    assign out_bytes = done ? out_bytes_reg : 23'd0;
 
endmodule

4.5.17 Serial receiver(Fsm serial)

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output done
); 
    //状态机三段式
    //参数声明    
    parameter IDLE = 4'd0, START = 4'd1, S1 = 4'd2, S2 = 4'd3, S3 = 4'd4, S4 = 4'd5, S5 = 4'd6, S6 = 4'd7, S7 = 4'd8, S8 = 4'd9, STOP = 4'd10, WAIT = 4'd11;
    reg [3:0]	state;
    reg [3:0]	next_state;
    //状态寄存器(时序) 
    always@(posedge clk)begin
        if(reset)begin
            state <= IDLE;
        end
        else begin
            state <= next_state;
        end
    end
    //次态的组合逻辑    
    always@(*)begin
        case(state)
            IDLE:begin
                next_state = in ? IDLE : START;
            end
            START:begin
                next_state = S1;
            end
            S1:begin
                next_state = S2;
            end
            S2:begin
                next_state = S3;
            end
            S3:begin
                next_state = S4;
            end
            S4:begin
                next_state = S5;
            end
            S5:begin
                next_state = S6;
            end
            S6:begin
                next_state = S7;
            end
            S7:begin
                next_state = S8;
            end
            S8:begin
                next_state = in ? STOP : WAIT;
            end
            STOP:begin
                next_state = in ? IDLE : START;
            end
            WAIT:begin
                next_state = in ? IDLE : WAIT;
            end
            default:begin
                next_state = IDLE;
            end
        endcase
    end
    //输出逻辑    
    assign done = (state == STOP);
 
endmodule

4.5.18 Serial receiver and datapath(Fsm serialdata)

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
     //状态机三段式
    //参数声明   
    parameter IDLE = 3'd0, START = 3'd1, DATA = 3'd2, STOP = 3'd3, WAIT = 3'd4;
    reg [3:0]	state;
    reg [3:0]	next_state;
    reg [3:0]	counter;
    reg [7:0]	par_in;
   
   //状态寄存器(时序) 
    always@(posedge clk)begin
        if(reset)begin
           	state <= IDLE;
        end
        else begin
           state <= next_state;
        end
    end
 
    //次态的组合逻辑   
    always@(*)begin
        case(state)
            IDLE:begin
                next_state = in ? IDLE : START;
            end
            START:begin
                next_state = DATA;
            end
            DATA:begin
                if(counter == 4'd8)begin
                    if(in)begin
                        next_state = STOP;
                    end
                    else begin
                        next_state = WAIT;
                    end
                end
                else begin
                    next_state = DATA;
                end
            end
            STOP:begin
                next_state = in ? IDLE : START;
            end
            WAIT:begin
                next_state = in ? IDLE : WAIT;
            end
            default:begin
                next_state = IDLE;
            end
        endcase
    end
 
    //输出逻辑    
    always@(posedge clk)begin
        if(reset)begin
            done <= 1'b0;
            out_byte <= 8'd0;
            counter <= 4'd0;
        end
        else begin
            case(next_state)
            	IDLE:begin
                	done <= 1'b0;
                	out_byte <= 8'd0;
                	counter <= 4'd0;
            	end
            	START:begin
                	done <= 1'b0;
                	out_byte <= 8'd0;
                	counter <= 4'd0;
            	end
            	DATA:begin
                	counter <= counter + 1'b1;
                	done <= 1'b0;
                	par_in[counter] <= in;
                	out_byte <= 8'd0;
            	end
            	STOP:begin
                	done <= 1'b1;
                	out_byte <= par_in;
            	end
            	WAIT:begin
                	done <= 1'b0;
                	out_byte <= 8'd0;
            	end
            	default:begin
                	done <= 1'b0;
                	out_byte <= 8'd0;
                	counter <= 3'd0;
            	end
            endcase
    	end
    end
 
endmodule

4.5.19 Serial receiver with parity checking(Fsm serialdp)

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //

    //状态机三段式
    //参数声明
    parameter IDLE = 4'd0, START = 4'd1, S1 = 4'd2, S2 = 4'd3, S3 = 4'd4, S4 = 4'd5, S5 = 4'd6, S6 = 4'd7, S7 = 4'd8, S8 = 4'd9, PARITY = 4'd10, STOP = 4'd11, WAIT = 4'd12;
    reg [3:0]	state;
    reg [3:0]	next_state;
    reg [7:0]	par_in;
    wire		odd;
	
    //状态寄存器(时序)
    always@(posedge clk)begin
        if(reset)begin
            state <= IDLE;
        end
        else begin
            state <= next_state;
        end
    end
	
    //次态的组合逻辑    
    always@(*)begin
        case(state)
            IDLE:begin
                next_state = in ? IDLE : START;
            end
            START:begin
                next_state = S1;
                par_in[0] = in;
            end
            S1:begin
                next_state = S2;
                par_in[1] = in;
            end
            S2:begin
                next_state = S3;
                par_in[2] = in;
            end
            S3:begin
                next_state = S4;
                par_in[3] = in;
            end
            S4:begin
                next_state = S5;
                par_in[4] = in;
            end
            S5:begin
                next_state = S6;
                par_in[5] = in;
            end
            S6:begin
                next_state = S7;
                par_in[6] = in;
            end
            S7:begin
                next_state = S8;
                par_in[7] = in;
            end
            S8:begin
                next_state = PARITY;
            end
            PARITY:begin
                next_state = in ? STOP : WAIT;
            end
            STOP:begin
                next_state = in ? IDLE : START;
            end
            WAIT:begin
                next_state = in ? IDLE : WAIT;
            end
            default:begin
                next_state = IDLE;
            end
        endcase
    end
	
    //输出逻辑    
    always@(posedge clk)begin
        if(reset)begin
            done <= 1'b0;
        end
        else if(next_state == STOP && odd == 1'b1)begin
            done <= 1'b1;
        end
        else begin
            done <= 1'b0;
        end
    end   
    
    always@(posedge clk)begin
        if(reset)begin
            out_byte <= 8'd0;
        end
        else if(next_state == STOP && odd == 1'b1)begin
            out_byte <= par_in;
        end
        else begin
            out_byte <= 8'd0;
        end
    end   
     
endmodule

4.5.20 Sequence recognition(Fsm hdlc)

module top_module(
    input clk,
    input reset,    // Synchronous reset
    input in,
    output disc,
    output flag,
    output err);
    
	//状态机三段式
    //参数声明  
    parameter S1 = 4'd1, S2 = 4'd2, S3 = 4'd3, S4 = 4'd4, S5 = 4'd5,S6 = 4'd6, S7 = 4'd7, DISC = 4'd8, ERR = 4'd9, FLAG = 4'd10;
    
    reg	[3:0]	state;
    reg [3:0]	next_state;
    
	//状态寄存器(时序) 
    always@(posedge clk)begin
        if(reset == 1'b1)begin
            state <= S1;
        end
        else begin
            state <= next_state;
        end
    end
	
    //次态的组合逻辑    
    always@(*)begin
        case(state)
            S1:begin
                next_state = in ? S2 : S1;
            end
            S2:begin
                next_state = in ? S3 : S1;
            end
            S3:begin
                next_state = in ? S4 : S1;
            end
            S4:begin
                next_state = in ? S5 : S1;
            end
            S5:begin
                next_state = in ? S6 : S1;
            end
            S6:begin
                next_state = in ? S7 : DISC;
            end
            S7:begin
                next_state = in ? ERR : FLAG;
            end
            DISC:begin
                next_state = in ? S2 : S1;
            end
            ERR:begin
                next_state = in ? ERR : S1;
            end
            FLAG:begin
                next_state = in ? S2 : S1;
            end
            default:begin
                next_state = S1;
            end
        endcase
    end
	
    //输出逻辑  
    assign disc = (state == DISC);
    assign err = (state == ERR);
    assign flag = (state == FLAG);
 
endmodule

4.5.21 Q8:Design a Mealy FSM(Exams/ece241 2013 q8)

module top_module (
    input clk,
    input aresetn,    // Asynchronous active-low reset
    input x,
    output z ); 

    //状态机三段式
    //参数声明    
    parameter S0 = 2'd0, S1 = 2'd1, S2 = 2'd2;
    reg [1:0]	state;
    reg [1:0]	next_state;
	
   //状态寄存器(时序)    
    always@(posedge clk or negedge aresetn)begin
        if(aresetn == 1'b0)begin
            state <= S0;
        end
        else begin
            state <= next_state;
        end
    end
	
    //次态的组合逻辑    
    always@(*)begin
        case(state)
            S0:begin
                next_state = x ? S1 : S0;
            end
            S1:begin
                next_state = x ? S1 : S2;
            end
            S2:begin
                next_state = x ? S1 : S0;
            end
            default:begin
                next_state = S0;
            end
        endcase
    end

    //输出逻辑    
    always@(*)begin
        case(state)
            S0:begin
                z = 1'b0;
            end
            S1:begin
                z = 1'b0;
            end
            S2:begin
                z = x;
            end
        endcase
    end
 
endmodule

4.5.22 Q5a:Serial two’s complementer(Moore FSM)(Exams/ece241 2014 q5a)

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 

    //状态机三段式
    //参数声明    
    parameter A = 2'd0, B = 2'd1, C = 2'd2;
    reg	[1:0]	state;
    reg	[1:0]	next_state;
 
   //状态寄存器(时序)  
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            state <= A;
        end
        else begin
            state <= next_state;
        end
    end
 
    //次态的组合逻辑 
    always@(*)begin
        case(state)
            A:begin
                next_state = x ? B : A;
            end
            B:begin
                next_state = x ? C : B;
            end
            C:begin
                next_state = x ? C : B;
            end
            default:begin
                next_state = A;
            end
        endcase
    end
    //输出逻辑   
    assign z = state == B;
 
endmodule

4.5.23 Q5b:Serial two’s complementer(Mealy FSM)(Exams/ece241 2014 q5b)

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 

    //状态机三段式
    //参数声明
    parameter A = 1'b0, B = 1'b1;
    reg	state;
    reg	next_state;
	
   //状态寄存器(时序)     
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            state <= A;
        end
        else begin
            state <= next_state;
        end
    end
	
    //次态的组合逻辑    
    always@(*)begin
        case(state)
            A:begin
                next_state = x ? B : A;
            end
            B:begin
                next_state = B;
            end
        endcase
    end
	
    //输出逻辑    
    assign z = (state == A && x == 1'b1 || state == B && x == 1'b0);
    
endmodule

4.5.24 Q3a: FSM(Exams/2014 q3fsm)

module top_module (
    input clk,
    input reset,   // Synchronous reset
    input s,
    input w,
    output z
);
    
    parameter A = 1'b0, B = 1'b1;
    reg	        state;
    reg	        next_state;
    
    always@(posedge clk)begin
        if(reset)begin
            state <= A;
        end
        else begin
            state <= next_state;
        end
    end
    
    always@(*)begin
        case(state)
            A:begin
                next_state = s ? B : A;
            end
            B:begin
                next_state = B;
            end
        endcase
    end
 
    reg	w_reg1;
    reg w_reg2;
    always@(posedge clk)begin
        if(reset)begin
            w_reg1 <= 1'b0;
            w_reg2 <= 1'b0;
        end
        else if(next_state == B)begin
            w_reg1 <= w;
            w_reg2 <= w_reg1;
        end
        else begin
            w_reg1 <= 1'b0;
            w_reg2 <= 1'b0;
        end
    end  
    
    always@(posedge clk)begin
        if(reset)begin
            z <= 1'b0;
        end
        else if(state == B && counter == 2'd0)begin
            if(~w & w_reg1 & w_reg2 | w & ~w_reg1 & w_reg2 | w & w_reg1 & ~w_reg2)begin
                z <= 1'b1;
            end
            else begin
                z <= 1'b0;
            end
        end
        else begin
            z <= 1'b0;
        end
    end   
    
    reg [1:0]	counter;
    always@(posedge clk)begin
        if(reset)begin
            counter <= 2'd0;
        end
        else if(counter == 2'd2)begin
            counter <= 2'd0;
        end
        else if(next_state == B)begin
            counter <= counter + 1'b1;
        end
    end
    
endmodule

4.5.25 Q3b: FSM(Exams/2014 q3bfsm)

module top_module (
    input clk,
    input reset,   // Synchronous reset
    input x,
    output z
);
 
    //状态机三段式
    //参数声明 
    parameter S0 = 3'd0, S1 = 3'd1, S2 = 3'd2;
    parameter S3 = 3'd3, S4 = 3'd4;
    
    reg	[2:0]	state;
    reg [2:0]	next_state;
   //状态寄存器(时序)     
    always@(posedge clk)begin
        if(reset)begin
            state <= S0;
        end
        else begin
            state <= next_state;
        end
    end
    //次态的组合逻辑    
    always@(*)begin
        case(state)
            S0:begin
                next_state = x ? S1 : S0;
            end
            S1:begin
                next_state = x ? S4 : S1;
            end
            S2:begin
                next_state = x ? S1 : S2;
            end
            S3:begin
                next_state = x ? S2 : S1;
            end
            S4:begin
                next_state = x ? S4 : S3;
            end
            default:begin
                next_state = S0;
            end
        endcase
    end
	
    //输出逻辑 
    assign z = (state == S3 || state == S4);           
            
endmodule

4.5.26 Q3c: FSM logic(Exams/2014 q3c)

module top_module (
    input clk,
    input [2:0] y,
    input x,
    output Y0,
    output z
);

    //输出逻辑    
    assign Y0 = (x & y == 3'b000 || ~x & y == 3'b001 || x & y == 3'b010 || ~x & y == 3'b011 || ~x & y == 3'b100);
    assign z = (y == 3'b011 || y == 3'b100); 
	
endmodule

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...