赞
踩
目录
3.3.1 Counter with period 1000(Exams/review2015 count1k)
3.3.2 4-bit shift register and down counter(Exams/review2015 shiftcount)
3.3.3 FSM:Sequence 1101 recognizer(Exams/review2015 fsmseq)
3.3.4 FSM:Enable shift register(Exams/review2015 fsmshift)
3.3.5 FSM:The complete FSM(Exams/review2015 fsm)
3.3.6 The complete timer(Exams/review2015 fancytimer)
3.3.7 FSM:One-hot logic equations(Exams/review2015 fsmonehot)
HDLbits网站如下
Problem sets - HDLBits (01xz.net)
从本期开始我们继续HDLbits第三章Circuits的学习,本期的内容是Building larger circuits(3.3.1-3.3.7)
构建一个计数范围为0到999(含0到999)的计数器,周期为1000个周期。复位输入是同步的,应将计数器重置为0。
- module top_module (
- input clk,
- input reset,
- output [9:0] q);
- always@(posedge clk) begin
- if(reset)
- q<=10'd0;
- else if(q==10'd999)
- q<=10'd0;
- else
- q<=q+10'd1;
- end
-
- endmodule
这是一系列五个练习的第一部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise。
构建一个四位移位寄存器,它也可以作为下行(递减)计数器。当shift_ena为1时,data向最高有效位移位即左移。当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(shift_ena)
- q<={q[2:0],data};
- else if(count_ena)
- q<=q-1;
- end
-
- endmodule
这是一系列五个练习的第二部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise。
构建一个在输入比特流中搜索序列1101的有限状态机。找到序列后,应将start_shifting设置为1,直到复位。保持最终状态是为了在一个尚未实施的更大的FSM中模拟前往其他状态。我们将在接下来的几个练习中扩展此FSM。
- module top_module (
- input clk,
- input reset, // Synchronous reset
- input data,
- output start_shifting);
- parameter s0=0,s1=1,s11=2,s110=3,s1101=4;
- reg [2:0]state,next;
-
- always@(posedge clk) begin
- if(reset)
- state<=0;
- else
- state<=next;
- end
-
- always@(*) begin
- case(state)
- s0:next=data?s1:s0;
- s1:next=data?s11:s0;
- s11:next=data?s11:s110;
- s110:next=data?s1101:s0;
- s1101:next=s1101;
- endcase
- end
-
- assign start_shifting=(state==s1101);
-
- endmodule
这是一系列五个练习的第三部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise。
作为用于控制移位寄存器的FSM的一部分,我们希望能够在检测到正确的位模式时,使移位寄存器能够精确地工作4个时钟周期。我们在3.3.3中处理序列检测,因此FSM的这部分仅处理移位寄存器的4个周期启用。
无论何时复位FSM,都要将shift_ena有效4个周期,然后永远为0(直到复位)。
- module top_module (
- input clk,
- input reset, // Synchronous reset
- output shift_ena);
- reg [2:0]cnt;
- always@(posedge clk) begin
- if(reset)
- cnt<=0;
- else if(cnt<=3)
- cnt<=cnt+1;
- else
- cnt<=cnt;
- end
-
- always@(*) begin
- if(cnt==4)
- shift_ena=0;
- else
- shift_ena=1;
- end
-
- endmodule
这是一系列五个练习的第四部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise。
我们想创建一个计时器:
在这个问题中,只实现控制计时器的FSM。这里不包括数据路径(计数器和一些比较器)。
串行数据在数据输入引脚上可用。当接收到序列1101时,状态机必须在整整4个时钟周期内使shift_ena有效。
之后,状态机使其计数输出有效,以指示它正在等待计数器,并等待直到输入done_counting为高。
此时,状态机必须断言done以通知用户计时器已超时,并等待直到输入 ack为1,然后再复位,以查找启动序列的下一次出现(1101)。
状态机应复位为开始搜索输入序列1101的状态。
以下是预期输入和输出的示例。“x”状态读起来可能有点混乱。它们表明FSM不应该关心该周期中的特定输入信号。例如,一旦检测到1101模式,FSM将不再查看数据输入,直到完成所有其他操作后恢复搜索。
Hint:
- module top_module (
- input clk,
- input reset, // Synchronous reset
- input data,
- output shift_ena,
- output counting,
- input done_counting,
- output done,
- input ack );
- parameter s=0,s1=1,s11=2,s110=3,shift=5,count=6,idle=7;
- reg [2:0]state,next;
- reg [2:0]cnt;
-
- always@(*) begin
- case(state)
- s:next=data?s1:s;
- s1:next=data?s11:s;
- s11:next=data?s11:s110;
- s110:next=data?shift:s;
- shift:next=(cnt<3)?shift:count;
- count:next=done_counting?idle:count;
- idle:next=ack?s:idle;
- endcase
- end
-
- always@(posedge clk) begin
- if(reset)
- state<=s;
- else
- state<=next;
- end
-
- always@(posedge clk) begin
- case(state)
- s110:cnt<=0;
- shift:cnt<=cnt+1;
- endcase
- end
-
- assign shift_ena = (state==shift);
- assign counting = (state==count);
- assign done = (state==idle);
-
- endmodule
这是一系列五个练习的第五部分,这些练习用几个较小的电路构建复杂的计数器。
我们想创建一个计时器:
串行数据在data输入引脚上可用。当接收到序列1101时,电路必须在接下来的4位中移位,最高有效位首先移位。这4位决定计时器延迟的持续时间。我称之为delay[3:0]。
之后,状态机使其counting输出有效,以指示其正在计数。状态机必须精确计数(delay[3:0]+1)*1000个时钟周期。 例如,delay=0表示计数1000个周期,delay=5表示计数6000个周期。同时输出当前剩余时间。这等价于delay对应1000个周期,delay-1对应1000个周期,依此类推,直到0对应1000个周期。当电路不计数时,count[3:0]输出是dont-care(无论什么值便于实现)。
此时,电路必须断言done,以通知用户计时器已超时,并等待输入ack为1,然后再复位,以查找下一次出现的启动序列(1101)。
电路应复位至开始搜索输入序列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 idle=0,s1=1,s11=2,s110=3,shift=4,timer=5,wait_=6;
-
- reg[2:0]state,next;
-
- always@(*) begin
- case(state)
- idle:next=data?s1:idle;
- s1:next=data?s11:idle;
- s11:next=data?s11:s110;
- s110:next=data?shift:idle;
- shift:next=(shift_cnt==3)?timer:shift;
- timer:next=(timer_cnt==(delay+1)*1000-1)?wait_:timer;
- wait_:next=ack?idle:wait_;
- endcase
- end
-
- always@(posedge clk) begin
- if(reset)
- state<=idle;
- else
- state<=next;
- end
-
- reg[3:0]delay;
- always@(posedge clk) begin
- if(reset)
- delay<=4'b0;
- else if(state==shift)
- delay<={delay[2:0],data};
- else
- delay<=delay;
- end
-
- reg[1:0]shift_cnt;
- always@(posedge clk) begin
- if(reset)
- shift_cnt<=0;
- else if(state==shift&&shift_cnt<2'd3)
- shift_cnt<=shift_cnt+2'd1;
- else
- shift_cnt<=0;
- end
-
- reg[15:0]timer_cnt;
- always@(posedge clk) begin
- if(reset)
- timer_cnt<=16'd0;
- else if(state==timer&&timer_cnt<((delay+1)*1000-1))
- timer_cnt<=timer_cnt+16'd1;
- else
- timer_cnt<=16'd0;
- end
-
- reg[10:0]cnt_1k;
- reg[3:0]num_1k;
-
- always@(posedge clk) begin
- if(reset)
- cnt_1k<=11'd0;
- else if(state==timer&&cnt_1k!=11'd999)
- cnt_1k<=cnt_1k+11'd1;
- else
- cnt_1k<=11'd0;
- end
-
- always@(posedge clk) begin
- if(reset)
- num_1k<=4'd0;
- else if(cnt_1k==11'd999)
- num_1k<=num_1k+1'b1;
- else if(state==timer)
- num_1k<=num_1k;
- else
- num_1k<=4'd0;
- end
-
- assign counting=(state==timer);
- assign done=(state==wait_);
- assign count=(state==timer)?(delay-num_1k):4'b0;
-
- endmodule
给定以下具有3个输入、3个输出和10个状态的状态机:
假设使用以下独热码,通过检查推导next_state态逻辑方程和output逻辑方程:(S、S1、S11、S110、B0、B1、B2、B3、Count、Wait)=(10'b0000000001、10'b0000000010、10'b0000000100、…、10'b1000000000)
编写生成以下方程式的代码:
- 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
- ); //
-
- parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
- reg[9:0]next;
-
- always@(*) begin
- next[S]=(state[S]&&~d)||(state[S1]&&~d)||(state[S110]&&~d)||(state[Wait]&&ack);
- next[S1]=state[S]&&d;
- next[S11]=state[S1]&&d;
- next[S110]=state[S11]&&~d;
- next[B0]=state[S110]&&d;
- next[B1]=state[B0];
- next[B2]=state[B1];
- next[B3]=state[B2];
- next[Count]=state[B3]||state[Count]&&~(done_counting);
- next[Wait]=state[Count]&&done_counting||state[Wait]&&~ack;
- end
-
- assign B3_next=next[B3];
- assign S_next=next[S];
- assign S1_next=next[S1];
- assign Count_next=next[Count];
- assign Wait_next=next[Wait];
-
- assign done=state[Wait];
- assign counting=state[Count];
- assign shift_ena=state[B0]||state[B1]||state[B2]||state[B3];
-
- endmodule
3.3.6分解成小任务就没有那么难了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。