HDLBits -【Building Larger Circuits】

1.Exams/review2015 count1k

  构建一个计数范围为0到999(含0到999)的计数器,周期为1000个周期。重置输入是同步的,应将计数器重置为0。
在这里插入图片描述

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

2.Exams/review2015 shiftcount

  构建一个四位移位寄存器,该寄存器也用作递减计数器。 当 shift_ena 为 1 时,数据首先移入最高有效位。当 count_ena 为 1 时,当前在移位寄存器中的数字递减。由于整个系统不会同时使用 shift_ena 和 count_ena,因此您的电路无关紧要 如果两个控制输入都为 1(这主要意味着哪种情况获得更高优先级并不重要)。
在这里插入图片描述

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

endmodule

3.Exams/review2015 fsmseq

  构建一个有限状态机,在输入比特流中搜索序列 1101。 找到序列后,应将 start_shifting 设置为 1,直到重置。 陷入最终状态旨在模拟在尚未实现的更大 FSM 中进入其他状态。 我们将在接下来的几个练习中扩展这个 FSM。
在这里插入图片描述

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output start_shifting);
    parameter A=3'd0,B=3'd1,C=3'd2,D=3'd3,E=3'd4;
    reg [2:0]state,next_state;
    always@(posedge clk)begin
        if(reset)
            state<=A;
        else
            state<=next_state;
    end
    
    always@(*)begin
        case(state)
            A:next_state=data?B:A;
            B:next_state=data?C:A;
            C:next_state=data?C:D;
            D:next_state=data?E:A;
            E:next_state=E;
            default:next_state=A;
        endcase
    end
    
    assign start_shifting=(state==E);
endmodule

4.Exams/review2015 fsmshift

  这是一系列五个练习中的第三个部分,这些练习由几个较小的电路构建一个复杂的计数器。 有关整体设计,请参阅最终练习。
  作为用于控制移位寄存器的 FSM 的一部分,我们希望能够在检测到正确的位模式时启用移位寄存器恰好 4 个时钟周期。 我们在 上题中处理序列检测,因此 FSM 的这一部分仅处理启用 4 个周期的移位寄存器。
  每当 FSM 复位时,将 shift_ena 置位 4 个周期,然后永远为 0(直到复位)。
在这里插入图片描述

//--------------------法一----------------------------//
module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);
    parameter S0=3'd1,S1=3'd2,S2=3'd3,S3=3'd4,S4=3'd5;
    reg [2:0]state,next_state;
    always@(posedge clk)begin
        if(reset)
            state<=S0;
        else
            state<=next_state;
    end
    
    always@(*)begin
        case(state)
            S0:next_state=S1;
            S1:next_state=S2;
            S2:next_state=S3;
            S3:next_state=S4;
            S4:next_state=S4;
            default:next_state=S0;
        endcase
    end
                
    assign shift_ena=(state==S0)|(state==S2)|(state==S1)|(state==S3);
endmodule

//-------------------法二----------------------------//
module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);
    wire cnt_start,cnt_end;
    reg [3:0]cnt;
    always@(posedge clk)begin
        if(reset)
            cnt<=4'd0;
        else if(cnt_start)begin
            cnt<=cnt+1'b1; 
        end
        else if(cnt_end)begin
            cnt<=4'd0; 
        end
    end
    
    assign cnt_start=shift_ena;
    assign cnt_end=(cnt==4'd3);
    
    always@(posedge clk)begin
        if(reset)
            shift_ena=1'b1;
        else if(cnt_end)
            shift_ena=1'b0;
    end
endmodule

5.Exams/review2015 fsm

  您可能希望先执行 FSM:启用移位寄存器和 FSM:序列识别器。我们想创建一个计时器:
  1.当检测到特定模式 (1101) 时开始,
  2.再移 4 位以确定延迟的持续时间,
  3.等待计数器完成计数,并且
  4.通知用户并等待用户确认计时器。
  在这个问题中,只实现控制定时器的有限状态机。此处不包括数据路径(计数器和一些比较器)。
  串行数据在数据输入引脚上可用。当接收到模式 1101 时,状态机必须断言输出 shift_ena 正好 4 个时钟周期。
  之后,状态机断言其计数输出以指示它正在等待计数器,并一直等到输入 done_counting 为高。
  此时,状态机必须断言完成以通知用户定时器已超时,并等待直到输入 ack 为 1,然后才被重置以寻找下一次出现的启动序列 (1101)。
  状态机应重置为开始搜索输入序列 1101 的状态。
  这是预期输入和输出的示例。 ‘x’ 状态读起来可能有点混乱。它们表明 FSM 不应该关心该周期中的特定输入信号。例如,一旦检测到 1101 模式,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 A=4'd0,B=4'd1,C=4'd2,D=4'd3,E=4'd4,S1=4'd5,S2=4'd6,S3=4'd7,COUNT=4'd8,WAIT=4'd9;
    reg [3:0]state,next_state;
    
    always@(posedge clk)begin
        if(reset)
            state<=A;
        else
            state<=next_state;
    end
    
    always@(*)begin
        case(state)
            A:next_state=data?B:A;
            B:next_state=data?C:A;
            C:next_state=data?C:D;
            D:next_state=data?E:A;
            E:next_state=S1;
            S1:next_state=S2;
            S2:next_state=S3;
            S3:next_state=COUNT;
            COUNT:next_state=done_counting?WAIT:COUNT;
            WAIT:next_state=ack?A:WAIT;
            default:next_state=A;
        endcase
    end
    
    assign shift_ena=(state==E)|(state==S1)|(state==S2)|(state==S3);
    assign counting=(state==COUNT);
    assign done=(state==WAIT);
endmodule

6.Exams/review2015 fancytimer

  在数据流中检测到序列 1101 后,电路需要将接下来的 4bit 数据移入移位寄存器。4bit 数据决定了计数器的计数周期,称为 delay[3:0]。首先到达的比特作为数据的高位。
  之后,状态机置高 counting 信号,表示其正在等待计数器完成计数。在 FSM 中增加计数器状态,计数周期为 (delay[3:0] + 1 )* 1000 个时钟周期。比如 delay = 0 时,计数值为 1000 个周期。delay = 5 代表 6000 个周期。同时输出 count 当前剩余的计数周期,输出当前剩余计数周期的千位(比如,还剩1000个周期输出 1,还剩 999 个周期时输出 0)。当计数停止后,count 的输出可以为任意数。
  当计数完成后,电路置高 done 信号通知上层应用计数器计数完成,等待 ack 信号置高后,状态机清除 done 信号,返回空闲状态等待捕获下一个 1101 序列。
  本题给出了一个期望输入输出的例子。图中的斜线代表当前信号为 ‘X’, 表示状态机不关心该信号当前的值。比如图例中,一旦 FSM 检测到 1101 序列并读取 delay[3:0] 后,在此次计数器事件完成前,对于当前的数据流不再关心。
  在图例中,电路计数周期为 2000 ,因为 delay[3:0] 数值为 4’b0001 。在后续的第二个计数周期中,因为 delay[3:0] = 4‘b1110,所以计数周期为 15000在这里插入图片描述

module top_module (
    input clk,
    input reset,      // Synchronous reset
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack );
    
	parameter S0=4'd0,S1=4'd1,S11=4'd2,S110=4'd3,
    D0=4'd4,D1=4'd5,D2=4'd6,D3=4'd7,COUNT=4'd8,WAIT=4'd9;
    reg [3:0]state,next_state;
    reg [3:0]delay;
    reg [15:0] cnt;
    wire full,start_cnt;
    
    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?D0:S0;
            D0:begin
                next_state=D1;
                //delay[3]=data;
            end
            D1:begin
                next_state=D2;
                //delay[2]=data;
            end
            D2:begin
                next_state=D3;
                //delay[1]=data;
            end
            D3:begin
                next_state=COUNT;
                //delay[0]=data;
            end
            COUNT:next_state=full?WAIT:COUNT; 
            WAIT:next_state=ack?S0:WAIT;
            default:next_state=S0;
        endcase
    end
    
    //为改变在组合逻辑中给delay[]赋值出现的latch
    always@(posedge clk)begin
        if((state==D0)|(state==D1)|(state==D2)|(state==D3))
            delay<={delay[2:0],data};
    end
    
    assign full=(cnt==(delay+1)*1000);//需要计数的周期数
  
    wire cnt_start,cnt_end;
    assign cnt_start=(next_state==COUNT);
    //assign cnt_end=(cnt==(delay+1)*1000);
    assign cnt_end=(next_state==WAIT);
    always@(posedge clk)begin
        if(reset)
            cnt<=16'd0;
        else if(cnt_start)begin
            cnt<=cnt+1'b1; 
        end
        else if(cnt_end)begin
            cnt<=16'd0; 
        end
    end

    always@(*)begin
        if(cnt<=1000) count=delay;
        else if(cnt>1000&&cnt<=2000) count=delay-4'd1;
        else if(cnt>2000&&cnt<=3000) count=delay-4'd2;
        else if(cnt>3000&&cnt<=4000) count=delay-4'd3;
        else if(cnt>4000&&cnt<=5000) count=delay-4'd4;
        else if(cnt>5000&&cnt<=6000) count=delay-4'd5;
        else if(cnt>6000&&cnt<=7000) count=delay-4'd6;
        else if(cnt>7000&&cnt<=8000) count=delay-4'd7;
        else if(cnt>8000&&cnt<=9000) count=delay-4'd8;
        else if(cnt>9000&&cnt<=10000) count=delay-4'd9;
        else if(cnt>10000&&cnt<=11000) count=delay-4'd10;
        else if(cnt>11000&&cnt<=12000) count=delay-4'd11;
        else if(cnt>12000&&cnt<=13000) count=delay-4'd12;
        else if(cnt>13000&&cnt<=14000) count=delay-4'd13;
        else if(cnt>14000&&cnt<=15000) count=delay-4'd14;
        else  count=delay-4'd15;
    end
    
    assign counting=(state==COUNT);
    assign done=(state==WAIT);
endmodule

7.Exams/review2015 fsmonehot

  给定以下具有3个输入、3个输出和10个状态的状态机:
在这里插入图片描述

  假设使用以下 one-hot 编码,通过检查导出下一状态逻辑方程和输出逻辑方程: (S, S1, S11, S110, B0, B1, B2, B3, Count, Wait) = (10’b0000000001, 10 'b0000000010, 10’b0000000100, … , 10’b1000000000)
  假设 one-hot 编码,通过检查导出状态转换和输出逻辑方程。 仅实现此状态机的状态转换逻辑和输出逻辑(组合逻辑部分)。 (测试台将使用非一个热输入进行测试,以确保您不会尝试做更复杂的事情)。

编写生成以下等式的代码:
  B3_next – next-state logic for state B1
  S_next
  S1_next
  Count_next
  Wait_next
  done – output logic
  counting
  shift_ena

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[S110]&~d)|(state[Wait]&ack)|(state[S1]&~d);
    assign S1_next=(state[S]&d);
    assign Count_next=(state[Count]&~done_counting)|(state[B3]);
    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]);

endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值