简单三段式状态机实验1-SOS

2023-10-15 02:30

本文主要是介绍简单三段式状态机实验1-SOS,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  一直想从一段式状态机切换到三段式状态机,从书上和网上不断搜寻三段式案例及方法,感觉很简单,就想拿之前做过的实验把一段式改成三段式,可是写起来并非那么简单,很棘手,改完后也没有成功,尤其状态机里面的计数器,查了一些资料,就一句话带过,把计数器提出来,但怎么提、怎么来保证同步、怎么不让生成latch,并没有仔细的讲清楚。也许自己比较笨吧,一时半会改不出来,当时就想,是不是起步太高了,应该在找一个简单的例程改写,循序渐进。这时就重新阅读黑金的"Verilog那些事儿"教程,看里面哪个例程比较简单,容易改的,结果找到建模篇的实验五例程进行改写,改完后发现三段式写还是比较简单的,思路也比较清晰。当然我跟书上的思路有点不一样,我是这样做的:

    产生SOS信号,就是短音(100ms)、间隔(50ms)、长音(300ms),三种音之间的一个组合,可以得到下面波形,这是SOS信号吗?好吧,就是利用三段式产生如下一个波形。

 由于不像占空比为50%波形那么有简单,中间要产生不同的占空比高低电平,那么就把它定义成18个状态,加上空闲状态,共19个状态,每个状态,输出高或低就行。

代码实现:

