基本知识:

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的更多相关文章

  1. 模电&数电知识整理(不定期更新)

    模电总复习之爱课堂题目概念整理 Chapter 1 1) 设室温情况下某二极管的反偏电压绝对值为1V,则当其反偏电压值减少100mV时,反向电流的变化是基本不发生变化. 2) 二极管发生击穿后,在击穿 ...

  2. 数电课设——琐碎

    这几天没有更新过网站了,也没继续开发VellLock了,可是感觉还是没有闲着,一直在跟下面的一些元器件在打交道,当然下面的都是小儿科,英文文档都看得我快吐血了.数电基本属于棺材边上过的我,是各种头大, ...

  3. java第二周周学习总结

    java运算符和循环 java运算符 一.for 语句 for 语句的基本结构如下所示:for(初始化表达式;判断表达式;递增(递减)表达式){    执行语句;   //一段代码} 初始化表达式:初 ...

  4. web前端笔记整理,从入门到上天,周周更新

    由于大前端知识点太多,所以一一做了分类整理,详情可见本人博客 http://www.cnblogs.com/luxiaoyao/ 一.HTML 1.注释 格式:<!-- 注释内容 --> ...

  5. 数电基础之《OC门》

    OC门,又称集电极开路门,Open Collector.   为什么引入OC门?实际使用中,有时需要两个或两个以上与非门的输出端连接在同一条导线上,将这些与非门上的数据(状态电平)用同一条导线输送出去 ...

  6. FPGA大公司面试笔试数电部分,看看你会多少

    1:什么是同步逻辑和异步逻辑?(汉王) 同步逻辑是时钟之间有固定的因果关系.异步逻辑是各时钟之间没有固定的因果关系. 答案应该与上面问题一致 [补充]:同步时序逻辑电路的特点:各触发器的时钟端全部连接 ...

  7. STM32f103的数电采集电路的DMA设计和使用优化程序

    DMA,全称为:Direct Memory Access,即直接存储器访问.DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直 ...

  8. 数电——全减器分析(用74HC138设计提示)

    -1=1(即Di=1). Di=(Y1' * Y2' * Y4' * Y7')'可以得到74HC138来表示,(注意:Ai,Bi,Ci-1的各自位权对应A2,A1,A0) Ci同理可得.

  9. STM32f103的数电采集电路的TIMER定时器的使用与时序控制的程序

    STM32 的通用定时器是一个通过可编程预分频器(PSC)驱动的 16 位自动装载计数器(CNT)构成.STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较 ...

  10. STM32f103的数电采集电路的双ADC的设计与使用

    STM32F103C8T6拥有3个ADC,其独立使用已经在本文的3.1.3里面有详细的介绍,这里主要是介绍双ADC的同时使用,即STM32的同步规则模式使用.在此模式在规则通道组上执行时,外部触发来自 ...

随机推荐

  1. 5.Ceph 基础篇 - 认证

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485272&idx=1&sn=4b27c357 ...

  2. es根据关键词查看某个指定索引的内容并删除

    # 根据关键词查询某个索引的内容 GET product/_search?q=title:测试商品 {"query":{"match_all":{}}} # 根 ...

  3. Docker 容器默认root账号运行,很不安全!

    文章转载自:https://mp.weixin.qq.com/s/AeZoEKZBWFYwyhgicpgD4Q

  4. haproxy + keeplived

    两台主机: 192.168.2.163 192.168.2.165 # yum安装haproxy yum install haproxy # cat /etc/haproxy/haproxy.cfg ...

  5. linux系统下查看某个进程内存使用量

  6. MongoDB 副本集的用户和权限一般操作步骤

    步骤总结: 在主节点上添加超管用户,副本集会自动同步 按照仲裁者.副本节点.主节点的先后顺序关闭所有节点服务 创建副本集认证的key文件,复制到每个服务所在目录 修改每个服务的配置文件,增加参数 启动 ...

  7. Netty 学习(五):服务端启动核心流程源码说明

    Netty 学习(五):服务端启动核心流程源码说明 作者: Grey 原文地址: 博客园:Netty 学习(五):服务端启动核心流程源码说明 CSDN:Netty 学习(五):服务端启动核心流程源码说 ...

  8. P7476 苦涩 题解

    Link 一道很好的复杂度均摊题目. 只需要考虑删除操作时的时间复杂度.保证复杂度的重点之一是精确定位到所有包含最大值的区间,即不去碰多余的区间.每次删除操作会删除若干个整个区间,以及至多两个区间被删 ...

  9. 18-基于CentOS7搭建RabbitMQ3.10.7集群镜像队列+HaProxy+Keepalived高可用架构

    集群架构 虚拟机规划 IP hostname 节点说明 端口 控制台地址 192.168.247.150 rabbitmq.master rabbitmq master 5672 http://192 ...

  10. [题解] Codeforces Dytechlab Cup 2022 1737 A B C D E 题解

    傻*Dytechlab还我rating!(不过目前rating还没加上去,据说E是偷的说不定要unrated) 实在没预料到会打成这样... 求点赞 点我看题 A. Ela Sorting Books ...