HDLbits(3)

60、mux2to1

 assign out = sel ? b : a ;

61、mux2to1v

assign out = sel ? b : a;

62、mux9to1v

    always @(*)
        begin
            case(sel)
                0: out = a ;
                1: out = b ;
                2: out = c ;
                3: out = d ;
                4: out = e ;
                5: out = f ;
                6: out = g ;
                7: out = h ;
                8: out = i ;
                default:out = 16'hffff;
            endcase
        end

63、mux256to1

assign out = in[sel] ;

使用输入sel作为in的指针。也可以assign out = in >> sel 。将in向右移sel位,赋值给out。因为out只有一位,所以in的高位会被截去,将sel位赋给out。

64、mux256to1v

 assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};

错误写法:assign out = in[selx4+3:selx4]; 这个语句不符合verilog语法规则

其他写法:

assign out = in[sel*4 +: 4];// 从 sel*4 开始,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4]
assign out = in[sel*4+3 -: 4];	// 从 sel*4+3 开始,选择比特序号小于 sel*4+3 的 4 位比特,相当于[sel*4+3:sel*4]

65、hadd

 assign {cout,sum} = a + b;

66、full adder

assign {cout,sum} = a+b+cin ;

67、3bit binary adder

    assign {cout[0],sum[0]} = a[0] + b[0] + cin ;
    assign {cout[1],sum[1]} = a[1] + b[1] + cout[0] ;
    assign {cout[2],sum[2]} = a[2] + b[2] + cout[1] ;

68、adder

    assign {cout[0],sum[0]} = x[0] + y[0] ;
    assign {cout[1],sum[1]} = x[1] + y[1] + cout[0];
    assign {cout[2],sum[2]} = x[2] + y[2] + cout[1];
    assign {sum[4],sum[3]} = x[3] + y[3] + cout[2];

69、signed addition overflow

    assign s = a + b ;
    assign overflow = ( a[7] && b[7] && ~s[7] ) || (~a[7] && ~b[7] && s[7]);

有符号数运算的溢出有两种情况。主要是正+正=负和负+负=正。对于这两种情况只需要考虑符号位的变化,即可判断是否发生了溢出。

还有一种办法是从n和n-1位的关系导出。即第n位为符号位,n-1位为数值最高位,这两位进行异或即可得到是否溢出。这个办法在微机原理中讲8086提到比较多。

70、adder100

wire [99:0] cout_in ;
assign {cout_in[0],sum[0]} = a[0] + b[0] + cin ;
generate
    genvar i;
    for(i=1;i<=99;i=i+1)
        begin:add
            assign {cout_in[i],sum[i]} = a[i] + b[i] + cout_in[i-1];
        end
endgenerate
assign cout = cout_in[99];

71、bcdadd4

    wire [3:0] cout_in ;
    bcd_fadd add_0(a[3:0],b[3:0],cin,cout_in[0],sum[3:0]);
    generate
        genvar i ;
        for(i=1;i<4;i=i+1)
            begin:bcdadd
                bcd_fadd add_i(a[4*i+3:4*i],b[4*i+3:4*i],cout_in[i-1],cout_in[i],sum[4*i+3:4*i]);
            end
    endgenerate
    assign cout = cout_in[3];

72、3-variables

assign out = (a==0&&b==0&&c==0)?1'b0 : 1'b1 ;

73、4-variables

 assign out = ~b&~c | ~a&~d | b&c&d | a&~b&d ;

74、4-variables

assign out = a | ~b&c ;

卡诺图中d相当于x,可以看作1也可以看作0;

75、4-variables

无法化简

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);

76、minimum SOP和POS

	assign out_sop = c&d | ~a&~b&c ;
    assign out_pos = !(~c | b&c&~d | a&~b&c) ;

sop是圈1,pos是圈0得到积之和再取反

77、karnaugh map

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

78、karnaugh map

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

79、k-map implemented with a multiplexer

