目录

写在前面

Finite State Manchines

Fsm serialdata

Fsm serialdp

Fsm hdlc

Design a Mealy FSM

ece241 2014 q5a

ece241 2014 q5b

2014 q3fsm

2014 q3bfsm


写在前面

HDLBits 刷题来到了最为重要的一部分---有限状态机,都说 Verilog 设计的精髓就是状态机的设计,可见状态机设计的重要性,通过三十多道的状态机的练习,可以更加熟悉状态机设计的要点,通常都设计为三段式,这样设计的状态机层次清晰且易于设计,时序上更为易懂。以下的解题方法不一定为最佳解决方案,有更好的方法欢迎提出,共同学习,共同进步!

Finite State Manchines

Fsm serialdata

设计一个有限状态机,可以识别何时在串行比特流中正确接收字节,请添加一个数据路径,该数据路径将输出正确接收的数据字节。out_byte 在完成时需要有效,并且是1,否则就不在乎。

请注意,串行协议首先发送最低有效位。

module top_module(input         clk,input         in,input         reset,    // Synchronous resetoutput [7:0]  out_byte,output        done
);
//状态机状态申明
parameter  IDLE       =  12'b000000000001;
parameter  START      =  12'b000000000010;
parameter  BIT_ONE    =  12'b000000000100;
parameter  BIT_TWO    =  12'b000000001000;
parameter  BIT_THREE  =  12'b000000010000;
parameter  BIT_FOUR   =  12'b000000100000;
parameter  BIT_FIVE   =  12'b000001000000;
parameter  BIT_SIX    =  12'b000010000000;
parameter  BIT_SEVEN  =  12'b000100000000;
parameter  BIT_EIGHT  =  12'b001000000000;
parameter  STOP       =  12'b010000000000;
parameter  WAIT       =  12'b100000000000;reg  [11:0]   state;
reg  [11:0]   next_state;//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) beginif (reset) beginstate <= IDLE;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) beginnext_state = state;case(state)IDLE: beginif (~in) beginnext_state = START;endelse beginnext_state = IDLE;endendSTART: beginnext_state = BIT_ONE;endBIT_ONE: beginnext_state = BIT_TWO;endBIT_TWO: beginnext_state = BIT_THREE;endBIT_THREE:beginnext_state = BIT_FOUR;endBIT_FOUR: beginnext_state = BIT_FIVE;endBIT_FIVE: beginnext_state = BIT_SIX;endBIT_SIX: beginnext_state = BIT_SEVEN;endBIT_SEVEN: beginnext_state = BIT_EIGHT;endBIT_EIGHT: beginif (in) beginnext_state = STOP;endelse beginnext_state = WAIT;endendWAIT: beginif (in) beginnext_state = IDLE;endelse beginnext_state = WAIT;endendSTOP: beginif (in) beginnext_state = IDLE;endelse beginnext_state = START;end   enddefault: beginnext_state = IDLE;endendcase
end //状态机第三段,结果输出,组合逻辑
always @(posedge clk) beginif (reset) begindone     <= 'd0;out_byte <= 'd0;endelse begincase(next_state)IDLE: begindone     <= 'd0;out_byte <= 'd0;                endSTART: begindone     <= 'd0;out_byte <= 'd0;endBIT_ONE: begindone        <= 'd0;out_byte[0] <= in; endBIT_TWO: begindone        <= 'd0;out_byte[1] <= in; endBIT_THREE: begindone        <= 'd0;out_byte[2] <= in; endBIT_FOUR: begindone        <= 'd0;out_byte[3] <= in; endBIT_FIVE: begindone        <= 'd0;out_byte[4] <= in; endBIT_SIX: begindone        <= 'd0;out_byte[5] <= in; endBIT_SEVEN: begindone        <= 'd0;out_byte[6] <= in; endBIT_EIGHT: begindone        <= 'd0;out_byte[7] <= in; endWAIT: begindone     <= in;out_byte <= out_byte;endSTOP: begindone     <= 'd1;out_byte <= out_byte;enddefault: begindone     <= 'd0;out_byte <= 'd0;endendcaseend
endendmodule

Fsm serialdp

我们希望将奇偶校验添加到串行接收器。奇偶校验在每个数据字节后添加一个额外的位。我们将使用奇偶校验,其中接收的9位中的1s数必须是奇数。例如,101001011满足奇偶校验(有 5 个 1秒),但001001011则不满足奇偶校验。

