Exams/review2015 fancytimer_HDLbits详解

铺垫了四题终于出来了,感觉像是打BOSS怪了

题目(瞄一眼就行,感觉写的乱七八糟):

我们希望创建一个带有一个输入的计时器:当检测到特定输入模式(1101)时启动,再移位4位以确定延迟的持续时间,等待计数器完成计数,然后通知用户并等待用户确认计时器。

串行数据在数据输入引脚上可用。当接收到模式1101时,电路必须在接下来的4位中移位,最高有效位首先移位。这4位决定计时器延迟的持续时间。我称之为delay[3:0]。

之后,状态机断言其计数输出,以指示其正在计数。状态机必须精确计数(delay[3:0]+1)*1000个时钟周期。e、 例如,delay=0表示计数1000个周期,delay=5表示计数6000个周期。同时输出当前剩余时间。这应该等于延迟1000个周期,然后延迟-1 1000个周期,依此类推,直到1000个周期为0。当电路不计数时,count[3:0]输出为不关心(无论什么值便于实现)。

此时,电路必须断言已完成,以通知用户计时器已超时,并等待输入ack为1,然后再重置,以查找下一次出现的启动序列(1101)。

电路应复位至开始搜索输入序列1101的状态。

以下是预期输入和输出的示例。“x”状态读起来可能有点混乱。它们表明FSM不应该关心该周期中的特定输入信号。例如,一旦1101和延迟[3:0]被读取,电路将不再查看数据输入,直到完成所有其他操作后恢复搜索。在本例中,电路计数2000个时钟周期,因为delay[3:0]值为4'b0001。最后几个周期开始另一次计数,delay[3:0]=4'b1110,这将计15000个周期。

解题:

状态变化和上一题类似,但是,图中count为啥从1变成0完全没想明白,delay怎么变化的也弄不清楚

看了别人的答案才知道,每过1000个计时周期delay要-1,我就说为啥我这儿count一直报错(*&&……%&¥脏话)我寻思着题里好像也没说吧,这波形图也离谱,在1994从count从0跳到1,这不误导人吗???

然后就再捋一捋就不难了,主要思路是:

1、搜索1101

2、接收data后移位,确定delay

3、开始计数(计数周期由delay确定)

4、判断是否完成done

5、完成后等待重置

代码详解如下:

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack );
    
    parameter s=0,s1=1,s11=2,s110=3,b0=4,b1=5,b2=6,b3=7,count0=8,wait0=9;
    reg [3:0] state,nstate;   
    reg [13:0] counter;//用来进行周期计数
    reg [3:0] delay,delay0;
    //delay0用老保持delay的初始值,从而确定计数周期不变,因为delay会改变而每次行为周期是确定的
    
    
    always @(posedge clk)
        begin
            if(reset) state<=s;
            else state<=nstate;
        end

    
    always @(posedge clk)
        begin
            case(state)
                b0:  delay={delay[2:0],data}; 
                b1:  delay={delay[2:0],data}; 
                b2:  delay={delay[2:0],data}; e 
                b3:begin delay={delay[2:0],data};counter =0; delay0=delay;end
                //当delay完成初始化之后,需要用delay0来保持delay的值,用于后续计数截止的判断
                count0:
                    begin 
                        counter=counter+1; 
                //在这里我用的加法,题意是用减法,我觉得意思一样,加法更便于后续的截止判断
                //一开始不清楚的就是这一部分,看了别人的答案才明白
                //从计数开始,每次满1000,delay就减1.
                        if(counter==1000) delay<=delay-1;
                        else if(counter==2000) delay<=delay-1;
                        else if(counter==3000) delay<=delay-1;
                        else if(counter==4000) delay<=delay-1;
                        else if(counter==5000) delay<=delay-1;
                        else if(counter==6000) delay<=delay-1;
                        else if(counter==7000) delay<=delay-1;
                        else if(counter==8000) delay<=delay-1;
                        else if(counter==9000) delay<=delay-1;
                        else if(counter==10000) delay<=delay-1;
                        else if(counter==11000) delay<=delay-1;
                        else if(counter==12000) delay<=delay-1;
                        else if(counter==13000) delay<=delay-1;
                        else if(counter==14000) delay<=delay-1;
                        else if(counter==15000) delay<=delay-1;
                        else if(counter==16000) delay<=delay-1;
                        //couter==16000不写也没事,周期最大就是15000,这里应该删除,写的时候一开始没有注意
                         
                    end
                
                default : begin counter =0;delay<=0; end
            endcase 
        
        end
    
    //状态变化和上一题类似,接收1101,移位,计数,完成,等待重置。
    always @(*)
        begin
            case(state)
                s: nstate<=(data)? s1 : s;
                s1: nstate<=(data)? s11: s;
                s11: nstate<=(!data)? s110: s11;
                s110: nstate<=(data)? b0: s;
                b0: nstate<=b1; //接收到1101即开始移位
                b1: nstate<=b2;
                b2: nstate<=b3;                    
                b3: nstate<=count0; //四个clk后开始计数
                count0:nstate<=(counter==(delay0+1)*1000-1)? wait0 : count0;
                //delay0的值保持不变,一开始用delay是不正确的
                wait0 : nstate<=(ack)?s:wait0;
                default : nstate<=s;
            endcase
        end     

    assign count = delay;
    assign counting = state==count0;
    assign done = state==wait0 ;
 

endmodule

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值