sos.v

  1 module sos(
  2             //input
  3             sys_clk,
  4             rst_n,
  5             start_cnt,
  6             
  7             //output
  8             sig_out
  9             );
 10 /*************************************************************/
 11 input         sys_clk;
 12 input         rst_n;
 13 input        start_cnt;
 14 
 15 output         sig_out;
 16 /*************************************************************/
 17 parameter    T1MS  = 16'd49_999;
 18 /*************************************************************/
 19 reg [15 : 0] cnt;
 20 always @(posedge sys_clk or negedge rst_n)
 21 if(!rst_n)
 22     cnt <= 16'd0;
 23 else if(!start_cnt || cnt == T1MS)
 24     cnt <= 16'd0;
 25 else if(start_cnt)
 26     cnt <= cnt + 1'b1;
 27 else
 28     cnt <= 16'd0;
 29 /*************************************************************/
 30 reg [15 : 0] cnt_ms;
 31 always @(posedge sys_clk or negedge rst_n)
 32 if(!rst_n)
 33     cnt_ms <= 16'd0;
 34 else if(start_cnt && cnt == T1MS)
 35     cnt_ms <= cnt_ms + 1'b1;
 36 else if(!start_cnt || cnt_ms == 11'd1950)
 37     cnt_ms <= 16'd0;
 38 /*************************************************************/
 39 parameter IDLE         = 5'd0    ;
 40 parameter SHORT_1   = 5'd1    ;
 41 parameter DLY_1        = 5'd2    ;
 42 parameter SHORT_2    = 5'd3  ;
 43 parameter DLY_2         = 5'd4    ;
 44 parameter SHORT_3    = 5'd5    ;
 45 parameter DLY_3         = 5'd6    ;
 46 parameter LONG_1    = 5'd7    ;
 47 parameter DLY_4         = 5'd8    ;
 48 parameter LONG_2    = 5'd9    ;
 49 parameter DLY_5         = 5'd10    ;
 50 parameter LONG_3    = 5'd11    ;
 51 parameter DLY_6         = 5'd12    ;
 52 parameter SHORT_4    = 5'd13    ;
 53 parameter DLY_7         = 5'd14    ;
 54 parameter SHORT_5    = 5'd15    ;
 55 parameter DLY_8         = 5'd16    ;
 56 parameter SHORT_6    = 5'd17    ;
 57 parameter DLY_9        = 5'd18    ;
 58 /*************************************************************/
 59 reg [4 : 0] state_crt,state_nxt;
 60 always @(posedge sys_clk or negedge rst_n)
 61 if(!rst_n)
 62     state_crt <= IDLE;
 63 else
 64     state_crt <= state_nxt;
 65 /*************************************************************/
 66 always @( * )
 67 case(state_crt)
 68     IDLE    :     state_nxt = SHORT_1;
 69     SHORT_1    :     if(cnt_ms == 11'd100 ) state_nxt = DLY_1;
 70                 else state_nxt = SHORT_1;
 71     DLY_1    :     if(cnt_ms == 11'd150 ) state_nxt = SHORT_2;
 72                 else state_nxt = DLY_1;
 73     SHORT_2    :     if(cnt_ms == 11'd250 ) state_nxt = DLY_2;
 74                 else state_nxt = SHORT_2;
 75     DLY_2    :     if(cnt_ms == 11'd300 ) state_nxt = SHORT_3;
 76                 else state_nxt = DLY_2;
 77     SHORT_3    :     if(cnt_ms == 11'd400 ) state_nxt = DLY_3;
 78                 else state_nxt = SHORT_3;
 79     DLY_3    :     if(cnt_ms == 11'd450 ) state_nxt = LONG_1;
 80                 else state_nxt = DLY_3;
 81     LONG_1    :     if(cnt_ms == 11'd750 ) state_nxt = DLY_4;
 82                 else state_nxt = LONG_1;
 83     DLY_4    :     if(cnt_ms == 11'd800 ) state_nxt = LONG_2;
 84                 else state_nxt = DLY_4;
 85     LONG_2    :     if(cnt_ms == 11'd1100) state_nxt = DLY_5;
 86                 else state_nxt = LONG_2;
 87     DLY_5    :     if(cnt_ms == 11'd1150) state_nxt = LONG_3;
 88                 else state_nxt = DLY_5;
 89     LONG_3    :     if(cnt_ms == 11'd1450) state_nxt = DLY_6;
 90                 else state_nxt = LONG_3;
 91     DLY_6    :     if(cnt_ms == 11'd1500) state_nxt = SHORT_4;
 92                 else state_nxt = DLY_6;
 93     SHORT_4    :     if(cnt_ms == 11'd1600) state_nxt = DLY_7;
 94                 else state_nxt = SHORT_4;
 95     DLY_7    :     if(cnt_ms == 11'd1650) state_nxt = SHORT_5;
 96                 else state_nxt = DLY_7;
 97     SHORT_5    :     if(cnt_ms == 11'd1750) state_nxt = DLY_8;
 98                 else state_nxt = SHORT_5;
 99     DLY_8    :     if(cnt_ms == 11'd1800) state_nxt = SHORT_6;
100                 else state_nxt = DLY_8;
101     SHORT_6    :     if(cnt_ms == 11'd1900) state_nxt = DLY_9;
102                 else state_nxt = SHORT_6;
103     DLY_9    :     if(cnt_ms == 11'd1950) state_nxt = IDLE;
104                 else state_nxt = DLY_9;
105     default :     state_nxt = IDLE;
106 endcase
107 /*************************************************************/
108 reg sig_out_temp;
109 always @(posedge sys_clk or negedge rst_n)
110 if(!rst_n)
111     sig_out_temp <= 1'b0;
112 else begin
113     case(state_nxt)
114     IDLE    : sig_out_temp <= 1'b0;
115     SHORT_1    : sig_out_temp <= 1'b1;
116     DLY_1    : sig_out_temp <= 1'b0;
117     SHORT_2    : sig_out_temp <= 1'b1;
118     DLY_2    : sig_out_temp <= 1'b0;
119     SHORT_3    : sig_out_temp <= 1'b1;
120     DLY_3    : sig_out_temp <= 1'b0;
121     LONG_1    : sig_out_temp <= 1'b1;
122     DLY_4    : sig_out_temp <= 1'b0;
123     LONG_2    : sig_out_temp <= 1'b1;
124     DLY_5    : sig_out_temp <= 1'b0;
125     LONG_3    : sig_out_temp <= 1'b1;
126     DLY_6    : sig_out_temp <= 1'b0;
127     SHORT_4    : sig_out_temp <= 1'b1;
128     DLY_7    : sig_out_temp <= 1'b0;
129     SHORT_5    : sig_out_temp <= 1'b1;
130     DLY_8    : sig_out_temp <= 1'b0;
131     SHORT_6    : sig_out_temp <= 1'b1;
132     DLY_9    : sig_out_temp <= 1'b0;
133     default : sig_out_temp <= 1'b0;
134     endcase
135 end
136 /*************************************************************/
137 assign sig_out = start_cnt ? (~sig_out_temp) : 1'b0; 
138 /*************************************************************/
139 endmodule
140 
141     
142     
View Code

sos_top.v

 1 `timescale 1ns/10ps
 2 module sos_top;
 3 /*************************************************************/
 4 reg          sys_clk;
 5 reg          rst_n;
 6 wire         start_cnt;
 7 /*************************************************************/
 8 initial begin
 9     sys_clk = 1'b0;
10     rst_n = 1'b0;
11     #100;
12     rst_n = 1'b1;
13 end
14 /*************************************************************/
15 always #10 sys_clk = ~sys_clk;
16 /*************************************************************/
17 reg [27:0] cnt;
18 always @(posedge sys_clk or negedge rst_n)
19 if(!rst_n)
20     cnt <= 28'd0;
21 else
22     cnt <= cnt + 1'b1;
23 
24 assign start_cnt = 1'b1;//~cnt[27];
25 /*************************************************************/
26 sos        u1_sos(
27                 //input
28                 .sys_clk(sys_clk),
29                 .rst_n(rst_n),
30                 .start_cnt(start_cnt),
31                 
32                 //output
33                 .sig_out(sig_out)
34               );
35 /*************************************************************/
36 endmodule
View Code

仿真波形:

最后输出进行反向,那是因为书上是驱动蜂鸣器的,而蜂鸣器工作是低电平有效,故输出取反。此实验没有下载到板子上验证,就是做了一个仿真,从仿真波形来看,与设计思想是对的。从上面的波形来看,感觉state_crt和state_nxt貌似基本上在同一时刻变换,其实不是的,state_nxt会比state_crt早一拍,把波形状态切换时刻放大就可以明显看到,如下波形:

转载于:https://www.cnblogs.com/wen2376/p/3443621.html

这篇关于简单三段式状态机实验1-SOS的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/214768

相关文章

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

poj 1113 凸包+简单几何计算

题意: 给N个平面上的点,现在要在离点外L米处建城墙,使得城墙把所有点都包含进去且城墙的长度最短。 解析: 韬哥出的某次训练赛上A出的第一道计算几何,算是大水题吧。 用convexhull算法把凸包求出来,然后加加减减就A了。 计算见下图: 好久没玩画图了啊好开心。 代码: #include <iostream>#include <cstdio>#inclu

uva 10130 简单背包

题意: 背包和 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

一、什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的。停工时间,就是不能向用户提供服务的时间。高可用,就是系统具有高度可用性,尽量减少停工时间。如何用最简单的方法来搭建一个高效率可用的服务端JAVA呢? 停工的原因一般有: 服务器故障。例如服务器宕机,服务器网络出现问题,机房或者机架出现问题等;访问量急剧上升,导致服务器压力过大导致访问量急剧上升的原因;时间和

简单的角色响应鼠标而移动

actor类 //处理移动距离,核心是找到角色坐标在世界坐标的向量的投影(x,y,z),然后在世界坐标中合成,此CC是在地面行走,所以Y轴投影始终置为0; using UnityEngine; using System.Collections; public class actor : MonoBehaviour { public float speed=0.1f; CharacterCo

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多