基于有限状态机的计数器

HDLBits链接


前言

今天更新搭建更大的电路部分的习题,内容主要跟计数器和有限状态机有关。


题库

Counter with period 1000

构造一个0-999的计数器,同步高电平复位。

Solution

module top_module (input clk,input reset,output [9:0] q);always @(posedge clk) beginif(reset) beginq <= 10'd0;endelse if(q == 10'd999) beginq <= 10'd0;endelse beginq <= q + 1'b1;endendendmodule

4-bit shift register and down counter

构造一个4bit的移位寄存器,同时也可以做倒数的计数器使用。其中当shift_ena为1时数据data的高位先进到移位寄存器中;当count_ena为1时,计数器从寄存器中存储的数开始逐时钟递减;shift_enacount_ena没有重要级先后顺序,因为他们不会同时使能。

Solution:

module top_module (input clk,input shift_ena,input count_ena,input data,output [3:0] q);reg [3:0] q_temp;always @(posedge clk) beginif(shift_ena) beginq_temp <= {q_temp[2:0],data};endelse if(count_ena) beginif(q_temp == 4'd0) beginq_temp <= 4'd15;endelse beginq_temp <= q_temp - 1'b1;endendendassign q = q_temp;endmodule

我以为计数器到0时停止计数,本来按这个逻辑写的,然后在线提交时出错。作者的意思是0后面下一个状态是15,这个大家做题时需注意。

FSM:Sequence 1101 recognizer

构造一个有限状态机检测data中的1101序列,如果检测到该序列,则将输出一直拉高直到同步复位信号为高。

Solution

module top_module (input clk,input reset,      // Synchronous resetinput data,output start_shifting);parameter IDLE = 3'd0, S1 = 3'd1, S2 = 3'd2;parameter S3 = 3'd3, OUT = 3'd4;reg [2:0] current_state, next_state;always @(*) begincase(current_state)IDLE:       next_state = data ? S1 : IDLE;S1:         next_state = data ? S2 : IDLE;S2:         next_state = data ? S2 : S3;S3:         next_state = data ? OUT : IDLE;OUT:        next_state = OUT;default:    next_state = IDLE;endcaseendalways @(posedge clk) beginif(reset) begincurrent_state <= IDLE;endelse begincurrent_state <= next_state;endendassign start_shifting = current_state == OUT;endmodule

FSM:Enable shift register

当有限状态机被复位时,将shift_ena拉高4个周期,之后保持为0直到再次复位。

Solution

module top_module (input clk,input reset,      // Synchronous resetoutput shift_ena);parameter IDLE = 2'd0, ENA = 2'd1, STOP = 2'd2;reg [1:0] current_state, next_state;reg [2:0] counter;always @(*) begincase(current_state)IDLE:       next_state = ENA;ENA:        next_state = (counter == 3'd3) ? STOP : ENA;STOP:       next_state = STOP;default:    next_state = IDLE;endcaseendalways @(posedge clk) beginif(reset) begincurrent_state <= IDLE;endelse begincurrent_state <= next_state;endendalways @(posedge clk) beginif(reset) begincounter <= 3'd0;endelse begincase(next_state)IDLE:       counter <= 3'd0;ENA:        counter <= counter + 1'b1;STOP:       counter <= 3'd0;default:    counter <= 3'd0;endcaseend      endassign shift_ena = current_state == ENA | current_state == IDLE;endmodule

需注意的是复位一直为高的时候输出也一直为高电平;

FSM:The complete FSM

官方提供的状态转移图

Solution

module top_module (input clk,input reset,      // Synchronous resetinput data,output shift_ena,output counting,input done_counting,output done,input ack );parameter S = 4'd0, S1 = 4'd1, S11 = 4'd2, S110 = 4'd3;parameter B0 = 4'd4, B1 = 4'd5, B2 = 4'd6, B3 = 4'd7;parameter Count = 4'd8, Wait = 4'd9;reg [3:0] current_state, next_state;always @(*) begincase(current_state)S:          next_state = data ? S1 : S;S1:         next_state = data ? S11 : S;S11:        next_state = data ? S11 : S110;S110:       next_state = data ? B0 : S;B0:         next_state = B1;B1:         next_state = B2;B2:         next_state = B3;B3:         next_state = Count;Count:      next_state = done_counting ? Wait : Count;Wait:       next_state = ack ? S : Wait;default:    next_state = S;endcaseendalways @(posedge clk) beginif(reset) begincurrent_state <= S;endelse begincurrent_state <= next_state;endendassign shift_ena = current_state == B0 | current_state == B1 | current_state == B2 | current_state == B3;assign counting = current_state == Count;assign done = current_state == Wait;endmodule

标准的FSM格式,没啥说的,画出状态转移表写就行了。

The complete timer

该道状态机就是前面几道状态机的组合,大家需注意的是计数那边的部分;之前我将计数子的位宽设置不当,导致这题卡的挺久,希望大家做题分析时注意。

Solution

module top_module (input clk,input reset,      // Synchronous resetinput data,output [3:0] count,output counting,output done,input ack );parameter IDLE = 4'd0, S1 = 4'd1, S2 = 4'd2, S3 = 4'd3;parameter C0 = 4'd4, C1 = 4'd5, C2 = 4'd6, C3 = 4'd7;parameter Count_1000 = 4'd8, Done = 4'd9;reg [3:0] current_state, next_state;reg [15:0] num;reg [3:0] delay;reg [3:0] already_count;wire count_state;assign count_state = (num == (delay + 1'b1)*1000) ? 1'b1 : 1'b0;always @(*) beginif(num <= 16'd1000) beginalready_count = 4'd0;endelse if(num > 16'd1000 && num <= 16'd2000) beginalready_count = 4'd1;endelse if(num > 16'd2000 && num <= 16'd3000) beginalready_count = 4'd2;endelse if(num > 16'd3000 && num <= 16'd4000) beginalready_count = 4'd3;endelse if(num > 16'd4000 && num <= 16'd5000) beginalready_count = 4'd4;endelse if(num > 16'd5000 && num <= 16'd6000) beginalready_count = 4'd5;endelse if(num > 16'd6000 && num <= 16'd7000) beginalready_count = 4'd6;endelse if(num > 16'd7000 && num <= 16'd8000) beginalready_count = 4'd7;endelse if(num > 16'd8000 && num <= 16'd9000) beginalready_count = 4'd8;endelse if(num > 16'd9000 && num <= 16'd10000) beginalready_count = 4'd9;endelse if(num > 16'd10000 && num <= 16'd11000) beginalready_count = 4'd10;endelse if(num > 16'd11000 && num <= 16'd12000) beginalready_count = 4'd11;endelse if(num > 16'd12000 && num <= 16'd13000) beginalready_count = 4'd12;endelse if(num > 16'd13000 && num <= 16'd14000) beginalready_count = 4'd13;endelse if(num > 16'd14000 && num <= 16'd15000) beginalready_count = 4'd14;endelse beginalready_count = 4'd15;endendalways @(posedge clk) beginif(reset) beginnum <= 16'd0;endelse if(next_state == Done) beginnum <= 16'd0;endelse if(next_state == Count_1000) beginnum <= num + 16'd1;endendalways @(*) begincase(current_state)IDLE:       next_state = data ? S1 : IDLE;S1:         next_state = data ? S2 : IDLE;S2:         next_state = data ? S2 : S3;S3:         next_state = data ? C0 : IDLE;C0:beginnext_state = C1;delay[3] = data;end         C1:beginnext_state = C2;    delay[2] = data;end         C2:beginnext_state = C3;    delay[1] = data;end         C3:beginnext_state = Count_1000;    delay[0] = data;end         Count_1000: next_state = count_state ? Done : Count_1000;Done:       next_state = ack ? IDLE : Done;default:    next_state = IDLE;endcaseendalways @(posedge clk) beginif(reset) begincurrent_state <= IDLE;endelse begincurrent_state <= next_state;endendassign count = (current_state == Count_1000) ? (delay - already_count) : 4'd0;assign counting = (current_state == Count_1000);assign done = current_state == Done;endmodule

FSM:One-hot logic equations

用one-hot编码的状态写出状态转移代码。

Solution

module top_module(input d,input done_counting,input ack,input [9:0] state,    // 10-bit one-hot current stateoutput 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 = ~d & state[S] | ~d & state[S1] | ~d & state[S110] | ack & state[Wait];assign S1_next = d & state[S];assign Count_next = state[B3] | ~done_counting & state[Count];assign Wait_next = done_counting & state[Count] | ~ack & state[Wait];assign done = state[Wait];assign counting = state[Count];assign shift_ena = state[B0] | state[B1] | state[B2] | state[B3];endmodule

结语

该小结就算更新结束了,下面剩的也不多了,争取在开学前全部刷完。如有不对的还望大家指正。

HDLBits答案(22)_基于有限状态机的计数器相关推荐

  1. HDLBits答案(24)_由波形图描述电路

    Build a circuit from a simulation waveform HDLBits链接 前言 今天更新HDLBits习题由波形图描述电路的部分,看图写代码. 题库 Combinati ...

  2. HDLBits答案(25)_编写Testbench

    Verification:Writing Testbenches HDLBits链接 前言 今天更新HDLBits最后一章的习题:编写Testbench. 题库 Clock 提供了如下描述的模块: m ...

  3. HDLBits答案(23)_找BUG

    Finding bugs in code HDLBits链接 前言 今天更新HDLBits习题部分找BUG部分,比较简单,大家看一下即可. 题库 8bit_2_1_Mux 原Code: module ...

  4. HDLBits答案(9)_卡诺图与最简SOP式

    卡诺图与最简SOP式 HDLBits链接 真值表 定义 真值表是表征逻辑事件输入和输出之间全部可能状态的表格.以1表示真,0表示假. 从真值表到标准式 SOP标准式:找出真值表中所有输出为1的表项,按 ...

  5. HDLBits答案(6)_硬件模块设计的思考方式

    硬件模块设计的思考方式 HDLBits链接 基本的逻辑门操作 题目描述1:将输入端口in和输出端口out连接. Solution1: module top_module (input in,outpu ...

  6. HDLBits答案(4)_如何避免生成锁存器?

    HDLBits_Verilog Language_Procedures HDLBits链接 组合逻辑的always块 [David说]: 考虑到硬件的可综合性,有两种always块是有意义的: 组合: ...

  7. 西安交通大学计算机笔试题,《大学计算机基础试题与答案》_西安交通大学

    <大学计算机基础试题与答案>_西安交通大学 (11页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.9 积分 . . . . .< ...

  8. C++课程设计实训_基于多态书籍信息管理系统的设计与实现、附源码、有过程截图

    C++课程设计实训_基于多态书籍信息管理系统的设计与实现.附源码,有过程截图 书籍信息管理系统的设计与实现(基于多态) 学生姓名: 学 号: 指导老师: 所 在 系: 专 业: 班 级: C++课程设 ...

  9. HTML5游戏_基于DOM平台跳跃小游戏开发_9.按键监听

    HTML5游戏_基于DOM平台跳跃小游戏开发 按键监听 视频讲解 HTML5游戏 效果图 本章知识点: 对象自定义名称属性,可以用变量来命名属性名称 //这段代码把多个属性(品牌, 型号, 排量)赋给 ...

最新文章

  1. python自动点赞_用Python模拟技巧带你实现自动抽屉登录自动点赞
  2. Python 2 中文乱码解决方案:
  3. AI:Algorithmia《2021 enterprise trends in machine learning 2021年机器学习的企业趋势》翻译与解读
  4. 画出该lti系统的幅频特性响应曲线_模拟电路-放大电路的频率响应
  5. 使用React和Spring Boot构建一个简单的CRUD应用
  6. 矩池云Jupyterlab支持download as pdf
  7. python HTTP请求过程
  8. php将一个日期字符串转换成举例来说当前的,PHP将一个日期字符串转换成举例来说当前的天数...
  9. (莱昂氏unix源代码分析导读-49) 字符缓冲区
  10. it营Typescript学习笔记02(基础完结)模块,命名空间,装饰器
  11. android rom root权限,教你刷机包获取ROOT权限的方法
  12. 曼昆《经济学原理(微观经济学分册)》(第6版)课后习题答案
  13. WPS简历模板的图标怎么修改_官方发福利一起来薅羊毛啦!教你免费领WPS会员
  14. emc re 整改 超标_CE认证EMC测试不合格,如何整改 ;
  15. 论文阅读:You said that?
  16. 高冷一字id_一字网名男生高冷霸气
  17. CAD图纸打印时如何去掉图纸边框的白边?
  18. 小巧精美原厂轴 Cherry发布全新MX Board 1.0
  19. [Vuetify] 解决mainterialicon加载慢
  20. 扬州美女能否走出传说产生经济价值?

热门文章

  1. CRM Fiori Opportunity Application Component.js - declare and require
  2. 本文可能是国内第一篇介绍C/4HANA Foundation的中文博客
  3. product thumbnail区域未能显示的原因分析
  4. wordpress的API end point
  5. WordPress的cookie处理
  6. Revenue Cloud答疑
  7. SAP CRM BSP component在test mode下launch的执行顺序
  8. java.lang.ClassNotFoundException: com.sap.exception.GlobalDefaultExceptionHandler
  9. 部署在CloudFoundry上的nodejs如何正确使用port环境变量
  10. 微信程序开发系列教程(一)开发环境搭建