码迷,mamicode.com
首页 > 其他好文 > 详细

上升沿检测器的两种状态机实现及直接实现Verilog

时间:2017-09-23 15:18:06      阅读:185      评论:0      收藏:0      [点我收藏+]

标签:job   hdp   ror   dad   anr   dsp   vsr   vax   cbe   

上升沿检测即是在输入信号由01时,输出一个时钟周期的指示信号。整理该题目的主要目的是为了加深对边沿检测印象及更好的理解两种状态机(Moore机及Mealy机)的实现机制的理解。


书中源代码及测试代码见尾部

 

基于Moore机的设计

基于Moore机的上升沿检测状态机如下图所示,在0状态和1状态之间还有一个边沿状态,在状态0下,输入信号变1时会进入边沿状态,并输出指示信号。

技术分享

modelsim仿真结果如下图

技术分享


基于Mealy机的设计

当状态机处于0状态且输入信号为1时,输出指示信号立即变为1。状态机在下一个时钟进入1状态且输出复位为0

modelsim仿真结果如下图

技术分享


直接实现

上升沿检测到电路实现非常简单,可以不用状态机而直接实现,且可以与上面的设计比较。设计RTL视图如下,只有当当前为1且寄存器中存储的上一个值为0时才输出1

技术分享

modelsim仿真结果如下图

技术分享


直接实现与Mealy机实现比较

虽然两者代码看上去有很大差别,但是加上两者描述的是同样的电路。如果给0状态和1状态赋值01,那么两者就是一样的了。


Moore机和Mealy机比较

尽管基于Moore机的设计和基于Mealy机的设计都能在输入信号的上升沿生成一个短暂的标记,但是两者仍有一些细微的差别。基于Mealy机的设计所需状态更少,响应更快,但是输出信号的宽度可能会变化,输入毛刺可能被传给输出。

两个设计之间的选择取决于使用这个输出信号的子系统。大部分时间,子系统是同步系统,共享一个时钟信号。因为FSM的输出只在时钟上升沿采样,所以只要输出信号在时钟边沿附近稳定,信号宽度和毛刺就无关紧要。注意Mealy输出信号比Moore输出快一个时钟周期,因此,基于Mealy机的设计电路更适合这种类型的应用。


最后一点补充:上面关于Moore机和Mealy机的比较是完完整整地摘抄自书本,因为本人对此还是有种似懂非懂的感觉,留着慢慢消化

 

Moore机

 

技术分享
 1 module edge_detect(
 2     input wire clk, reset,
 3     input wire level,
 4     output reg tick
 5     );
 6     
 7     // symbolic state declaration
 8     localparam [1:0]
 9         zero = 2b00,
10         edg    = 2b01,
11         one = 2b10;
12         
13     // signal declaration
14     reg [1:0] state_reg, state_next;
15     
16     // state register
17     always @(posedge clk or posedge reset)
18         if(reset)
19             state_reg <= zero;
20         else
21             state_reg <= state_next;
22             
23     // next-state logic and output logic
24     always @* begin
25         state_next = state_reg;        // default state: the same
26         tick = 1b0;                // default output: 0
27         case (state_reg)
28             zero:
29                 if(level)
30                     state_next = edg;
31             edg:
32                 begin
33                     tick = 1b1;
34                     if(level)
35                         state_next = one;
36                     else
37                         state_next = zero;
38                 end
39             one:
40                 if(~level)
41                     state_next = zero;
42             default:
43                 state_next = zero;
44         endcase
45     end
46 endmodule
47     
View Code

 

 

Mealy机

技术分享
 1 module edge_detect(
 2     input wire clk, reset,
 3     input wire level,
 4     output reg tick
 5     );
 6     
 7     // symbolic state declaration
 8     localparam zero = 1b0,
 9                 one = 1b1;
10                 
11     // signal declaration
12     reg state_reg, state_next;
13     
14     // state register
15     always @(posedge clk, posedge reset)
16         if(reset)
17             state_reg <= zero;
18         else
19             state_reg <= state_next;
20             
21     // next-state logic and output logic
22     always @* begin
23         state_next = state_reg;    // default state: the same
24         tick = 1b0;            // default output: 0
25         case(state_reg)
26             zero:
27                 if(level)
28                     begin
29                         tick = 1b1;
30                         state_next = one;
31                     end
32             one:
33                 if(~level)
34                     state_next = zero;
35             default:
36                 state_next = zero;
37         endcase
38     end
39     
40 endmodule
View Code

 

直接实现

技术分享
 1 module edge_detect(
 2     input wire clk, reset,
 3     input wire level,
 4     output wire tick
 5     );
 6     
 7     // signal declaration
 8     reg delay_reg;
 9     
10     // delay register
11     always @(posedge clk or posedge reset)
12         if(reset)
13             delay_reg <= 1b0;
14         else
15             delay_reg <= level;
16     
17     // decoding logic
18     assign tick = ~delay_reg & level;
19 endmodule
View Code

 

Testbench

技术分享
 1 `timescale 1ns/10ps
 2 
 3 module edge_detect_tb;
 4 
 5     // declaration
 6     localparam T = 20;
 7     reg clk, reset;
 8     reg level;
 9     wire tick;
10 
11     // uut instantiate
12     edge_detect uut(
13         .clk    (clk    ),
14         .reset    (reset    ),
15         .level    (level    ),
16         .tick    (tick    )
17     );
18     
19     // clock
20     always begin
21         clk = 1b1;
22         #(T/2);
23         clk = 1b0;
24         #(T/2);
25     end
26     
27     // reset for the first half cycle
28     initial begin
29         reset = 1b1;
30         #(T/2);
31         reset = 1b0;
32     end
33     
34     // other simulus
35     initial begin
36         // initial input
37         level = 0;
38         
39         @(negedge reset);    // wait reset to deassert
40         @(negedge clk);        // wait for one clock
41         
42         // test
43         repeat(5) @(negedge clk);
44         level = 1;
45         repeat(5) @(negedge clk);
46         
47         $stop;
48     end
49     
50 endmodule
View Code

 

 

 

 

2017/9/23

 

本文整理自《基于Nios II的嵌入式SoPC系统设计与Verilog开发实例》

 


 

上升沿检测器的两种状态机实现及直接实现Verilog

标签:job   hdp   ror   dad   anr   dsp   vsr   vax   cbe   

原文地址:http://www.cnblogs.com/qingkai/p/7581051.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!