校招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
参考资料: