数电第8周周结_by_yc
基本知识:
1、有限状态机的分类:
- Moore型:输出仅与电路的状态有关;
- Mealy型:输出与当前电路状态和当前电路输入有关。
2、有限状态机的描述方法:
状态转换图:节点:状态(Moore输出);
边:由一个状态转换为另一个状态的对应输入(Mealy)算法状态机:类似于流程图。
3、设计步骤:
- S1、定类型;
- S2、列状态+编码;
- S3、画状态转换图;
- S4、代码语言描述
4、状态转移图检查:
- 完备性;
- 互斥性。
设计案例:序列检测器
功能描述:设计一个“1101”的序列检测器,设\(d_{in}\)为数子码流输入,\(s_{out}\)为检出标记输出,高电平表示发现指定序列,低电平表示没有发现指令序列
A.Moore型
状态+编码:
S0:未检测到‘1’
S1:检测到输入序列‘1’
S2:检测到输入序列‘11’
S3:检测到输入序列‘110’
S4:检测到输入序列‘1101’
共计5个状态,需要声明位宽为3的状态寄存器*2.状态转移图:

- 代码语言描述:
module seqdet
#(parameter s0=3'b000,
parameter s1=3'b001,
parameter s2=3'b010,
parameter s3=3'b011,
parameter s4=3'b100)
(input clk, reset, din,
output reg sout);
reg [2:0] cur_state, next_state;
always@(posedge clk) begin
if(reset) cur_state <= s0;
else cur_state <= next_state;
end
always@(din, cur_state) begin
case(cur_state)
s0: begin
if(din==1'b1) next_state=s1;
else next_state=s0;
end
s1: begin
if(din==1'b1) next_state=s2;
else next_state=s0;
end
s2: begin
if(din==1'b1) next_state=s2;
else next_state=s3;
end
s3: begin
if(din==1'b1) next_state=s4;
else next_state=s0;
end
s4: begin
if(din==1'b1) next_state=s2;
else next_state=s0;
end
endcase
end
always@(cur_state) begin
if(reset) sout=1'b0;
else if(cur_state==s4) sout=1'b1;
else sout=1'b0;
end
endmodule
B.Mealy型
状态+编码:
由于Mealy型在边上即可进行输入,故无需S4状态:
S0:未检测到‘1’
S1:检测到输入序列‘1’
S2:检测到输入序列‘11’
S3:检测到输入序列‘110’
共计4个状态,需要声明位宽为2的状态寄存器*2.状态转移图:

- 代码语言描述:
module seqdet
#(parameter s0=2'b00,
parameter s1=2'b01,
parameter s2=2'b10,
parameter s3=2'b11)
(input clk, reset, din,
output reg sout);
reg [2:0] cur_state, next_state;
always@(posedge clk) begin
if(reset) cur_state <= s0;
else cur_state <= next_state;
end
always@(cur_state, din) begin
case(cur_state)
s0: begin
if(din==1'b1) next_state=s1;
else next_state=s0;
end
s1: begin
if(din==1'b1) next_state=s2;
else next_state=s0;
end
s2: begin
if(din==1'b1) next_state=s2;
else next_state=s3;
end
s3: begin
if(din==1'b1) next_state=s1;
else next_state=s0;
end
endcase
end
always@(posedge clk) begin
if(reset) sout=1'b0;
else if(cur_state==s3 && din) sout=1'b1;
else sout=1'b0;
end
endmodule
Lab4_有限状态机
一、FSM1--混合输出状态机:
- 功能描述:
依据状态转移图,设计有限状态机,要求采用二段式或三段式描述方法。

- 设计方案:
①定类型:Mealy型和Moore型均需实现;
②状态编码:由状态转移图可知:共有四种状态,可进行编码如下:
#(parameter s0=2'b00,
parameter s1=2'b01,
parameter s2=2'b10,
parameter s3=2'b11)
③无需再画状态转移图,已经给出;
- 关键代码:
always@(posedge clk) begin
if(!rst_n) cur_state <= s0;
else cur_state <= next_state;
end
always@(cur_state, in) begin
case(cur_state)
s0: begin
if(in==1'b1) next_state=s2;
else next_state=s0;
end
s1: begin
if(in==1'b1) next_state=s1;
else next_state=s0;
end
s2: begin
if(in==1'b1) next_state=s3;
else next_state=s0;
end
s3: begin
if(in==1'b1) next_state=s1;
else next_state=s0;
end
endcase
end
always@(cur_state) begin //Moore
if(!rst_n) o_moore=1'b0;
else if(cur_state==s1) o_moore=1'b1;
else o_moore=1'b0;
end
always@(cur_state, in) begin //Mealy
if(!rst_n) o_mealy=1'b0;
else if(cur_state!=s0 && in==1'b0) o_mealy=1'b1;
else o_mealy=1'b0;
end
- 仿真验证:
依据给出的波形图,编写testbench如下:

initial begin
clk=0;
forever #10 clk=~clk;
end
initial begin
rst_n=0; in=1;
#20 rst_n=1; in=1;
#60 in=0;
#20 in=1;
#20 in=0;
#20 in=1;
#40 in=0;
#20 in=1;
#40 in=0;
#20 in=1;
#40 in=0;
#20 in=1;
#80 in=0;
#20 in=1;
#20 in=0;
#20 in=1;
#20 in=0;
#20 in=1;
#20 in=0;
#100 $stop;
end
得到的仿真波形图如下图所示,与给出的设定波形相符,符合题意。

- 综合结果:

- 总结反思:
由于Mealy型和Moore型的触发条件不同,所以不应放在同一个always块中。
二、FSM2——序列检测器(01101):
功能描述:
分别使用Moore和Mealy型有限状态机设计“01101”的序列检测器,要求使用二段式或三段式描述方法。设计方案:
A.Moore型:
①定类型:Moore型;
②状态编码:共有六种状态,可进行编码如下:
#(parameter s0=3'b000,
parameter s1=3'b001,
parameter s2=3'b010,
parameter s3=3'b011,
parameter s4=3'b100,
parameter s5=3'b101)
③画出状态转移图如下;

- 关键代码:
always@(posedge clk, rstn) begin
if(!rstn) cur_state <= s0;
else cur_state <= next_state;
end
always@(cur_state, data) begin
case(cur_state)
s0: begin
if(data==1'b1) next_state=s0;
else next_state=s1;
end
s1: begin
if(data==1'b1) next_state=s2;
else next_state=s1;
end
s2: begin
if(data==1'b1) next_state=s3;
else next_state=s1;
end
s3: begin
if(data==1'b1) next_state=s0;
else next_state=s4;
end
s4: begin
if(data==1'b1) next_state=s5;
else next_state=s1;
end
s5: begin
if(data==1'b1) next_state=s3;
else next_state=s0;
end
default: next_state=s0;
endcase
end
always@(cur_state) begin
if(!rstn) out_moore=1'b0;
else if(cur_state==s5) out_moore=1'b1;
else out_moore=1'b0;
end
- 仿真验证:
编写testbench如下:
initial begin
clk=0;
forever #10 clk=~clk;
end
initial begin
rstn=0; data=1;
#20 rstn=1;
#40 data=0;
#20 data=1;
#60 data=0;
#40 data=1;
#20 data=0;
#20 data=1;
#40 data=0;
#20 data=1;
#40 data=0;
#20 data=1;
#20 data=0;
#30 $stop;
end
得到的仿真波形图如下图所示,与给出的设定波形相符,符合题意。

- 综合结果:

相应的生成的状态转移图为:

B.Mealy型:
①定类型:Mealy型;
②状态编码:共有五种状态,可进行编码如下:
#(parameter s0=3'b000,
parameter s1=3'b001,
parameter s2=3'b010,
parameter s3=3'b011,
parameter s4=3'b100)
③画出状态转移图如下;

- 关键代码:
always@(posedge clk, rstn) begin
if(!rstn) cur_state <= s0;
else cur_state <= next_state;
end
always@(cur_state, data) begin
case(cur_state)
s0: begin
if(data==1'b1) next_state=s0;
else next_state=s1;
end
s1: begin
if(data==1'b1) next_state=s2;
else next_state=s1;
end
s2: begin
if(data==1'b1) next_state=s3;
else next_state=s1;
end
s3: begin
if(data==1'b1) next_state=s0;
else next_state=s4;
end
s4: begin
if(data==1'b1) next_state=s2;
else next_state=s1;
end
endcase
end
always@(cur_state, data) begin
if(!rstn) out_mealy=1'b0;
else if(cur_state==s4 && data==1) out_mealy=1'b1;
else out_mealy=1'b0;
end
- 仿真验证:
编写testbench如下:
initial begin
clk=0;
forever #10 clk=~clk;
end
initial begin
rstn=0; data=1;
#20 rstn=1;
#40 data=0;
#20 data=1;
#60 data=0;
#40 data=1;
#20 data=0;
#20 data=1;
#40 data=0;
#20 data=1;
#40 data=0;
#20 data=1;
#20 data=0;
#30 $stop;
end
得到的仿真波形图如下图所示,与给出的设定波形相符,符合题意。

- 综合结果:

相应地生成的状态转移图如下:

三、FSM4--序列接收器:
- 功能描述:
在某些串行通信协议中,每个数据字节与一个起始位和一个停止位一起发送,以帮助接收器从比特流中划分字节。一种常见的方案是使用一个起始位(0)、8个数据位和1个停止位(1)。当无任何传输(空闲)时,线路也处于逻辑1。
设计一个有限状态机,当给定一个比特流时,它将识别字节何时已经被正确的接收到。它需要识别起始位,等待所有8个数据位,然后验证停止位是否正确。如果停止位正确,那么输出该循环内所接收到的8位数据(注意,数据到达的顺序是从低位到高位),其他时间内输出数据为零;如果停止位未按预期出现,则FSM必须等到找到停止位后再尝试接收下一个字节(该输入无效)。
- 设计方案:
①定类型:Moore型;
②状态编码:
#(parameter IDLE = 3'b000,
parameter START= 3'b001,
parameter HOLD = 3'b010,
parameter STOP = 3'b011,
parameter MISS = 3'b100)
③当处于IDLE状态时,此时若输入1,则继续循环IDLE状态;若输入0,则进入START状态,开始接收数据;
当处于START状态时,此时无论输入任何数据都会在下一步进入HOLD状态;
当处于HOLD状态时,每次在上升沿循环进入此状态时加一,当输入为1时,做出以下判断:
若cnt<7,则继续HOLD;
若cnt=7,则下一STOP,cnt置零;
若cnt>7,则下一MISS,cnt置零;
当处于STOP状态时,输出done=1,以及输出序列,此时若输入为0,则进入START,此时若输入为1,则进入IDLE;
当处于MISS状态时,若输入为0,则进入MISS,若输入为1,则进入IDLE。
据此可以做出状态转移图如下:

- 关键代码:
always@(posedge clk) begin
if(reset) cur_state <= IDLE;
else begin
if(cur_state==HOLD && cnt!=8)
cnt<=cnt+1;
else if(cur_state==STOP||cur_state==MISS)
cnt<=0;
else cnt<=cnt;
cur_state <= next_state;
num_reg[cnt+1]=in;
end
end
always@(cur_state, in, cnt) begin
case(cur_state)
IDLE: begin
if(in==1'b0) next_state=START;
else next_state=IDLE;
end
START: next_state=HOLD;
HOLD: begin
if((cnt==7) && (in==1'b1)) begin next_state=STOP; end
else if((cnt==7) && (in==1'b0)) begin next_state=MISS; end
else begin next_state=HOLD; end
end
STOP: begin
if(in==1'b1) next_state=IDLE;
else next_state=START;
end
MISS: begin
if(in==1'b1) next_state=IDLE;
else next_state=MISS;
end
default: next_state=IDLE;
endcase
end
//assign done=(cur_state==STOP);
//assign out_byte=(cur_state==STOP?num_reg:8'b0);
always@(cur_state) begin
if(reset) begin done=1'b0; out_byte=8'b0; end
else if(cur_state==STOP) begin done=1'b1; out_byte=num_reg; end
else begin done=1'b0; out_byte=8'b0; end
end
- 仿真验证:
根据给出的波形图,编写 testbench如下:

initial begin
clk=1;
forever #10 clk=~clk;
end
initial begin
reset=1; in=0;
#10 reset=0;
#80 in=1;
#20 in=0;
#20 in=1;
#40 in=0;
#20 in=1;
#20 in=0;
#40 in=1;
#20 in=0;
#60 in=1;
#20 in=0;
#20 in=1;
#20 in=0;
#60 in=1;
#20 in=0;
#40 in=1;
#20 in=0;
#60 in=1;
#20 in=0;
#20 in=1;
#40 in=0;
#20 $stop;
end
得到的仿真波形图如下,符合题意:

- 综合结果:

相应生成的状态转移图如下:

- 总结反思:
注意区分各个变量的触发条件!不要混在一起写!!
四、FSM6--表达式状态机-允许括号:
- 功能描述:
1、表达式F中只含有数字0-9,加号"+",乘号"*",半角括号"("和")"。
2、表达式F可以按如下的规则产生:
a. 单个数字[0-9]是F;
b. 如果X是F,Y是F,则X+Y也是F;
c. 如果X是F,Y是F,则X*Y也是F。
d. 如果X是F,且X中不含括号,那么(X)也是F。
每个时钟上升沿,状态机从in中读入一个ASCII编码的字符。假设读入的第i个字符为\({(c_i)}\),则第n个时钟上升沿时,可以拼出一个字符串: \([s=c_1 c_2....c_n]\)我们需要你在此时判断s是否符合表达式F的定义。假如\(s\)符合F的定义,那么\(out\)应输出1,否则输出0;
另外,每个clr上升沿时,请清零状态;如果clk的上升沿时clr为1,也需要清零状态。清零后,上面定义的字符串\((s)\)也应从空串开始计算。如果\((s)\)当前是空串,out也应输出0。
- 设计方案:
①定类型:Moore型;
②状态编码:
#(parameter NULL =3'b000,
parameter NUM =3'b001,
parameter BRACKET =3'b010,
parameter OPERATOR =3'b011,
parameter LEGAL =3'b100,
parameter ILLEGAL =3'b101)
③当处于NULL状态时,此时若输入数字,则NUM状态;若输入运算符,则ILLEGAL;若输入左括号,则BRACKET;若输入右括号,则ILLEGAL;
当处于NUM状态时,若输入数字,则ILLEGAL;若输入运算符,则ILLEGAL;若输入左括号,则ILLEGAL;若输入右括号,如与前面匹配,则LEGAL,否则ILLEGAL;
当处于BRACKET状态时,若输入数字,则NUM;若输入运算符或括号,则ILLEGAL;
当处于OPERATOR状态时,若输入数字,则NUM;若输入运算符,则ILLEGAL;若输入左括号,如前面括号均已匹配,则BRACKET,否则ILLEGAL;若输入右括号,则ILLEGAL;
当处于LEGAL状态时,若输入数字,则NUM;若输入运算符,则OPERATOR;若输入左括号,则BRACKET;若输入右括号,则ILLEGAL;
当处于ILLEGAL状态时,则ILLEGAL.
- 关键代码:
always@(posedge clk) begin
if(clr) begin
cur_state<=NULL;
flag<=1'b1;
end
else begin
if(next_state==BRACKET)
flag<=1'b0;
else if(next_state==LEGAL)
flag<=1'b1;
else
flag<=flag;
cur_state<=next_state;
end
end
always@(in, cur_state) begin
case(cur_state)
NULL: begin
if(isnum(in)) next_state=NUM;
else if(isop(in)) next_state=ILLEGAL;
else if(in==8'h28) begin
if(flag==1) next_state=BRACKET;
else next_state=ILLEGAL;
end
else if(in==8'h29) next_state=ILLEGAL;
else next_state=ILLEGAL;
end
NUM: begin
if(isnum(in)) next_state=ILLEGAL;
else if(isop(in)) next_state=OPERATOR;
else if(in==8'h28) next_state=ILLEGAL;
else if(in==8'h29) begin
if(flag==0) next_state=LEGAL;
else next_state=ILLEGAL;
end
else next_state=ILLEGAL;
end
BRACKET: begin
if(isnum(in)) next_state=NUM;
else if(isop(in)) next_state=ILLEGAL;
else if(in==8'h28) next_state=ILLEGAL;
else if(in==8'h29) next_state=ILLEGAL;
else next_state=ILLEGAL;
end
OPERATOR: begin
if(isnum(in)) next_state=NUM;
else if(isop(in)) next_state=ILLEGAL;
else if(in==8'h28) begin
if(flag==1) next_state=BRACKET;
else next_state=ILLEGAL;
end
else if(in==8'h29) next_state=ILLEGAL;
else next_state=ILLEGAL;
end
LEGAL: begin
if(isnum(in)) next_state=NUM;
else if(isop(in)) next_state=OPERATOR;
else if(in==8'h28) next_state=BRACKET;
else if(in==8'h29) next_state=ILLEGAL;
else next_state=ILLEGAL;
end
ILLEGAL:/*begin
if(isnum(in)) next_state=NUM;
else if(isop(in)) next_state=ILLEGAL;
else if(in==8'h28) begin
if(flag==1) next_state=BRACKET;
else next_state=ILLEGAL;
else if(in==8'h29) next_state=ILLEGAL;
*/
next_state=ILLEGAL;
default: next_state=NULL;
endcase
end
always@(cur_state) begin
if(clr) out=1'b0;
else if((cur_state==LEGAL)||((cur_state==NUM)&&(flag==1'b1))) out=1'b1;
else out=1'b0;
end
- 仿真验证:
根据给出的波形图,编写 testbench如下:
initial begin
clk=0;
forever #10 clk=~clk;
end
initial begin
in="1";
#20 in="+";
#20 in="(";
#20 in="1";
#20 in="+";
#20 in="2";
#20 in=")";
#20 in="*";
#20 in="(";
#20 in="3";
#20 in="+";
#20 in="1";
#20 in=")";
#40 $stop;
/*in="(";
#20 in="1";
#20 in=")";
#20 in="+";
#20 in="(";
#20 in="2";
#20 in=")";
#20 in="(";
#20 in="1";
#20 in="*";
#20 in="2";
#20 in=")";
#20 in="(";
#20 in="1";
#20 in=")";
#20 in="+";
#20 in="(";
#20 in="2";
#20 in=")";
#20 in="*";
#20 in="(";
#20 in="1";
#20 in="*";
#20 in="2";
#20 in=")";
#40 in="1";
#20 in="+";
#20 in="2";
#20 in="+";
#40 in="5";
#40 in="1";
#20 in="2";
#20 in="+";
#20 in="5";
#80 $stop;*/
end
initial begin
clr=1'b0;
/*#230 clr=1'b1;
#10 clr=1'b0;
#270 clr=1'b1;
#10 clr=1'b0;
#130 clr=1'b1;
#10 clr=1'b0;
#140 $stop;*/
end
得到的仿真波形图如下,符合题意:


- 综合结果:

相应生成的状态转移图如下:

- 总结反思:
注意初始化!!
消除LATCH:
- \(if-else\)语句写完整;
- \(case\)语句写好\(default\);
- 变量赋初值;
- 区分组合逻辑与时序逻辑,不要把变量混着放。
数电第8周周结_by_yc的更多相关文章
- 模电&数电知识整理(不定期更新)
模电总复习之爱课堂题目概念整理 Chapter 1 1) 设室温情况下某二极管的反偏电压绝对值为1V,则当其反偏电压值减少100mV时,反向电流的变化是基本不发生变化. 2) 二极管发生击穿后,在击穿 ...
- 数电课设——琐碎
这几天没有更新过网站了,也没继续开发VellLock了,可是感觉还是没有闲着,一直在跟下面的一些元器件在打交道,当然下面的都是小儿科,英文文档都看得我快吐血了.数电基本属于棺材边上过的我,是各种头大, ...
- java第二周周学习总结
java运算符和循环 java运算符 一.for 语句 for 语句的基本结构如下所示:for(初始化表达式;判断表达式;递增(递减)表达式){ 执行语句; //一段代码} 初始化表达式:初 ...
- web前端笔记整理,从入门到上天,周周更新
由于大前端知识点太多,所以一一做了分类整理,详情可见本人博客 http://www.cnblogs.com/luxiaoyao/ 一.HTML 1.注释 格式:<!-- 注释内容 --> ...
- 数电基础之《OC门》
OC门,又称集电极开路门,Open Collector. 为什么引入OC门?实际使用中,有时需要两个或两个以上与非门的输出端连接在同一条导线上,将这些与非门上的数据(状态电平)用同一条导线输送出去 ...
- FPGA大公司面试笔试数电部分,看看你会多少
1:什么是同步逻辑和异步逻辑?(汉王) 同步逻辑是时钟之间有固定的因果关系.异步逻辑是各时钟之间没有固定的因果关系. 答案应该与上面问题一致 [补充]:同步时序逻辑电路的特点:各触发器的时钟端全部连接 ...
- STM32f103的数电采集电路的DMA设计和使用优化程序
DMA,全称为:Direct Memory Access,即直接存储器访问.DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直 ...
- 数电——全减器分析(用74HC138设计提示)
-1=1(即Di=1). Di=(Y1' * Y2' * Y4' * Y7')'可以得到74HC138来表示,(注意:Ai,Bi,Ci-1的各自位权对应A2,A1,A0) Ci同理可得.
- STM32f103的数电采集电路的TIMER定时器的使用与时序控制的程序
STM32 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成.STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较 ...
- STM32f103的数电采集电路的双ADC的设计与使用
STM32F103C8T6拥有3个ADC,其独立使用已经在本文的3.1.3里面有详细的介绍,这里主要是介绍双ADC的同时使用,即STM32的同步规则模式使用.在此模式在规则通道组上执行时,外部触发来自 ...
随机推荐
- SDN实验环境安装配置
- Java SE 19 新增特性
Java SE 19 新增特性 作者:Grey 原文地址: 博客园:Java SE 19 新增特性 CSDN:Java SE 19 新增特性 源码 源仓库: Github:java_new_featu ...
- VUE:引入腾讯地图并实现轨迹动画
腾讯位置服务JavaScript API 效果: 引入步骤: 在 html 中通过引入 script 标签加载API服务 在一个盒子元素 div 中预先准备地图容器,并在CSS样式中定义地图(容器)显 ...
- 发布日志 - kratos v2.1.0 版本发布
github https://github.com/go-kratos/kratos/releases/tag/v2.1.0 新的功能 新增客户端负载均衡器(load balancing)和路由选择器 ...
- logstash中output{}的另类写法
日志传输路径如下: filebeat->redis->logstash->es 在filebeat配置文件中,收集日志的时候配置的有如下参数: fields: log_source: ...
- typora基础和计算机五大组成部分
typora typora软件 是一款适合于IT行业文本编辑器,笔记,当下来说,非常火爆,可以使用多种语言,python java... 安装的时候路径选择可以设置一些简单便于后续查找的文件路 ...
- zookeeper之安装
zookeeper之安装 一.准备条件 1.1 最低三个服务器(一主多从,1个leader,多个flower)1.2 将zookeeper安装包上传到集群并解压zookeeper 二.将conf目录下 ...
- MyBatis的各种查询功能
1.查询一个实体类对象 /** * 根据用户id查询用户信息 * @param id * @return */ User getUserById(@Param("id") int ...
- PHP cURL抓取网上图片
cURL的底层是由一个命令行工具实现的,用于获取远程文件或传输文件,更多的情况是用来模拟get/post表单提交.也可以用户文件上传,爬取文件,支持FTP/FTPS,HTTP/HTTPS等协议,通俗来 ...
- 【Firefox浏览器】关闭触摸板双指滑动进行前进后退的功能
痛点 本以为只是Chrome浏览器存在这一奇葩功能,没成想Firefox也沦陷了!有好一阵子在使用Firefox的时候,并未发现其存在这个功能.直到有一天,打开自己的博客,翻阅上篇< [Chro ...