简单三段式状态机实验3-Sequence Detect(序列检测)

1、序列检测器的逻辑功能描述:序列检测指的就是将一个指定的序列从数字码流中识别出来。本例中,我们将设计一个"10010”序列的检测器。设x_in为数字码流输入,z_out为检出标记输出,高电平表示“发现指定序列”,低电平表示“没有发现指定序列”。

2、本次试验的data stream是 18'b11_0010_0100_0010_0101,通过循环来给x_in进行赋值。其中还要考虑到重叠现象。

3、重点是状态图的描绘,仅有当状态机跳到E状态时,z_out才置1,说明发现了指定序列。其实这个试验关键是怎么来描绘该状态机。第一次看到夏宇闻书上该例子时,脑子里马上想到头一个问题,就是他是如何画出该状态机的,这个过程没有讲,很纳闷,那会是刚看Verilog,很多不懂,于是就放下这个问题,只阅读了代码。然而此次去看该例子时,我只看了题目和他的状态机,代码就不用看了,觉得书上画的状态机有点啰嗦,就没仔细看,干脆自己画一个 ,画该状态机其实也很简单,先把所有状态全都列出来,先单向的把IDLE->A->B->C->D->E跳变条件写上,比如IDLE到A,是当输入x_in为1时才会调到A,这个很好确认的吧,然后在仔细针对每个状态为其它条件时该如何跳,比如B是在x_in为1时是到C的,那么就得好好考虑x_in为0时,状态该跳到哪儿,就这样一步一步的仔细推敲,完整的状态机很快就完成

4、代码实现:

sequence_detect.v

 1 module sequence_detect(
 2                         //input
 3                         clk,
 4                         rst_n,
 5                         x_in,
 6                         
 7                         //ouput
 8                         z_out
 9                         );
10 /****************************************/
11 input clk;
12 input rst_n;
13 input x_in;
14 output z_out;
15 /****************************************/
16 parameter IDLE = 3'd0;
17 parameter A    = 3'd1;
18 parameter B    = 3'd2;
19 parameter C    = 3'd3;
20 parameter D    = 3'd4;
21 parameter E    = 3'd5;
22 /****************************************/
23 reg [2:0] crt_state,nxt_state;
24 always @(posedge clk or negedge rst_n)
25 begin
26     if(!rst_n)
27         crt_state <= IDLE;
28     else
29         crt_state <= nxt_state;
30 end
31 /****************************************/
32 always @(*)
33 begin
34     case(crt_state)
35         IDLE: if(x_in) nxt_state = A;
36               else nxt_state = IDLE;
37               
38         A   : if(!x_in) nxt_state = B;
39               else nxt_state = A;
40               
41         B   : if(!x_in) nxt_state = C;
42               else nxt_state = A;
43               
44         C   : if(x_in) nxt_state = D;
45               else nxt_state = IDLE;
46         
47         D   : if(!x_in) nxt_state = E;
48               else nxt_state = A;
49         
50         E   : if(!x_in) nxt_state = C;
51               else nxt_state = A;
52         
53         default: nxt_state = IDLE;
54     endcase
55 end
56 /****************************************/
57 reg z_out_temp;
58 always @(posedge clk or negedge rst_n)
59 begin
60     if(!rst_n)
61         z_out_temp <= 1'b0;
62     else case(nxt_state)
63             IDLE   : z_out_temp <= 1'b0;
64             A      : z_out_temp <= 1'b0;
65             B      : z_out_temp <= 1'b0;
66             C      : z_out_temp <= 1'b0;
67             D      : z_out_temp <= 1'b0;
68             E      : z_out_temp <= 1'b1;
69             default: z_out_temp <= 1'b0;
70         endcase
71 end
72 /****************************************/
73 assign z_out = z_out_temp;
74 /****************************************/
75 endmodule

sequence_detect_top.v

 1 `timescale 1ns / 10ps
 2 module sequence_detect_top;
 3 reg clk;
 4 reg rst_n;
 5 reg [17:0] data;
 6 wire x_in;
 7 wire z_out;
 8 /***********************************************************/
 9 initial
10 begin
11     clk = 1'b0;
12     rst_n = 1'b0;
13     #100;
14     rst_n = 1'b1;
15 end
16 /***********************************************************/
17 always #10 clk = ~clk;
18 /***********************************************************/
19 always @(posedge clk or negedge rst_n)
20 begin
21     if(!rst_n)
22         data <= 18'b11_0010_0100_0010_0101;
23     else
24         data <= {data[16:0],data[17]};
25 end
26 /***********************************************************/
27 assign x_in = data[17];
28 /***********************************************************/
29 sequence_detect  sequence_detect_inst(
30                                         //input
31                                         .clk(clk),
32                                         .rst_n(rst_n),
33                                         .x_in(x_in),
34                                        
35                                         //ouput
36                                         .z_out(z_out)
37                                      );
38 /***********************************************************/
39 endmodule

5、仿真波形:

仅当crt_state在E状态(5)时,z_out置1。通过波形可以看到,输出是正确的。

 

 

 

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

三段式状态机是指在Verilog HDL中,使用三个always块来实现状态机的设计方法。其中,第一个always块用于状态转移,第二个always块用于状态转移条件的判断,第三个always块用于输出状态。这种设计方法的优势在于代码结构清晰,易于维护。 序列检测是指在输入序列检测是否存在某个特定的序列。在三段式状态机中,可以使用Moore型状态机来实现序列检测。Moore型状态机的输出仅与当前状态有关,因此输出和状态可以写在一起。具体实现方法是,在第三个always块中,根据当前状态输出相应的值,然后在第二个always块中判断输入序列是否匹配特定的序列,如果匹配则进行状态转移。 下面是一个简单三段式状态机代码实现,用于检测输入序列"1010": ``` module sequence_detector( input clk, input reset, input data, output reg match ); reg [1:0] state; parameter S0 = 2'b00; parameter S1 = 2'b01; parameter S2 = 2'b10; parameter S3 = 2'b11; always @(posedge clk, posedge reset) begin if (reset) begin state <= S0; end else begin case (state) S0: if (data) state <= S1; else state <= S0; S1: if (!data) state <= S2; else state <= S1; S2: if (data) state <= S3; else state <= S0; S3: if (!data) begin state <= S0; match <= 1; end else begin state <= S1; match <= 0; end endcase end end endmodule ``` 在这个代码中,第一个always块用于状态转移,第二个always块用于判断输入序列,第三个always块用于输出状态。当输入序列匹配"1010"时,输出match信号为1,否则为0。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值