HDLbits---Exams/review2015 fancytimer

HDLbits—Exams/review2015 fancytimer

这一题同样困扰了我几天,今天把HDLbits—Fsm serialdp 和这题都给完成了,之前的发现自己犯的错是把输入wire型的放在时序逻辑中输出,但是应该是使用寄存器再assign输出才对。慢慢写倒是一次写出来了。历时2周终于把HDLbits刷完了,接下来学习找工作需要的内容了

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack );
    
	parameter IDLE = 3'd0,DECT_1 = 3'd1,DECT_11 = 3'd2,DECT_110 = 3'd3,REC_DELAY = 3'd4,TIMER = 3'd5,WAIT = 3'd6;
    //IDLE空闲状态,只有接收到1时才跳转
    //DECT_1 = 3'd1,DECT_11 = 3'd2,DECT_110这3个状态是用来接收1101de
    //REC_DELAY状态接收4bit延迟数据,接收完成跳转到计时状态
    //TIMER状态只有当接收完成跳转WAIT状态
    //WAIT状态等待ack信号
    
    reg [2:0] state,next_state;
    reg counting_reg,done_reg;
    reg [15:0] counter;//用于保存(delay+1)*1000
    reg [3:0] delay;//用于保存延迟数据
    reg [3:0] counter_delay;//用于得到count结果,count = delay-counter_delay
    reg [1:0] rec_delay_count;//接收4bitdelay计数器,0-3
    
    
    //描述次态寄存器迁移到现态寄存器
    always@(posedge clk)begin
        if(reset)begin
        	state <= IDLE;
        end
        else begin
            state <= next_state;
        end
    end
    
    
    //组合逻辑always模块,描述状态转移条件判断
    always@(*)begin
        case(state)
            IDLE:begin
                if(data)begin
                	next_state <= DECT_1;
                end
                else begin
                    next_state <= IDLE;
                end
            end
            DECT_1:begin
                if(data)begin
                	next_state <= DECT_11;
                end
                else begin
                    next_state <= IDLE;
                end
            end
            DECT_11:begin
                if(!data)begin
                	next_state <= DECT_110;
                end
                else begin
                    next_state <= DECT_11;
                end
            end
            DECT_110:begin
                if(data)begin
                	next_state <= REC_DELAY;
                end
                else begin
                    next_state <= IDLE;
                end
            end
            REC_DELAY:begin
                if(rec_delay_count == 3)begin
                    next_state <= TIMER;
                end
                else begin
                    next_state <= REC_DELAY;
                end
            end
            TIMER:begin
                if(counter == ((delay + 1)*1000 - 1))begin
                    next_state <= WAIT;
                end
                else begin
                    next_state <= TIMER;
                end
            end
            WAIT:begin
                if(ack)begin
                    next_state <= IDLE;
                end
                else begin
                    next_state <= WAIT;
                end
            end
            default:next_state <= IDLE;
        endcase
    end
    
    
    //同步时序always模块,格式化描述次态寄存器输出
    always@(posedge clk)begin
        if(reset)begin
            counting_reg = 0;
            done_reg = 0;
            
            counter = 0;//用于保存(delay+1)*1000
            delay = 0;//用于保存延迟数据
            rec_delay_count = 0;//接收4bitdelay计数器,0-3
        end
        else begin
            case(state)
            	IDLE:begin
                    counting_reg <= 0;
                    done_reg <= 0;

                    counter <= 0;//用于保存(delay+1)*1000
                    delay <= 0;//用于保存延迟数据
                    rec_delay_count <= 0;//接收4bitdelay计数器,0-3
            	end
                DECT_1:begin
                    
                end
                DECT_11:begin
                    
                end
                DECT_110:begin
                    
                end
                REC_DELAY:begin
                    if(rec_delay_count == 3)begin
                        delay <= {delay[2:0],data};
                        counting_reg <= 1;
                    end
                    else begin
                        rec_delay_count <= rec_delay_count + 1;
                        delay <= {delay[2:0],data};
                    end
                end
                TIMER:begin
                    if(counter == ((delay + 1)*1000 - 1))begin
                        done_reg <= 1;
                        counting_reg <= 0;
                    end
                    else begin
                        counter <= counter + 1;
                    end
                end
                WAIT:begin
                    if(ack)begin
                        done_reg <= 0;
                    end
                    else begin
                        done_reg <= 1;
                    end
                end
                default:begin
                    counting_reg <= 0;
                    done_reg <= 0;

                    counter <= 0;//用于保存(delay+1)*1000
                    delay <= 0;//用于保存延迟数据
                    rec_delay_count <= 0;//接收4bitdelay计数器,0-3
            	end
            endcase
        end
    end
    
    
    //这里用组合逻辑是因为这么写更清晰,将这一段放在状态机看起来不太方便,因为是从0开始计数的所以结果是((delay + 1)*1000 - 1)
    always@(*)begin
        if(counter <= 999)begin
            counter_delay = 4'd0;
        end
        else if(counter >= 1000 && counter <= 1999)begin
            counter_delay = 4'd1;
        end
        else if(counter >= 2000 && counter <= 2999)begin
            counter_delay = 4'd2;
        end
        else if(counter >= 3000 && counter <= 3999)begin
            counter_delay = 4'd3;
        end
        else if(counter >= 4000 && counter <= 4999)begin
            counter_delay = 4'd4;
        end
        else if(counter >= 5000 && counter <= 5999)begin
            counter_delay = 4'd5;
        end
        else if(counter >= 6000 && counter <= 6999)begin
            counter_delay = 4'd6;
        end
        else if(counter >= 7000 && counter <= 7999)begin
            counter_delay = 4'd7;
        end
        else if(counter >= 8000 && counter <= 8999)begin
            counter_delay = 4'd8;
        end
        else if(counter >= 9000 && counter <= 9999)begin
            counter_delay = 4'd9;
        end
        else if(counter >= 10000 && counter <= 10999)begin
            counter_delay = 4'd10;
        end
        else if(counter >= 11000 && counter <= 11999)begin
            counter_delay = 4'd11;
        end
        else if(counter >= 12000 && counter <= 12999)begin
            counter_delay = 4'd12;
        end
        else if(counter >= 13000 && counter <= 13999)begin
            counter_delay = 4'd13;
        end
        else if(counter >= 14000 && counter <= 14999)begin
            counter_delay = 4'd14;
        end
        else begin
            counter_delay = 4'd15;
        end
    end 
    //输出数据
	assign counting = counting_reg;
    assign done = done_reg;
    assign count = (state == TIMER)?(delay - counter_delay ):0;
endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

离离离谱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值