校招Verilog——序列检测机【转】

一、序列检测发生器

  以产生 11010 的序列为例,设计代码如下:

 1 module seq_gen(
 2 input           clk         ,
 3 input           reset       ,
 4 output          out
 5 );
 6 
 7 reg [4:0]       shift       ;
 8 
 9 always@(posedge clk or posedge rst_n) begin
10     if(reset)
11         shift <= 5'b11010;
12     else
13         shift <= {shift[3:0], shift[4]};
14 end
15 
16 assign out = shift[4];
17     
18 endmodule

仿真结果如下:

RTL视图如下:

  用了 5 位的移位寄存器,需要 5 个触发器来实现。

 

二、序列检测机——Moore型

  检测序列1101,检测到输出为1,否则输出为0。

1、Moore型

(1)无重叠检测的状态转移图

  无重叠检测,即如果出现 1101101,只会检测到一个1101。

(2)Verilog代码

 1 `timescale 1ns / 1ps
 2 
 3 module seq_moore
 4 //========================< 端口 >==========================================
 5 (
 6 input                       clk             ,
 7 input                       reset           ,
 8 input                       din             ,
 9 output                      dout
10 );
11 //========================< 信号 >==========================================
12 localparam [4:0]            s0 = 5'b00001   ,
13                             s1 = 5'b00010   ,
14                             s2 = 5'b00100   ,
15                             s3 = 5'b01000   ,
16                             s4 = 5'b10000   ;
17 reg [4:0]                   state_c         ;
18 reg [4:0]                   state_n         ;
19 //==========================================================================
20 //==    状态机
21 //==========================================================================
22 always @(posedge clk, posedge reset) begin
23     if(reset)
24         state_c <= s0;
25     else
26         state_c <= state_n;
27 end
28 
29 always @(*) begin
30     case(state_c)
31         s0:
32             if(din == 1'b1)
33                 state_n = s1;
34             else
35                 state_n = s0;
36         s1:
37             if(din == 1'b1)
38                 state_n = s2;
39             else
40                 state_n = s0;
41         s2:
42             if(din == 1'b0)
43                 state_n = s3;
44             else
45                 state_n = s2;
46         s3:
47             if(din == 1'b1)
48                 state_n = s4;
49             else
50                 state_n = s0;
51         s4:
52             if(din == 1'b1)
53                 state_n = s1;
54             else
55                 state_n = s0;
56         default:
57                 state_n = s0;
58     endcase
59 end
60 //==========================================================================
61 //==    结果输出
62 //==========================================================================
63 assign dout = (state_c == s4) ? 1'b1 : 1'b0;
64 
65 
66 endmodule

(3)有重叠检测

  无重叠检测,即如果出现 1101101,会检测到两个1101。只需要将无重叠检测的状态转移图里的 S4 状态转移到 S2 状态即可,代码也是。

 

2、mealy型

(1)无重叠检测的状态转移图

  无重叠检测,即如果出现 1101101,只会检测到一个1101。

(2)Verilog代码

 1 `timescale 1ns / 1ps
 2 
 3 module seq_mealy
 4 //========================< 端口 >==========================================
 5 (
 6 input                       clk             ,
 7 input                       reset           ,
 8 input                       din             ,
 9 output                      dout
10 );
11 //========================< 信号 >==========================================
12 localparam [3:0]            s0 = 4'b0001    ,
13                             s1 = 4'b0010    ,
14                             s2 = 4'b0100    ,
15                             s3 = 4'b1000    ;
16 reg [3:0]                   state_c         ;
17 reg [3:0]                   state_n         ;
18 //==========================================================================
19 //==    状态机
20 //==========================================================================
21 always @(posedge clk, posedge reset) begin
22     if(reset)
23         state_c <= s0;
24     else
25         state_c <= state_n;
26 end
27 
28 always @(*) begin
29     case(state_c)
30         s0:
31             if(din == 1'b1)
32                 state_n = s1;
33             else
34                 state_n = s0;
35         s1:
36             if(din == 1'b1)
37                 state_n = s2;
38             else
39                 state_n = s0;
40         s2:
41             if(din == 1'b0)
42                 state_n = s3;
43             else
44                 state_n = s2;
45         s3:
46                 state_n = s0;
47         default:
48                 state_n = s0;
49     endcase
50 end
51 //==========================================================================
52 //==    结果输出
53 //==========================================================================
54 assign dout = ((state_c==s3) && (din==1'b1)) ? 1'b1 : 1'b0;
55 
56 
57 endmodule

(3)有重叠检测

  即如果出现 1101101,会检测到两个1101。只需要将无重叠检测的状态转移图里的 S3 状态转移到 S2 状态即可,代码也是。

 

三、例题1

  有“101”序列输入时,输出为 1,其他输入情况下,输出为 0.画出状态转移图,并用 verilog 描述。
 1 `timescale 1ns / 1ps
 2 
 3 module seq_detect
 4 //========================< 端口 >==========================================
 5 (
 6 input                       clk             ,
 7 input                       reset           ,
 8 input                       din             ,
 9 output                      dout
10 );
11 //========================< 信号 >==========================================
12 localparam [3:0]            s0 = 4'b0001    ,
13                             s1 = 4'b0010    ,
14                             s2 = 4'b0100    ,
15                             s3 = 4'b1000    ;
16 reg [3:0]                   state_c         ;
17 reg [3:0]                   state_n         ;
18 //==========================================================================
19 //==    状态机
20 //==========================================================================
21 always @(posedge clk, posedge reset) begin
22     if(reset)
23         state_c <= s0;
24     else
25         state_c <= state_n;
26 end
27 
28 always @(*) begin
29     case(state_c)
30         s0:
31             if(din == 1'b1)
32                 state_n = s1;
33             else
34                 state_n = s0;
35         s1:
36             if(din == 1'b0)
37                 state_n = s2;
38             else
39                 state_n = s1;
40         s2:
41             if(din == 1'b1)
42                 state_n = s3;
43             else
44                 state_n = s0;
45         s3:
46             if(din == 1'b1)
47                 state_n = s1;
48             else
49                 state_n = s2;
50         default:
51                 state_n = s0;
52     endcase
53 end
54 //==========================================================================
55 //==    结果输出
56 //==========================================================================
57 assign dout = (state_c==s3) ? 1'b1 : 1'b0;
58 
59 
60 endmodule

 

四、例题2

  输入口是1bit,每次进来一位数据,检查当前序列是否能整除3,能则输出1,否则输出0。

  答案参考博客:https://www.cnblogs.com/lyc-seu/p/12768321.html

 

参考资料:

https://blog.csdn.net/Reborn_Lee

posted @ 2020-08-17 20:52  咸鱼IC  阅读(2196)  评论(0编辑  收藏  举报