[HDLbit] Exams/review2015 fancytimer

难点易错点总结

  1. 状态机:总共10个状态,一开始写了11个状态,发现从B4跳变到CUNT的状态多余,并且时序不符合题目要求,会延迟一个时钟周期输出count信号
  2. count信号:该信号每计数够1000就减一,同时要求进入CUNT状态的第一个周期就要输出count数据。要满足此要求,唯有将上个状态(D4)的data_r信号直接输出。

代码

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack );

    parameter IDLE = 4'd0;
    parameter B1   = 4'd1;
    parameter B2   = 4'd2;
    parameter B3   = 4'd3;
    parameter B4   = 4'd4;		//不需要此状态
    parameter D1   = 4'd5;
    parameter D2   = 4'd6;
    parameter D3   = 4'd7;
    parameter D4   = 4'd8;
    parameter CUNT = 4'd9;
    parameter DONE = 4'd10;

    reg [3:0] state, next_state;
    reg [3:0] data_r;		//count_d每计数1000减一
    reg [3:0] data_rr;		//稳定值,不变
    reg [14:0] count_d;		//计数器
    wire c_flag;			//计数完毕标志


    always @(posedge clk)begin
        if(reset)
            state <= IDLE;
        else
            state <= next_state;
    end


    always @*begin
        case(state)
            IDLE : next_state = data ? B1 : IDLE;
            B1	 : next_state = data ? B2 : IDLE;
            B2	 : next_state = data ? B2 : B3;
            B3	 : next_state = data ? D1 : IDLE;
            D1	 : next_state = D2;
            D2	 : next_state = D3;
            D3	 : next_state = D4;            
            D4	 : next_state = CUNT;
            CUNT : next_state = c_flag ? DONE : CUNT;
            DONE : next_state = ack ? IDLE : DONE;
            default : next_state = 'x;
        endcase
    end


    always @(posedge clk)begin
        if(reset)begin
            data_r <= 0;
            count_d <= 0;
        end
        else
            case(state)				//此处可以用移位寄存器
                D1 : data_r[3] <= data;
                D2 : data_r[2] <= data;
                D3 : data_r[1] <= data;
                D4 : begin
                    data_r[0] <= data;
                    data_rr <= {data_r[3:1], data};
                end
                CUNT: begin
                    count_d <= count_d +1'b1;
                    case(count_d)
                        999: data_r <=data_r -1'b1;
                        1999: data_r <=data_r -1'b1;
                        2999: data_r <=data_r -1'b1;
                        3999: data_r <=data_r -1'b1;
                        4999: data_r <=data_r -1'b1;
                        5999: data_r <=data_r -1'b1;
                        6999: data_r <=data_r -1'b1;
                        7999: data_r <=data_r -1'b1;
                        8999: data_r <=data_r -1'b1;
                        9999: data_r <=data_r -1'b1;
                        10999: data_r <=data_r -1'b1;
                        11999: data_r <=data_r -1'b1;
                        12999: data_r <=data_r -1'b1;
                        13999: data_r <=data_r -1'b1;
                        14999: data_r <=data_r -1'b1;
                        15999: data_r <=data_r -1'b1;
                    endcase
                end
                default: count_d <= 0;
            endcase
    end
    
    
    assign c_flag = (count_d == (data_rr+1'b1)*1000-1);
    assign counting = (state == CUNT);
    assign done = (state == DONE);
    assign count = data_r;

endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

666BOY666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值