更改 FSM 和数据路径以执行奇数奇偶校验。仅当正确接收到一个字节并且其奇偶校验通过时才置位完成的信号。喜欢串行接收器 FSM,此 FSM 需要识别起始位,等待所有 9 个(数据和奇偶校验)位,然后验证停止位是否正确。如果停止位未按预期出现,则 FSM 必须等到找到停止位后再尝试接收下一个字节。

为您提供了以下模块,可用于计算输入流的奇偶校验(它是具有重置功能的TFF)。预期用途是应为它提供输入位流,并在适当的时间重置,以便计算每个字节中的1位数。

module top_module(input         clk,input         in,input         reset,    // Synchronous resetoutput [7:0]  out_byte,output        done
);
//状态机状态申明
parameter  IDLE       =  13'b0000000000001;
parameter  START      =  13'b0000000000010;
parameter  BIT_ONE    =  13'b0000000000100;
parameter  BIT_TWO    =  13'b0000000001000;
parameter  BIT_THREE  =  13'b0000000010000;
parameter  BIT_FOUR   =  13'b0000000100000;
parameter  BIT_FIVE   =  13'b0000001000000;
parameter  BIT_SIX    =  13'b0000010000000;
parameter  BIT_SEVEN  =  13'b0000100000000;
parameter  BIT_EIGHT  =  13'b0001000000000;
parameter  PARITY_BIT =  13'b0010000000000;
parameter  STOP       =  13'b0100000000000;
parameter  WAIT       =  13'b1000000000000;reg  [12:0]   state;
reg  [12:0]   next_state;
reg           odd;//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) beginif (reset) beginstate <= IDLE;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) beginnext_state = state;case(state)IDLE: beginif (~in) beginnext_state = START;endelse beginnext_state = IDLE;endendSTART: beginnext_state = BIT_ONE;endBIT_ONE: beginnext_state = BIT_TWO;endBIT_TWO: beginnext_state = BIT_THREE;endBIT_THREE:beginnext_state = BIT_FOUR;endBIT_FOUR: beginnext_state = BIT_FIVE;endBIT_FIVE: beginnext_state = BIT_SIX;endBIT_SIX: beginnext_state = BIT_SEVEN;endBIT_SEVEN: beginnext_state = BIT_EIGHT;endBIT_EIGHT: beginnext_state = PARITY_BIT;endPARITY_BIT: beginif (in) beginnext_state = STOP;endelse beginnext_state = WAIT;endendWAIT: beginif (in) beginnext_state = IDLE;endelse beginnext_state = WAIT;endendSTOP: beginif (in) beginnext_state = IDLE;endelse beginnext_state = START;end  enddefault: beginnext_state = IDLE;endendcase
end //状态机第三段,结果输出,组合逻辑
always @(posedge clk) beginif (reset) beginout_byte <= 'd0;done <= 'd0;endelse begincase(next_state)IDLE: beginout_byte <= 'd0;done <= 'd0;endSTART: beginout_byte <= 'd0;done <= 'd0;endBIT_ONE: beginout_byte[0] <= in;done <= 'd0;endBIT_TWO: beginout_byte[1] <= in;done <= 'd0; endBIT_THREE: beginout_byte[2] <= in;done <= 'd0;endBIT_FOUR: beginout_byte[3] <= in;done <= 'd0;endBIT_FIVE: beginout_byte[4] <= in;done <= 'd0;endBIT_SIX: beginout_byte[5] <= in;done <= 'd0; endBIT_SEVEN: beginout_byte[6] <= in;done <= 'd0;endBIT_EIGHT: beginout_byte[7] <= in;done <= 'd0; endPARITY_BIT: beginout_byte <= out_byte;done <= 'd0;endWAIT: beginout_byte <= out_byte;done <= 'd0;endSTOP: beginout_byte <= out_byte;if (odd=='d1) begindone <= 'd1;    endelse begindone <= 'd0;endenddefault: beginout_byte <= 'd0;done <= 'd0;endendcaseend
end
// always @(posedge clk) begin
//  if (reset) begin
//      done <= 'd0;
//  end
//  else if (next_state==STOP && odd=='d1) begin
//      done <= 'd1;
//  end
//  else begin
//      done <= 'd0;
//  end
// endwire   rst;
assign rst = (reset == 1'b1 || next_state == IDLE || next_state == START);parity u_parity(.clk        (clk      ),.reset      (rst      ),.in         (in           ),.odd        (odd      )
);endmodule

Fsm hdlc

同步 HDLC 成帧涉及解码连续的位数据流,以查找指示帧(数据包)开始和结束的位模式。看到 6 个连续的 1(即01111110)是一个指示帧边界的“标志”。为了避免数据流意外包含“标志”,发送方在每5个连续的1之后插入一个零,接收方必须检测并丢弃。如果连续有 7 个或更多个 1,我们还需要发出错误信号。

创建一个有限状态机来识别这三个序列:

  • 0111110:需要丢弃一个位的信号(丢弃)。
  • 01111110:标记帧的开头/结尾(标志)。
  • 01111111...: 错误 (7 或更多 1 ) (错误)。

重置 FSM 时,它应处于行为类似于上一个输入为 0 的状态。

下面是一些示例序列,用于说明所需的操作。

module top_module(input       clk,input       reset,    // Synchronous resetinput       in,output      disc,output      flag,output      err
);parameter  IDLE       =  10'b0000000001;
parameter  BIT_ONE    =  10'b0000000010;
parameter  BIT_TWO    =  10'b0000000100;
parameter  BIT_THREE  =  10'b0000001000;
parameter  BIT_FOUR   =  10'b0000010000;
parameter  BIT_FIVE   =  10'b0000100000;
parameter  BIT_SIX    =  10'b0001000000;
parameter  STOP       =  10'b0010000000;
parameter  DIS        =  10'b0100000000;
parameter  ERROR      =  10'b1000000000;reg  [9:0]   state;
reg  [9:0]   next_state;//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) beginif (reset) beginstate <= IDLE;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) beginnext_state = state;case(state)IDLE: beginif (in) beginnext_state = BIT_ONE;endelse beginnext_state = IDLE;endendBIT_ONE: beginif (in) beginnext_state = BIT_TWO;endelse beginnext_state = IDLE;endendBIT_TWO: beginif (in) beginnext_state = BIT_THREE;endelse beginnext_state = IDLE;endendBIT_THREE: beginif (in) beginnext_state = BIT_FOUR;endelse beginnext_state = IDLE;endendBIT_FOUR: beginif (in) beginnext_state = BIT_FIVE;endelse beginnext_state = IDLE;endendBIT_FIVE: beginif (in) beginnext_state = BIT_SIX;endelse beginnext_state = DIS;endendBIT_SIX: beginif (~in) beginnext_state = STOP;endelse beginnext_state = ERROR;endendSTOP: beginif (in) beginnext_state = BIT_ONE;endelse beginnext_state = IDLE;endendDIS: beginif (in) beginnext_state = BIT_ONE;endelse beginnext_state = IDLE;endendERROR: beginif (in) beginnext_state = ERROR;endelse beginnext_state = IDLE;endenddefault: beginnext_state = IDLE;endendcase
end//状态机第三段,结果输出,时序逻辑非阻塞赋值
always @(posedge clk) beginif (reset) begindisc <= 'd0;flag <= 'd0;err  <= 'd0;endelse begincase(next_state)DIS: begindisc <= 'd1;flag <= 'd0;err  <= 'd0;endSTOP: begindisc <= 'd0;flag <= 'd1;err  <= 'd0;                          endERROR: begindisc <= 'd0;flag <= 'd0;err  <= 'd1;enddefault: begindisc <= 'd0;flag <= 'd0;err  <= 'd0;endendcaseend
endendmodule

Design a Mealy FSM

实现一个 Mealy 型有限状态机,该状态机在名为 x 的输入信号上识别序列“101”。您的 FSM 应具有一个输出信号 z,当检测到“101”序列时,该信号被置位到逻辑-1。您的 FSM 还应具有低电平有效异步复位。您的状态机中可能只有 3 个状态。您的 FSM 应识别重叠序列。

module top_module (input      clk,input      aresetn,    // Asynchronous active-low resetinput      x,output     z
);//状态定义
parameter  IDLE       =  4'b0001;
parameter  BIT_ONE    =  4'b0010;
parameter  BIT_TWO    =  4'b0100;
parameter  BIT_THREE  =  4'b1000;//现态和次态
reg  [3:0]   state;
reg  [3:0]   next_state;//状态机第一段,初始化状态,时序逻辑非阻塞赋值
always @(posedge clk or negedge aresetn) beginif (!aresetn) beginstate <= IDLE;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) beginnext_state = state;case(state)IDLE: beginif (x) beginnext_state = BIT_ONE;endelse beginnext_state = IDLE;endendBIT_ONE: beginif (~x) beginnext_state = BIT_TWO;endelse beginnext_state = BIT_ONE;endendBIT_TWO: beginif (x) beginnext_state = BIT_THREE;endelse beginnext_state = IDLE;endendBIT_THREE: beginif (x) beginnext_state = BIT_ONE;endelse beginnext_state = BIT_TWO;endenddefault: beginnext_state = IDLE;endendcase
end//状态机第三段,结果输出,组合逻辑
assign z = (next_state==BIT_THREE);endmodule

