发布时间:2022-11-07 文章分类:编程知识 投稿人:赵颖 字号: 默认 | | 超大 打印

Exams/review2015 count1k

计数到999再清零即可。

module top_module (
    input clk,
    input reset,
    output reg[9:0] q);
    always@(posedge clk)
    begin
        if(reset)
            q <= 'd0;
        else
            q <= (q<10'd999)?(q+1'b1):'d0;
    end
endmodule

Exams/review2015 shiftcount

电路有两种状态:移位和向下计数,这里计到0是可以继续计的,不用做特殊处理。

module top_module (
    input clk,
    input shift_ena,
    input count_ena,
    input data,
    output reg[3:0] q);
    always@(posedge clk)
    begin
        if(shift_ena)
            q <= {q[2:0],data};
        else if(count_ena)
            q <= q-1'b1;
    end
endmodule

Exams/review2015 fsmseq

序列检测的状态机,很熟悉了。

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output start_shifting);
    reg[2:0]state,next_state;
    parameter S0=0,S1=1,S11=2,S110=3,S1101=4;
    always@(posedge clk)
    begin
        if(reset) 
            state <= S0;
        else
            state <= next_state;
    end
    always@(*)
    begin
        case(state)
            S0:next_state=data?S1:S0;
            S1:next_state=data?S11:S0;
            S11:next_state=data?S11:S110;
            S110:next_state=data?S1101:S0;
            S1101:next_state=S1101;
            default:next_state=S0;
        endcase
    end
    assign start_shifting=(state == S1101);
endmodule

Exams/review2015 fsmshift

这里是count==3就拉低,因为从时序图可以看出这里的四个周期是从reset开始算起的。

module top_module (
    input clk,
    input reset,      // Synchronous reset
    output reg shift_ena);
    reg [3:0]count;
    always@(posedge clk)
    begin
        if(reset)begin
            count <= 4'd0;
            shift_ena <= 1'b1;
        end
        else begin
            count <= (count<4)?(count +1'b1):4'd0;
            if(count==3)
                shift_ena <= 1'b0;
        end
    end
endmodule

Exams/review2015 fsm

这题只需要实现控制的状态机,不需要计数。

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output shift_ena,
    output counting,
    input done_counting,
    output done,
    input ack );
    parameter S0=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
    reg [3:0]state,next_state;
    always@(posedge clk)
    begin
        if(reset) 
            state <= S0;
        else
            state <= next_state;
    end    
    always@(*)
    begin
        case(state)
            S0:next_state=data?S1:S0;
            S1:next_state=data?S11:S0;
            S11:next_state=data?S11:S110;
            S110:next_state=data?B0:S0;
            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?S0:Wait;
            default:next_state=S0;
        endcase
    end
    assign shift_ena = (state==B0)||(state==B1)||(state==B2)||(state==B3);
    assign counting = (state==Count);
    assign done = (state==Wait);
endmodule

Exams/review2015 fancytimer

在上一题的基础上要实现整个完整的逻辑。

主要是计数部分的代码要仔细考虑一下,这里直接用了一个除法,简单粗暴,但是实际电路中感觉这样不太好,看了一下别人的答案,有的是通过循环计数到999再进行shift_reg-1的操作,感觉会更好一些。

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output reg[3:0] count,
    output counting,
    output done,
    input ack );
    parameter S0=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
    reg [3:0]state,next_state;
    always@(posedge clk)
    begin
        if(reset) 
            state <= S0;
        else
            state <= next_state;
    end    
    always@(*)
    begin
        case(state)
            S0:next_state=data?S1:S0;
            S1:next_state=data?S11:S0;
            S11:next_state=data?S11:S110;
            S110:next_state=data?B0:S0;
            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?S0:Wait;
            default:next_state=S0;
        endcase
    end
    wire shift_ena;
    wire done_counting;
    reg[31:0]cnt;
    reg [3:0]delay;
    always@(posedge clk)
    begin
        if(reset)begin
            cnt <= 'd0;
            delay <= 'd0;
        end           
        else if(shift_ena)begin
            delay <={delay[2:0],data};
        end
        else if(counting)begin
            cnt <= cnt + 1'b1;
        end
        else
            cnt <= 'd0;
    end
    assign shift_ena = (state==B0)||(state==B1)||(state==B2)||(state==B3);
    assign counting = (state==Count);
    assign done = (state==Wait);
    assign count = delay-cnt/1000;
    assign done_counting = (cnt==(delay+1)*1000-1);
endmodule

Exams/review2015 fsmonehot

也是老题型了,有状态转换图还是非常好写的。

module top_module(
    input d,
    input done_counting,
    input ack,
    input [9:0] state,    // 10-bit one-hot current state
    output B3_next,
    output S_next,
    output S1_next,
    output Count_next,
    output Wait_next,
    output done,
    output counting,
    output shift_ena
); //
    // You may use these parameters to access state bits using e.g., state[B2] instead of state[6].
    parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
    assign B3_next = state[B2];
    assign S_next = (state[S]&~d)||(state[S1]&~d)|(state[S110]&~d)||(state[Wait]&ack);
    assign S1_next = (state[S]&d);
    assign Count_next = state[B3]||(state[Count]&~done_counting);
    assign Wait_next = (state[Count]&done_counting)||(state[Wait]&~ack);
    assign done = state[Wait];
    assign counting = state[Count];  
    assign shift_ena=state[B0]|state[B1]|state[B2]|state[B3];
    // etc.
endmodule