assign mux_in = {c&d,~d,1'b0,c|d};

将mux分为四路,化简每路确定每路的输出

80、D flip-flip

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

81、D flip-flips

    reg [7:0] q_out;
    always @(posedge clk)
        begin
            q_out <= d;
        end
    assign q = q_out;

82、DFF with reset

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

synchonous同步

83、DFF with reset value

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

84、DFF with asynchronous reset

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

85、DFF with byte enable

    always @(posedge clk)
        begin
            if(!resetn)
                q <= 16'h0;
            else
                begin
                    case(byteena)
                        2'b00: begin q <=q;end
                        2'b01: begin q[15:8]<=q[15:8];q[7:0]<=d[7:0];end
                        2'b10: begin q[15:8]<=d[15:8];q[7:0]<=q[7:0];end
                        2'b11: begin q<=d;end
                        default:q<=16'h0;
                    endcase
                end
        end

使能关闭时,对应寄存器值保持不变,而不是输出0;

86、D latch

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

85、DFF

    always @(posedge clk or posedge ar)
        begin
            if(ar)
                q <= 0;
            else
                q<= d ;
        end

86、DFF

    always @(posedge clk)
        begin
            if(r)
                q <= 0;
            else
                q<= d;
        end

87、DFF + gate

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

88、Mux and DFF

    wire D;
    assign D = L ? r_in : q_in ;
    always @(posedge clk)
        begin
            Q <= D;
        end

89、Mux and DFF

    wire D;
    always @(*)
        begin
            case({E,L})
                2'b00:D = Q;
                2'b10:D = w;
                2'b01,2'b11:D = R;
                default:D=0;
             endcase
        end
    always @(posedge clk)
        begin
            Q <= D;
        end
    

90、DFF and gates

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

91、caret circuit from truth tabale

    always @(posedge clk)
        begin
            case({j,k})
                2'b00: Q <= Q; 
                2'b01: Q <= 1'b0; 
                2'b10: Q <= 1'b1;
                3'b11: Q <= ~Q ;
            endcase
        end

92、detect an edge

    reg[7:0] in_1,in_2;
    always @(posedge clk)
        begin
            in_1 <= in;
            in_2 <= in_1;
        end
    
    assign pedge = ~in_2 & in_1 ;

打两拍再进行组合逻辑运算,或者直接在第二拍进行逻辑运算。

    reg[7:0] in_1,in_2;
    always @(posedge clk)
        begin
            in_1 <= in;
            pedge <= ~in_1 & in;
        end
    

将输入打一拍进行错位,此时若in为1,in_1为0则为上升沿,in为0,in_1为1则为下降沿。

93、detect both edges

    reg[7:0] in_1;
    always @(posedge clk)
        begin
            in_1 <= in;
            anyedge <= in_1 ^ in ;
        end

94、edge capture register

这道题捕获输入下降沿,捕获到下降沿就使对应out为1并保持,除非复位。

    reg [31:0] in_1;
    wire [31:0] capture;
	
    always @(posedge clk)
        begin
            in_1 <= in;
        end
    assign capture = ~in & in_1;//检测下降沿信号
    
    always @(posedge clk)
        begin
            if(reset)
                out <= 32'h0;
            else
                begin
                    for(int i=0;i<32;i=i+1)
                        begin
                            if(capture[i]==1'b1)
                                out[i] <= 1'b1;
                        end
                end
        end

95、dual-edge triggered flip-flop

本题要求实现同时在时钟上升沿和下降沿进行采样。所以采用两个寄存器分别对时钟上升沿和下降沿进行采样,然后将q看作一根导线,在时钟为高电平时将输出连到上升沿采样寄存器,在时钟为低电平时将输出连接到下降沿采样寄存器

	reg q1,q2;
    assign q = clk ? q1:q2;
    always @(posedge clk)
        begin
        	q1 <= d;
        end
    always @(negedge clk)
        begin
            q2 <= d;
        end
    

96、Four-bit binary counter

    reg[3:0] counter;
    
    always @(posedge clk)
        begin
            if(reset)
                counter <= 4'b0;
            else if(counter == 4'hf)
                counter	<= 4'b0;
            else
                counter	<=	counter + 1;
                
        end
    
    assign q = counter ;

97、Decade counter

    reg[3:0] counter;
    
    always @(posedge clk)
        begin
            if(reset)
                counter <= 4'b0;
            else if(counter == 4'd9)
                counter	<= 4'b0;
            else
                counter	<=	counter + 1;
                
        end
    
    assign q = counter ;

98、Decade counter again

    reg[3:0] counter;
    
    always @(posedge clk)
        begin
            if(reset)
                counter <= 4'd1;
            else if(counter == 4'd10)
                counter	<= 4'd1;
            else
                counter	<=	counter + 1;
                
        end
    
    assign q = counter ;

99、slow decade counter

    reg [3:0] counter;
    
    always @(posedge clk)
        begin
            if(reset)
                counter <= 4'd0;
            else
                begin
                    if(!slowena)
                        counter <= counter;
                    else if(counter == 4'd9)
                        counter <= 4'd0;
                    else
                        counter <= counter + 1;
                end                                        
        end
    assign q = counter ;

100、counter 1-12

	assign c_enable = enable ;
    assign c_load = reset | (Q == 4'd12 & enable == 1);
    assign c_d = 4'd1;
    count4 the_counter (clk, c_enable, c_load, c_d ,Q );

本题主要是对给定的计数器再包一层,加入一些控制信号使其成为1-12计数器。思想是在检测到其需要复位或者计数到12时,使载入信号有效,这时载入1。

101、counter100

    wire[3:0] Q0,Q1,Q2;
    assign c_enable[0] = 1'b1;
    assign c_enable[1] = (Q0==4'd9) ? 1'b1 : 1'b0;
    assign c_enable[2] = ((Q1==4'd9) &&(Q0 == 4'd9) ) ? 1'b1 : 1'b0;
    always @(*)
        begin
            if(reset)
                OneHertz = 1'b0;
            else if(Q2 == 4'd9 && Q1 == 4'd9 && Q0 == 4'd9)
                OneHertz = 1'b1;
            else
                OneHertz = 1'b0;
        end
    
    bcdcount counter0 (clk, reset, c_enable[0],Q0/*, ... */);
    bcdcount counter1 (clk, reset, c_enable[1],Q1/*, ... */);
    bcdcount counter2 (clk, reset, c_enable[2],Q2/*, ... */);

注意要在前两级计数器计到99才开启第三级计数器,条件判断是(Q1==4'd9) &&(Q0 == 4'd9),如果只有Q1 == 4‘d9,那么判断的是计到90。

102、4-digit decimal counter

  reg [3:0]count0,count1,count2,count3;
    
    always @(posedge clk)
        begin
            if(reset)
                count0 <= 0;
            else if(count0 == 4'd9)
                count0 <= 4'd0;
            else
                count0 <= count0 + 1;
        end
   always @(posedge clk)
        begin
            if(reset)
                count1<= 0;
            else if(count1== 4'd9 && count0 == 4'd9)
                count1<= 4'd0;
            else if(count0 == 4'd9)
                count1<= count1+ 1;
        end
   always @(posedge clk)
        begin
            if(reset)
                count2<= 0;
            else if(count2== 4'd9 && count1== 4'd9 && count0 == 4'd9)
                count2<= 4'd0;
            else if(count0 == 4'd9 && count1 == 4'd9)
                count2<= count2+ 1;
        end
    always @(posedge clk)
        begin
            if(reset)
                count3<= 0;
            else if(count3 == 4'd9 && count2== 4'd9 && count1== 4'd9 && count0 == 4'd9)
                count3<= 4'd0;
            else if(count2 == 4'd9 && count0 == 4'd9 && count1 == 4'd9)
                count3<= count3+ 1;
        end
      
    assign ena[1] = (count0 == 4'd9) ? 1'b1:1'b0;
    assign ena[2]= (count0 == 4'd9 && count1 == 4'd9) ? 1'b1:1'b0;
    assign ena[3]= (count0 == 4'd9 && count1 == 4'd9 && count2 == 4'd9) ? 1'b1:1'b0;          
    
    assign q[15:0] = {count3,count2,count1,count0};

103、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); 
	
    reg [7:0] h;
    reg p;
    reg [7:0] s;
    reg [7:0] m;
    wire ena_m;
    wire ena_h;
    assign ena_m = ena && (s == 8'h59);
    assign ena_h = ena && (s == 8'h59) && (m == 8'h59);
    count60 count_s(clk,reset,ena,s);
    count60 count_m(clk,reset,ena_m,m);
    always @(posedge clk)
        begin
            if(reset)
                p <= 1'b0;
            else if(h == 8'h11&& s == 8'h59 && m == 8'h59)
                p <= ~p;
            else
                p <= p;
        end
    always @(posedge clk)
        begin
        	if(reset)
            	h <= 8'h12;
    		else if(!ena_h)
        		h <= h;
            else if(h == 8'h12 && s == 8'h59 && m == 8'h59)
                h <= 8'h1;
            else if(s == 8'h59 && m == 8'h59)
                begin
                	h[3:0] <= h[3:0] + 4'h1;
                    if(h[3:0]==4'h9)
                        begin
                        	h[7:4] <= h[7:4] + 4'h1;
                            h[3:0] <= 4'h0;
                        end
                end
    	end
          
    assign pm = p;
    assign hh = h;
    assign mm = m;
    assign ss = s;
    
    
endmodule

module count60(input clk,input reset,input ena,output reg [7:0]count);
    always @(posedge clk)
        begin
            if(reset)
                count <= 8'h0;
			else if(~ena)
                 count <= count;
            else if(count == 8'h59)
                 count <= 8'h0;
            else
                 begin
                     count[3:0] <= count[3:0] + 4'h1;
                     if(count[3:0] == 4'h9 )
                         begin
                         	count[7:4] <= count[7:4] + 4'h1;
                             count[3:0] <= 4'h0;
                         end
                 end
            
        end
endmodule

注意题目,使用BCD码表示。

104、4-bit shift register

    always @(posedge clk or posedge areset)
        begin
            if(areset)
                q <= 4'h0;
            else
                begin
                    if(load)
                        q <= data;
                    else if(ena)
                        q <= {1'b0,q[3],q[2],q[1]};
                    else
                        q <= q;
                end
        end

105、left/right rotator

    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:q <= q;
                    endcase
                end
        end

106、left/right arithmetic shift by 1 or 8

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

107、5-bit LFSR

    always @(posedge clk )
        begin
            if(reset)
                q <= 5'h1;
            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

108、3-bit LFSR

    reg[2:0] Q;
    wire[2:0]R;
    wire[2:0]D;
    wire L;
  	wire clk;
	assign D[0] = L ? R[0] : Q[2];
	assign D[1] = L ? R[1] : Q[0];
	assign D[2] = L ? R[2] : (Q[1]^Q[2]);
	
always @(posedge clk)
	begin
		Q[0] <= D[0];
		Q[1] <= D[1];
		Q[2] <= D[2];
	end
	
	assign R = SW;
    assign {L,clk} = KEY;
    assign LEDR = Q;
    

109、32-bit LFSR

    always @(posedge clk)
        begin
            if(reset)
                q <= 32'h1;
            else
                q <= {q[0],q[31:23],q[22]^q[0],q[21:3],q[2]^q[0],q[1]^q[0]};
        end

110、shift register

    reg [3:0] q;
    
    always @(posedge clk)
        begin
            if(!resetn)
                q <= 4'h0;
            else
                begin
                    q[0] <= in;
                    q[1] <= q[0];
                    q[2] <= q[1];
                    q[3] <= q[2];
                end
        end
    assign out = q[3] ;

111、shift register

	wire [3:0] w_input = {KEY[3],LEDR[3],LEDR[2],LEDR[1]};
    generate 
        genvar i;
        for(i=0;i<4;i=i+1) begin:muxdff
            MUXDFF (
        		.clk(KEY[0]),
                .w(w_input[i]),
                .R(SW[i]),
        		.E(KEY[1]),
        		.L(KEY[2]),
                .Q(LEDR[i])
    		);
        end
    endgenerate

endmodule

module MUXDFF (input clk,input w,R,E,L,output reg Q);
    
    always @(posedge clk)
        begin
            case({E,L})
                2'b00 : Q <= Q;
                2'b01: Q <= R;
                2'b10 : Q <= w;
                2'b11: Q <= R;
            endcase
        end
    
                
    

endmodule

112、3-input LUT

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

需要注意输入S填充到Q[0],然后向右移位。

113、Rule 90

    always @(posedge clk)
        begin
            if(load)
                q <= data;
            else
                q <= {1'b0,q[511:1]} ^ {q[510:0],1'b0};
        end

q的每一位下一状态是当前状态的两个相邻元素异或得到;

114、rule 110

    always @(posedge clk)
        begin
            if(load)
                q <= data;
            else
                q <= (q ^ {q[510:0],1'b0}) | ((~{1'b0,q[511:1]})&q);
        end

把真值表进行卡诺图化简得到表达式,注意B非C+BC非是BC的异或

115、conwaylife

    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

116、simple FSM 1

状态机最好采用三段式写法:状态跳转逻辑、状态触发器实现、输出逻辑确定

    parameter A=0, B=1; 
    reg state, next_state;

    always @(*) begin    // This is a combinational always block
        // State transition logic
        case (state)
            A : next_state = in ? A : B;
            B : next_state = in ? B : A;
        endcase
            
    end

    always @(posedge clk, posedge areset) begin    // This is a sequential always block
        // State flip-flops with asynchronous reset
        if(areset)
            state <= B;
        else
            state <= next_state;
        
    end

    // Output logic
    // assign out = (state == ...);
    assign out = (state == B);

107、simple FSM 1

    parameter A=0, B=1; 
    reg state, next_state;

    always @(*) begin    // This is a combinational always block
        // State transition logic
        case (state)
            A : next_state = in ? A : B;
            B : next_state = in ? B : A;
        endcase
            
    end

    always @(posedge clk) begin    // This is a sequential always block
        // State flip-flops with asynchronous reset
        if(reset)
            state <= B;
        else
            state <= next_state;
        
    end

    // Output logic
    // assign out = (state == ...);
    assign out = (state == B);

108、simple FSM 2

    parameter OFF=0, ON=1; 
    reg state, next_state;

    always @(*) begin
        case(state)
            ON : next_state = k ? OFF : ON;
            OFF: next_state = j ? ON : OFF;
        endcase
        
    end

    always @(posedge clk, posedge areset) begin
        // State flip-flops with asynchronous reset
        if(areset)
            state <= OFF;
        else
            state <= next_state;
    end

    // Output logic
    // assign out = (state == ...);
    assign out = (state == ON) ;

109、simple FSM 2

    parameter OFF=0, ON=1; 
    reg state, next_state;

    always @(*) begin
        case(state)
            ON : next_state = k ? OFF : ON;
            OFF: next_state = j ? ON : OFF;
        endcase
        
    end

    always @(posedge clk) begin
        // State flip-flops with asynchronous reset
        if(reset)
            state <= OFF;
        else
            state <= next_state;
    end

    // Output logic
    // assign out = (state == ...);
    assign out = (state == ON) ;

110、simple state transition 3

    always @(*)
        begin
            case(state)
               A :  next_state = in ? B : A;
               B :  next_state = in ? B : C;
               C :  next_state = in ? D : A;
               D :  next_state = in ? B : C;
            endcase
        end
    assign out = (state == D) ;

111、simple one-hot state transition

    // 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[D]&in) | (state[B]&in);
    assign next_state[C] = (state[B]&~in) | (state[D]&~in);
    assign next_state[D] = (state[C]&in);

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

根据真值表,得到每一位置1的条件

112、simple FSM 3

异步复位

    parameter A = 0, B = 1 , C = 2 , D = 3;
    reg [1:0] state,next_state;
	
    always @(*)
        begin
            case(state)
                A : next_state = in ? B : A ;
                B : next_state = in ? B : C ;
                C : next_state = in ? D : A ;
                D : next_state = in ? B : C ;
            endcase
        end
    always @(posedge clk or posedge areset)
        begin
            if(areset)
                state <= A ;
            else
                state <= next_state;
        end
    
    assign out = (state == D);

113、simple FSM 3

同步复位

parameter A = 0, B = 1 , C = 2 , D = 3;
reg [1:0] state,next_state;

always @(*)
    begin
        case(state)
            A : next_state = in ? B : A ;
            B : next_state = in ? B : C ;
            C : next_state = in ? D : A ;
            D : next_state = in ? B : C ;
        endcase
    end
always @(posedge clk )
    begin
        if(reset)
            state <= A ;
        else
            state <= next_state;
    end

assign out = (state == D);

114、design a moore fsm

    reg [3:1] state ,next_state;
    reg flag,next_flag;
    wire [3:1] fr;
   
    assign {fr3,fr2,fr1} = fr;
    assign next_state = s;
    
    always @(*)
        begin
            case(state)
                3'b111: fr = 3'b0;
                3'b011: fr = 3'b001;
                3'b001: fr = 3'b011;
                3'b000: fr = 3'b111;
                default: fr = 3'b000;
            endcase
        end
    always @(*)
        begin
            if(s == state)
                next_flag = flag;
            else if(s < state || s == 0)
                next_flag  = 1'b1 ;
            else
                next_flag = 1'b0;
        end
    always @(posedge clk )
        begin
            if(reset) begin
                state <= 0;
                flag <= 1'b1;
            end
            else begin
                state <= next_state;
                flag <= next_flag;
            end
        end
    assign dfr = (flag == 1'b1);

115、Lemmings1

 	parameter LEFT = 1 , RIGHT = 0;
    reg state,next_state;
    
    always @(*)
        begin
            case (state)
                RIGHT : next_state = bump_right ? LEFT : RIGHT;
                LEFT  : next_state = bump_left  ? RIGHT : LEFT;
            endcase
        end
    always @(posedge clk or posedge areset)
        begin
            if(areset)
            	state <= LEFT;
            else
                state <= next_state;
        end
    
    assign walk_left = (state == LEFT) ;
    assign walk_right = (state == RIGHT) ;

116、Lemmings 2

 parameter LEFT = 1 , RIGHT = 0 , FALL = 2;
    reg [1:0] state,next_state;
    reg walk;
    
    always @(*)
        begin
            if(ground == 1'b1)
            	case (state)
               	 	RIGHT : next_state = bump_right ? LEFT : RIGHT;
                	LEFT  : next_state = bump_left  ? RIGHT : LEFT;
                    FALL  : next_state = walk ;
            	endcase
            else
                next_state = FALL ;
        end
    always @(posedge clk or posedge areset)
        begin
            if(areset)
            	state <= LEFT;
            else
                state <= next_state;
        end
                    
   always @(posedge clk)
         begin
             case(state)
                 RIGHT : walk <= 1'b0;
                 LEFT  : walk <= 1'b1;
                 default: walk <= walk;
             endcase
         end
                    
                            
    assign walk_left = (state == LEFT) ;
    assign walk_right = (state == RIGHT) ;
    assign aaah = (state == FALL) ;

117、Lemmings 3

    localparam left = 0;
    localparam right = 1;
    localparam left_dig = 2;
    localparam right_dig = 3;
    localparam left_fall = 4;
    localparam right_fall = 5;
    
    reg[2:0] state, next_state;
    reg[3:0] out;
    
    //state
    always@(posedge clk or posedge areset) begin
        if(areset)
            state <= left;
        else
            state <= next_state;
    end
    
    //transition
    always@(*) begin
        case(state)
            left:next_state=ground?(dig?left_dig:(bump_left?right:left)):left_fall;
            right:next_state=ground?(dig?right_dig:(bump_right?left:right)):right_fall;
            left_dig:next_state=ground?left_dig:left_fall;
            right_dig:next_state=ground?right_dig:right_fall;
            left_fall:next_state=ground?left:left_fall;
            right_fall:next_state=ground?right:right_fall;
        endcase
    end
    
    //out
    always@(posedge clk or posedge areset) begin
        if(areset)
            out <= 4'b1000;
        else
            case(next_state)
                left: out <= 4'b1000;
                left_dig: out <= 4'b0001;
                left_fall: out <= 4'b0010;
                right: out <= 4'b0100;
                right_dig: out <= 4'b0001;
                right_fall: out <= 4'b0010;
            endcase
    end
    
    assign {walk_left, walk_right, aaah, digging} = out;

image-20211111152802228

根据状态转移图按照三段式写法,条理更清楚

118、Lemmings 4

image-20211111153508327

 localparam left = 0;
    localparam right = 1;
    localparam left_dig = 2;
    localparam right_dig = 3;
    localparam left_fall = 4;
    localparam right_fall = 5;
    localparam over = 6;
    
    reg[2:0] state, next_state;
    reg[3:0] out;
    reg[7:0] cnt;
    
    always@(posedge clk or posedge areset) begin
        if(areset)
            state <= left;
        else
            state <= next_state;
    end
    
    always@(*) begin
        case(state)
            left:next_state=ground?(dig?left_dig:(bump_left?right:left)):left_fall;
            right:next_state=ground?(dig?right_dig:(bump_right?left:right)):right_fall;
            left_dig:next_state=ground?left_dig:left_fall;
            right_dig:next_state=ground?right_dig:right_fall;
            left_fall:next_state=ground?((cnt>=5'd21)?over:left):left_fall;
            right_fall:next_state=ground?((cnt>=5'd21)?over:right):right_fall;
            over:next_state=over;
        endcase
    end
    
    always@(posedge clk or posedge areset) begin
        if(areset) begin
            out <= 4'b1000;
        end
        else
            case(next_state)
                left:begin
                    out <= 4'b1000;
                    cnt <= 0;
                end
                right:begin
                    out <= 4'b0100;
                    cnt <= 0;
                end
                left_dig:begin
                    out <= 4'b0001;
                    cnt <= 0;
                end
                right_dig:begin
                    out <= 4'b0001;
                    cnt <= 0;
                end
                left_fall:begin
                    out <= 4'b0010;
                    cnt = cnt + 1;
                end
                right_fall:begin
                    out <= 4'b0010;
                    cnt = cnt + 1;
                end
                over:out <= 4'b0000;
            endcase
    end
    
    assign {walk_left, walk_right, aaah, digging} = out;

119、ONT-HOT fsm


    parameter S0 = 4'd0, S1 = 4'd1, S2 = 4'd2, S3 = 4'd3, S4 = 4'd4;
    parameter 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];

对照着转移图直接写

image-20211111155757169

120、PS/2 packet parser

image-20211111161630658

	parameter S1=0,S2=1,S3=2,S4=3;
    reg [2:0] state,next_state;
    
    always @(posedge clk)
        begin
            if(reset)
                state <= S1;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case(state)
                S1 : next_state = in[3] ? S2 : S1;
                S2 : next_state = S3;
                S3 : next_state = S4;
                S4 : next_state = in[3] ? S2 : S1;
            endcase
        end
    assign done = (state == S4) ;

121、PS/2 packet parser and datapath

 parameter S1=0,S2=1,S3=2,S4=3;
    reg [2:0] state,next_state;
    reg [23:0] out;
    
    always @(posedge clk)
        begin
            if(reset)
                state <= S1;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case(state)
                S1 :begin
                    	next_state = in[3] ? S2 : S1;
                	end
                S2 :begin 
                    	next_state = S3;
                end
                S3 : begin
                    next_state = S4;
                end
                S4 :begin 
                    next_state = in[3] ? S2 : S1;
                end
            endcase
        end
    always @(posedge clk)
        begin
            case (state)
                S1 : out[23:16] <= (next_state == S2) ? in : 8'h0;
                S2 : out[15:8] <= in;
                S3 : out[7:0] <= in;
                S4 : out[23:16] <= (next_state == S2) ? in : 8'h0;
            endcase
        end
    
    assign done = (state == S4) ;
	assign out_bytes = done ? out : 8'h0; 

122、serial receiver

 parameter START=0,BIT1=1,BIT2=2,BIT3=3,BIT4=4,BIT5=5,BIT6=6,BIT7=7,BIT8=8,STOP=9,WAIT=10,IDLE=11;
    reg[3:0]state,next_state;
    
    always @(posedge clk)
        begin
            if(reset)
                state <= IDLE;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case(state)
                IDLE : next_state = in ? IDLE : START;
                START : next_state = BIT1;
                BIT1 : next_state = BIT2;
                BIT2 : next_state = BIT3;
                BIT3 : next_state = BIT4;
                BIT4 : next_state = BIT5;
                BIT5 : next_state = BIT6;
                BIT6 : next_state = BIT7;
                BIT7 : next_state = BIT8;
                BIT8 : next_state = in ? STOP : WAIT;
                WAIT: next_state = in ? IDLE : WAIT;
                STOP : next_state = in ? IDLE : START;
               default:next_state <= IDLE;
            endcase
        end
    assign done = (state == STOP);    

123、serial receiver and datapath

 	 parameter START=0,BIT1=1,BIT2=2,BIT3=3,BIT4=4,BIT5=5,BIT6=6,BIT7=7,BIT8=8,STOP=9,WAIT=10,IDLE=11;
    reg[3:0]state,next_state;
    reg[7:0] out;
    always @(posedge clk)
        begin
            if(reset)
                state <= IDLE;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case(state)
                IDLE : next_state = in ? IDLE : START;
                START : next_state = BIT1;
                BIT1 : next_state = BIT2;
                BIT2 : next_state = BIT3;
                BIT3 : next_state = BIT4;
                BIT4 : next_state = BIT5;
                BIT5 : next_state = BIT6;
                BIT6 : next_state = BIT7;
                BIT7 : next_state = BIT8;
                BIT8 : next_state = in ? STOP : WAIT;
                WAIT: next_state = in ? IDLE : WAIT;
                STOP : next_state = in ? IDLE : START;
               default:next_state <= IDLE;
            endcase
        end
    
    always @(posedge clk)
        begin
            case(state)
                START:out[0] <= in;
                BIT1: out[1] <= in;
                BIT2: out[2] <= in;
                BIT3: out[3] <= in;
                BIT4: out[4] <= in;
                BIT5: out[5] <= in;
                BIT6: out[6] <= in;
                BIT7: out[7] <= in;
                //BIT8: out[7] <= in;
                default:out <= out;
            endcase
        end
                
                
    assign done = (state == STOP);    
    assign out_byte = done ? out : 8'b0;

注意对应好状态于当前输入的关系

124、serial receiver with parity checking

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

    parameter IDLE  = 3'd0; 
    parameter DATA  = 3'd1; 
    parameter CHECK = 3'd2; 
    parameter STOP  = 3'd3; 
    parameter ERROR = 3'd4;
    
    reg [2 : 0] curr_state; 
    reg [2 : 0] next_state;
    reg [3 : 0] cnt;
    reg [7 : 0] out;
    reg check;
    
    wire odd; 
    wire start;  
    
    //transition
    always@(*)
    begin
        start = 0;
        case(curr_state)
            IDLE : begin 
                next_state = in ? IDLE : DATA; 
                start=1; 
            end
            DATA : begin
                next_state = (cnt == 8) ? CHECK : DATA;
            end
            CHECK: begin 
                next_state = in ? STOP : ERROR;
            end
            STOP : begin 
                next_state = in ? IDLE : DATA; 
                start = 1; 
            end
            ERROR: begin
                next_state = in ? IDLE : ERROR;
            end
        endcase
    end
    
    //state
    always@(posedge clk)
    begin
        if(reset)
            curr_state <= IDLE;
        else
            curr_state <= next_state;
    end
    
    //cnt
    always@(posedge clk)
    begin
        if(reset)
            cnt <= 0;
        else begin
            case(curr_state)
                DATA: cnt <= cnt + 1'b1;
                default: cnt <= 0;
            endcase
        end
    end
    
    //out
    always@(posedge clk)
    begin
        if(reset)
            out <= 8'd0;
        else begin
            case(next_state)
                DATA: out <= {in, out[7 : 1]};
            endcase
        end
    end
    
    //check
    always@(posedge clk)
    begin
        if(reset)
            check <= 1'b0;
        else
            check <= odd;
    end
    
    assign out_byte = out;
    assign done = check & (curr_state == STOP);
    
    parity parity_inst(
        .clk(clk),
        .reset(reset | start),
        .in(in),
        .odd(odd));  
    
endmodule

125、sequence recognition

image-20211112162052705

parameter none=4'd0;
    parameter one=4'd1;
    parameter two=4'd2;
    parameter three=4'd3;
    parameter four=4'd4;
    parameter five=4'd5;
    parameter six=4'd6;
    parameter error=4'd7;
    parameter discard=4'd8;
    parameter flag_=4'd9;
    
    reg [3:0] state;
    reg [3:0] next_state;
    
    always@(posedge clk)
        if(reset)
            state<=none;
        else
            state<=next_state;
    
    always@(*)
        case(state)
            none   :next_state=in?one:none;
            one    :next_state=in?two:none;
            two    :next_state=in?three:none;
            three  :next_state=in?four:none;
            four   :next_state=in?five:none;
            five   :next_state=in?six:discard;
            six    :next_state=in?error:flag_;
            error  :next_state=in?error:none;
            discard:next_state=in?one:none;
            flag_  :next_state=in?one:none;
        endcase
    
    assign disc = state == discard;
    assign flag = state == flag_;
    assign err  = state == error;
    

126、Desgin a Mealy FSM

    parameter IDLE=0,ONE=1,TWO=2;
    reg[1:0] state,next_state;
    
    always @(posedge clk or negedge aresetn)
        begin
            if(~aresetn)
                state <= IDLE;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case(state)
                IDLE : begin
                    next_state = x ? ONE : IDLE;
                    z = 1'b0;end
                ONE : begin
                    next_state = x ? ONE : TWO;
                    z = 1'b0;end
                TWO: begin
                    next_state = x ? ONE : IDLE;
                    z = x ? 1'b1 : 1'b0;end
            endcase
        end
    

127、Q5a

这道题假设输入都是负数,对输入作按位取反加一操作就行。对于源码和补码的区出现在第一个1,因为第一个1取反后变为0,此时进位到此为止。

.image-20211112171859201

	parameter A=0,B=1,C=2;
    reg[1:0] state,next_state;
    
    always @(posedge clk or posedge areset)
        begin
            if(areset)
                state <= A;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case (state)
                A : next_state = x ? B : A;
                B : next_state = x ? C : B;
                C : next_state = x ? C : B;
            endcase
        end
    assign z = (state == B) ;

128、Q5b

	parameter A=0,B=1;
    reg[1:0] state,next_state;
    
    always @(posedge clk or posedge areset)
        begin
            if(areset)
                state <= A;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case (state)
                A : next_state = x ? B : A;
                B : next_state =  B;
            endcase
        end
    assign  z    =   state == A ? x:~x ;

129、Q3A

image-20211112201117145

   reg [3:0]   state;
    reg [3:0]   nxt_state;

    wire        w_shft_ena;
    reg[1:0]    w_cntr;
    localparam A = 0;
    localparam B = 1;
    localparam B1 = 2;
    localparam B2 = 4;

    // State transition logic (combinational)
    always @(*) begin
        case (state)
            A:begin
                if(s)
                    nxt_state = B;
                else
                    nxt_state = A;
            end
            B:begin
                nxt_state = B1;
            end
            B1:begin
                nxt_state = B2;
            end
            B2:begin
                nxt_state = B;
            end
          default: begin
            nxt_state = A;
          end
        endcase
    end

    // State flip-flops (sequential)
    always @(posedge clk ) begin
        if(reset)
            state   <=  A;
        else begin
            state   <=  nxt_state;
        end  
    end

    always @(posedge clk ) begin
        if(reset)
            w_cntr   <=  2'b0;
        else if(state == B)begin
            w_cntr   <=  w;
        end
        else if(state == B1 || state == B2)begin
            w_cntr   <=  w_cntr + w;
        end   
    end

    assign  z    =   state == B &&  w_cntr == 2 ? 1'b1 : 1'b0;

130、Q3B

    reg [2:0]   state;
    reg [2:0]   nxt_state;

    localparam IDLE  = 3'd0;
    localparam s_1   = 3'd1;
    localparam s_10  = 3'd2;
    localparam s_11  = 3'd3;
    localparam s_100 = 3'd4;

    // State transition logic (combinational)
    always @(*) begin
        case (state)
            IDLE:begin
                if(x)
                    nxt_state = s_1;
                else
                    nxt_state = IDLE;
            end
            s_1:begin
                if(x)
                    nxt_state = s_100;
                else
                    nxt_state = s_1;
            end
            s_10:begin
                if(x)
                    nxt_state = s_1;
                else
                    nxt_state = s_10;
            end
            s_11:begin
                if(x)
                    nxt_state = s_10;
                else
                    nxt_state = s_1;
            end
            s_100:begin
                if(x)
                    nxt_state =s_100;
                else
                    nxt_state = s_11;
            end
          default: begin
            nxt_state = IDLE;
          end
        endcase
    end

    // State flip-flops (sequential)
    always @(posedge clk ) begin
        if(reset)
            state   <=  IDLE;
        else begin
            state   <=  nxt_state;
        end  
    end

    assign  z    =   state >= s_11;

131、Q3C

本题将当前状态作为输入,只需要规定出状态跳转逻辑即可,用输入来触发跳转,不需要时钟

      reg [2:0]   state;
    reg [2:0]   nxt_state;

    localparam IDLE  = 3'd0;
    localparam s_1   = 3'd1;
    localparam s_10  = 3'd2;
    localparam s_11  = 3'd3;
    localparam s_100 = 3'd4;

    assign state = y;
    // State transition logic (combinational)
    always @(*) begin
        case (state)
            IDLE:begin
                if(x)
                    nxt_state = s_1;
                else
                    nxt_state = IDLE;
            end
            s_1:begin
                if(x)
                    nxt_state = s_100;
                else
                    nxt_state = s_1;
            end
            s_10:begin
                if(x)
                    nxt_state = s_1;
                else
                    nxt_state = s_10;
            end
            s_11:begin
                if(x)
                    nxt_state = s_10;
                else
                    nxt_state = s_1;
            end
            s_100:begin
                if(x)
                    nxt_state =s_100;
                else
                    nxt_state = s_11;
            end
          default: begin
            nxt_state = IDLE;
          end
        endcase
    end


    assign Y0 = nxt_state[0] ;
    assign  z    =   state >= s_11;

132、Q6b

注意题目要求的是输出Y2的次态而不是现态

    wire [2:0]   state = y;
    reg [2:0]   nxt_state;

    localparam sA  = 3'd0;
    localparam sB  = 3'd1;
    localparam sC  = 3'd2;
    localparam sD  = 3'd3;
    localparam sE  = 3'd4;
    localparam sF  = 3'd5;

    // State transition logic (combinational)
    always @(*) begin
        case (state)
            sA:begin
                if(w)
                    nxt_state = sA;
                else
                    nxt_state = sB;
            end
            sB:begin
                if(w)
                    nxt_state = sD;
                else
                    nxt_state = sC;
            end
            sC:begin
                if(w)
                    nxt_state = sD;
                else
                    nxt_state = sE;
            end
            sD:begin
                if(w)
                    nxt_state = sA;
                else
                    nxt_state = sF;
            end
            sE:begin
                if(w)
                    nxt_state = sD;
                else
                    nxt_state = sE;
            end
            sF:begin
                if(w)
                    nxt_state = sD;
                else
                    nxt_state = sC;
            end
          default: begin
            nxt_state = sA;
          end
        endcase
    end
 
    assign  Y2   =   nxt_state[1];

132、Q6c

    assign Y2 = ~w & y[1] ;
    assign Y4 = (w & y[2])|(w & y[3])|(w & y[5])|(w & y[6]);

133、Q6

 reg [5:0]   state;
    reg [5:0]   nxt_state;

    localparam sA  = 6'd1;
    localparam sB  = 6'd2;
    localparam sC  = 6'd4;
    localparam sD  = 6'd8;
    localparam sE  = 6'd10;
    localparam sF  = 6'd20;

    // State transition logic (combinational)
    always @(*) begin
        nxt_state[0]    <=  w ? state[0] || state[3] : 1'b0;
        nxt_state[1]    <=  w ? 1'b0 : state[0];
        nxt_state[2]    <=  w ? 1'b0 : state[5] || state[1];
        nxt_state[3]    <=  w ? state[1] || state[2] || state[4] || state[5]: 1'b0;
        nxt_state[4]    <=  w ? 1'b0 : state[4] || state[2];
        nxt_state[5]    <=  w ? 1'b0 : state[3];
    end

    always @(posedge clk ) begin
        if(reset)
            state   <=  sA;
        else begin
            state   <=  nxt_state;
        end  
    end
 
    assign  z   =   state[4] || state[5];  

134、Q2a

reg  [6 : 1] curr_state;
    reg  [6 : 1] next_state;
    
    parameter A = 1;
    parameter B = 2;
    parameter C = 3;
    parameter D = 4;
    parameter E = 5;
    parameter F = 6;
    
    always@(posedge clk)
    begin
        if(reset)
            curr_state    <= A;
        else
            curr_state    <= next_state;
    end
    
    always@(*)
    begin
        next_state[A] = (curr_state[A] &  ~w) || (curr_state[D] &  ~w);
        next_state[B] = (curr_state[A] & w);
        next_state[C] = (curr_state[B] & w) || (curr_state[F] & w);
        next_state[D] = (curr_state[B] &  ~w) || (curr_state[C] &  ~w)
        || (curr_state[E] &  ~w) || (curr_state[F] &  w);
        next_state[E] = (curr_state[C] & w) || (curr_state[E] & w);
        next_state[F] = (curr_state[D] & w);
    end
    
    assign z = curr_state[E] | curr_state[F];

135、Q2b

    wire [6 : 1] curr_state = y[5 : 0];
    reg  [6 : 1] next_state;
    
    parameter A = 1;
    parameter B = 2;
    parameter C = 3;
    parameter D = 4;
    parameter E = 5;
    parameter F = 6;
    
    always@(*)
    begin
        next_state[A] = (curr_state[A] & ~w) || (curr_state[D] & ~w);
        next_state[B] = (curr_state[A] &  w);
        next_state[C] = (curr_state[B] &  w) || (curr_state[F] &  w);
        next_state[D] = (curr_state[B] & ~w) || (curr_state[C] & ~w)
        			 || (curr_state[E] & ~w) || (curr_state[F] & ~w);
        next_state[E] = (curr_state[C] &  w) || (curr_state[E] &  w);
        next_state[F] = (curr_state[D] &  w);
    end
    
    assign Y1 = next_state[B];
    assign Y3 = next_state[D];

136、Q2a


    wire [2:0] ri = r;
    wire [2:0] go;

    reg [3:0]   state;
    reg [3:0]   nxt_state;

    localparam sidle    = 0;
    localparam sd1      = 1;//devive 1 
    localparam sd2      = 2;
    localparam sd3      = 3;

    // State transition logic (combinational)
    always @(*) begin
        nxt_state[sidle]    <=  (state[sidle] && ~(|ri)) 
                             || (state[sd1]   && ~ri[0]) 
                             || (state[sd2]   && ~ri[1]) 
                             || (state[sd3]   && ~ri[2]);

        nxt_state[sd1  ]    <=  (state[sidle] && ri[0])
                             || (state[sd1  ] && ri[0]);

        nxt_state[sd2  ]    <=  (state[sidle] && ~ri[0] && ri[1])
                             || (state[sd2  ] && ri[1]);

        nxt_state[sd3  ]    <=  (state[sidle] && ~ri[0] && ~ri[1] && ri[2])
                             || (state[sd3  ] && ri[2]);
        
    end

    // State flip-flops (sequential)
    always @(posedge clk ) begin
        if(~resetn)
            state   <=  4'b1;
        else begin
            state   <=  nxt_state;
        end  
    end

    //output logic
    assign      go[0]   =   state[sd1  ];
    assign      go[1]   =   state[sd2  ];
    assign      go[2]   =   state[sd3  ];
    assign      g       =   go;

137、Q2b

本道题要求复位的下一时钟输出f,可以理解为两状态状态机。然后检测x为101又是一个状态机。在检测完成后,进入检测y的状态机。

因为y要检测两个时钟周期,所以加上idle状态即是三个状态。

    localparam FSM_W  = 10;
    localparam FSM_W1 = FSM_W - 1'b1;

    reg [FSM_W1:0]   state;
    reg [FSM_W1:0]   nxt_state;

    localparam  IDLE      = 0;
    localparam  AFT_RST   = 1;
    localparam  STRT_X_MNT= 2;
    localparam  X_1       = 3;
    localparam  X_0       = 4;
    localparam  X_10      = 5;
    localparam  X_101     = 6;
    localparam  Y_S0      = 7;
    localparam  G_O0      = 8;
    localparam  G_O1      = 9;

    // State transition logic (combinational)
    always @(*) begin
        nxt_state[IDLE   ]          =   1'b0; // never reach for nxt_state
        nxt_state[AFT_RST]          =   (state[IDLE   ]);
        nxt_state[STRT_X_MNT]       =   (state[AFT_RST]);
        nxt_state[X_1    ]          =   (state[STRT_X_MNT] &&  x) || (state[X_1    ] &&  x) || (state[X_0    ] &&  x);
        nxt_state[X_0    ]          =   (state[STRT_X_MNT] && ~x) || (state[X_10   ] && ~x) || (state[X_0    ] && ~x);
        nxt_state[X_10   ]          =   (state[X_1    ] && ~x);
        nxt_state[X_101  ]          =   (state[X_10   ] &&  x);
        nxt_state[Y_S0   ]          =   (state[X_101  ] && ~y);
        nxt_state[G_O0   ]          =   (state[Y_S0   ] && ~y) || state[G_O0   ];
        nxt_state[G_O1   ]          =   (state[Y_S0   ] &&  y) || (state[X_101  ] &&  y) || state[G_O1   ];
    end

    // State flip-flops (sequential)
    always @(posedge clk) begin
        if(~resetn)
            state   <=  'b1; //IDLE
        else begin
            state   <=  nxt_state;
        end  
    end

    //output logic
    assign  f    =   state[AFT_RST];
    assign  g    =   (state[X_101] || state[G_O1] || state[Y_S0]) ? 1'b1 : 1'b0;

138、4-bit shift register and down counter

    reg [3:0]shift;
    always @(posedge clk)
        begin
            if(shift_ena)
                shift <= {shift[2:0],data};
            else if(count_ena)
                shift <= shift - 1;
            else
                shift <= shift;
        end
    assign q = shift;

139、FSM:sequence 1101 recognizer

    reg [2:0] state,next_state;
    parameter idle=0,s1=1,s11=2,s110=3,s1101=4;
    
    always @(posedge clk)
        begin
            if(reset)
                state <= idle;
            else 
                state <= next_state;
        end
    always @(*)
        begin
            case(state)
                idle : next_state = data ? s1 : idle;
                s1	 : next_state = data ? s11: idle;
                s11	 : next_state = data ? s11: s110;
                s110 : next_state = data ? s1101 : idle;
                s1101: next_state = s1101;
                default : next_state = idle;
            endcase
        end
    assign start_shifting = (state == s1101) ;

140、FSM:Enable shift register

    parameter idle=0,s0=1,s1=2,s2=3,s3=4;
    reg [2:0] state,next_state;
    
    always @(posedge clk)
        begin
            if(reset)
                state <= s0;
            else
                state <= next_state;
        end
    always @(*)
        begin
            case (state)
                idle : next_state = idle ;
                s0 : next_state = s1;
                s1 : next_state = s2;
                s2 : next_state = s3;
                s3 : next_state = idle;
                default : next_state = idle;
            endcase
        end
    assign shift_ena = (state == s0) |(state == s1) |(state == s2) |(state == s3) ;

141、complete FSM

image-20211113162451566

 parameter S = 4'd0, S1 = 4'd1, S11 = 4'd2, S110 = 4'd3;
    parameter B0 = 4'd4, B1 = 4'd5, B2 = 4'd6, B3 = 4'd7;
    parameter Count = 4'd8, Wait = 4'd9;
    reg [3:0] current_state, next_state;

    always @(*) begin
        case(current_state)
            S:          next_state = data ? S1 : S;
            S1:         next_state = data ? S11 : S;
            S11:        next_state = data ? S11 : S110;
            S110:       next_state = data ? B0 : S;
            B0:         next_state = B1;
            B1:         next_state = B2;
            B2:         next_state = B3;
            B3:         next_state = Count;
            Count:      next_state = done_counting ? Wait : Count;
            Wait:       next_state = ack ? S : Wait;
            default:    next_state = S;
        endcase
    end

    always @(posedge clk) begin
        if(reset) begin
            current_state <= S;
        end
        else begin
            current_state <= next_state;
        end
    end

    assign shift_ena = current_state == B0 | current_state == B1 | current_state == B2 | current_state == B3;
    assign counting = current_state == Count;
    assign done = current_state == Wait;

posted @   骑猪上树的少年  阅读(304)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
回到顶部
点击右上角即可分享
微信分享提示

目录导航