ece241 2014 q5a

设计一个单输入一输出串行2的补码器摩尔状态机。输入(x)是一系列位(每个时钟周期一个),从数字的最低有效位开始,输出(Z)是输入的2的补码。机器将接受任意长度的输入数字。该电路需要异步复位。释放重置时开始转换,断言重置时停止转换。

module top_module (input       clk,input       areset,input       x,output      z
); parameter  MSB    =  3'b001;
parameter  OUT_1  =  3'b010;
parameter  OUT_0  =  3'b100;reg  [2:0]     state;
reg  [2:0]     next_state;//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk or posedge areset) beginif (areset) beginstate <= MSB;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) beginnext_state = state;case(state)MSB: beginif (x) beginnext_state = OUT_1;endelse beginnext_state = MSB;endendOUT_1: beginif (x) beginnext_state = OUT_0;endelse beginnext_state = OUT_1;endendOUT_0: beginif (~x) beginnext_state = OUT_1;endelse beginnext_state = OUT_0;endenddefault: beginnext_state = MSB;endendcase
end//状态机第三段,结果输出,组合逻辑
assign z = (state==OUT_1);endmodule

ece241 2014 q5b

利用独热码编写一下的米利状态机。

module top_module (input       clk,input       areset,input       x,output      z
); parameter  A  =  2'b01;
parameter  B  =  2'b10;reg  [1:0]     state;
reg  [1:0]     next_state;//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk or posedge areset) beginif (areset) beginstate <= A;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) beginnext_state = state;case(state)A: beginif (x) beginnext_state = B;z = 'd1;endelse beginnext_state = A;z = 'd0;endendB: beginnext_state = B;if (x) beginz = 'd0;endelse beginz = 'd1;endendendcase
endendmodule

