zoukankan      html  css  js  c++  java
  • 简单三段式状态机实验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早一拍,把波形状态切换时刻放大就可以明显看到,如下波形:

  • 相关阅读:
    前端性能优化
    技术从业者的未来(二)
    微服务架构
    SpringCloud 微服务最佳开发实践
    架构师之路
    SpringBoot开发秘籍
    架构设计方法论
    消息架构的设计难题以及应对之道
    SpringCloud 中如何防止绕过网关请求后端服务?
    微服务架构授权是在网关做还是在微服务做?
  • 原文地址:https://www.cnblogs.com/wen2376/p/3443621.html
Copyright © 2011-2022 走看看