2014 q3fsm

module top_module (input       clk,input       reset,   // Synchronous resetinput       s,input       w,output      z
);parameter  IDLE =  5'b00001;
parameter  A    =  5'b00010;
parameter  B    =  5'b00100;
parameter  C    =  5'b01000;
parameter  D    =  5'b10000;reg  [4:0]    state;
reg  [4:0]    next_state;
reg  [10:0]   cnt;//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) beginif (reset) beginstate <= IDLE;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) begincase(state)IDLE: beginif (s) beginnext_state = A;endelse beginnext_state = IDLE;endendA: beginnext_state = B;endB: beginnext_state = C;endC: beginnext_state = D;endD: beginnext_state = B;enddefault: beginnext_state = IDLE;endendcase
endalways @(posedge clk) beginif (reset) begincnt <= 'd0;endelse begincase(next_state)IDLE: begincnt <= 'd0;endA: begincnt <= 'd0;endB: beginif (w) begincnt <= 'd1;endelse begincnt <= 'd0;endendC: beginif (w) begincnt <= cnt + 'd1;endelse begincnt <= cnt;endendD: beginif (w) begincnt <= cnt + 'd1;endelse begincnt <= cnt;endendendcaseend
endassign z = (state==D && cnt=='d2);endmodule

2014 q3bfsm

给定如下所示的状态分配表,实现有限状态机。重置应将 FSM 重置为状态 000。

module top_module (input      clk,input      reset,   // Synchronous resetinput      x,output     z
);parameter  A  =  3'b000;
parameter  B  =  3'b001;
parameter  C  =  3'b010;
parameter  D  =  3'b011;
parameter  E  =  3'b100;reg  [2:0]  state;
reg  [2:0]  next_state;//状态机第一段,状态初始化,时序逻辑非阻塞赋值
always @(posedge clk) beginif (reset) beginstate <= A;endelse beginstate <= next_state;end
end//状态机第二段,状态跳转,阻塞赋值
always @(*) beginnext_state = state;case(state)A: beginif (x) beginnext_state = B;endelse beginnext_state = A;endendB: beginif (x) beginnext_state = E;endelse beginnext_state = B;endendC: beginif (x) beginnext_state = B;endelse beginnext_state = C;endendD: beginif (x) beginnext_state = C;endelse beginnext_state = B;endendE: beginif (x) beginnext_state = E;endelse beginnext_state = D;endenddefault: beginnext_state = A;endendcase
end//状态机第三段,结果输出,组合逻辑
assign z = (state==D) || (state==E);endmodule

【HDLBits 刷题 11】Circuits(7)Finite State Manchines 18-26相关推荐

  1. 【HDLBits 刷题】所有答案直达链接汇总

    写在前面 以下为HDLBits全部答案,有些题的解法不唯一,我的也许不是最优解,欢迎提出更好的想法,HDLBits总的来说比较适合初学者. HDLBits 答案汇总 Language [HDLBits ...

  2. 【HDLBits 刷题 10】Circuits(6)Finite State Manchines 10-17

    目录 写在前面 Finite State Manchines Lemmings1 Lemmings2 Lemmings3 Lemmings4 Fsm onehot Fsm ps2 Fsm ps2dat ...

  3. 【HDLBits 刷题 9】Circuits(5)Finite State Manchines 1-9

    目录 写在前面 Finite State Manchines Fsm1 Fsm1s Fsm2 Fsm2s Fsm3comb Fsm3onehot Fsm3 Fsm3s Design a Moore F ...

  4. 【HDLBits 刷题 12】Circuits(8)Finite State Manchines 27-34

    目录 写在前面 Finite State Manchines 2014 q3c m2014 q6b m2014 q6c m2014 q6 2012 q2fsm 2012 q2b 2013 q2afsm ...

  5. HDLBits刷题合集—9 Arithmetic Circuits

    HDLBits刷题合集-9 Arithmetic Circuits HDLBits-66 Hadd Problem Statement 创建一个半加器.半加器将两个输入(不带低位的进位)相加产生和和向 ...

  6. HDLBits刷题全记录(五)

    文章目录 Finite State Machines Simple FSM 1_1(asynchronous reset) Simple FSM 1_2(synchronous reset) Simp ...

  7. 【小罗的hdlbits刷题笔记4】从lemming4中的有限状态机debug过程中的一些感悟

    心累,debug过程就是很烦,先说一下结论:设置变量时一定要注意位宽,否则会出现截位导致输出结果出现bug 废话不多说,先上问题 *Although Lemmings can walk, fall, ...

  8. 【小罗的hdlbits刷题笔记5】基于fifo思想的fsm设计(Exams/2014 q3fsm)

    在写状态机时,经常会有检测输入信号波形的情况,这种情况下,如果采用三段式状态机书写,则需要通过穷举法把输入信号所有可能存在的情况书写出来,在检测一到两个周期的输入信号时工作量不会很大,但是在检测多于三 ...

  9. 刷题记录(2023.3.14 - 2023.3.18)

    [第五空间 2021]EasyCleanup 临时文件包含考点 分析源码,两个特殊的点,一个是 eval,另一个是 include eval 经过了 strlen filter checkNums 三 ...

最新文章

  1. vue-cli eslint 规则
  2. Angular HTML template的解析位置
  3. mysql char varchar 性能_Mysql小细节:varchar与char在性能上的特点
  4. 一些Base64编码/解码及数据压缩/解压方面的知识
  5. Java知多少(28)super关键字
  6. Centos 5 手动安装yum
  7. python是开源语言吗c,属于新十年的开发语言:Go语言可能很快会取代Python
  8. 零拷贝的基本原理及使用Java通过零拷贝实现数据传输
  9. 使用WinDbg分析Windows dump文件方法
  10. keras中文文档网址
  11. Spring文件中的xsd文件
  12. laravel使用irazasyed/laravel-gamp集成google analytics
  13. matlab改变直方图数量级,直方图规定化——Matlab实现及其原理
  14. android光谱图软件,光谱精灵精华版Plus
  15. java 通过 ip地址 找到 打印机_有没有办法使用java套接字程序找到打印机状态?...
  16. 智能LED电子钟的制作
  17. Java中浮点数原理及精度丢失问题
  18. 地方门户网站SEO 重点做长尾词
  19. Redis主从模式下从库过期的key仍然能够被读到的解决方案
  20. Linux程序设计—多进程编程

热门文章

  1. align的对齐方式
  2. pp-vehicle简介
  3. JS 事件高级(包括DOM事件流,阻止事件冒泡,阻止事件默认行为,,,以及对我来说,很好用的 事件代理)
  4. Arduino UNO输出高电平点亮LED(三)
  5. 金蝶EAS8.6 金蝶EAS8.5 SHR8.6 金蝶EAS7.5 金蝶EAS7.03
  6. oracle+统计表的字段,统计系统中表的个数与查询所有表的字段信息-Oracle
  7. 纷享销客CRM自定义函数:计划任务
  8. QQ自定义音乐卡片代码
  9. 【LeetCode】675. 为高尔夫比赛砍树
  10. IOS越狱设备关机重启之后发现SSH连接不上解决方法