序列检测器二
101101序列检测器
module seqdet ( input wire x, input wire clk, input wire rst_n, output reg z ); //用verilog设计一个 101101 序列的检测器 reg [4:0] cs,ns; localparam [4:0] IDLE =5'd0, A =5'd1, B =5'd2, C =5'd3, D =5'd4, E =5'd5, F =5'd6; //状态转移 always @ (posedge clk,negedge rst_n) if(!rst_n) cs <= IDLE; else cs <= ns; //组合逻辑,产生下一状态译码逻辑,判断条件为cs当前状态 always @ (*) begin ns = 5'bx; case(cs) IDLE: begin if(x==1) ns = A; else ns = IDLE; end A: begin if(x==0) ns = B; else ns = A; end B: begin if(x==1) ns = C; else ns = IDLE; end C: begin if(x==1) ns = D; else ns = B; end D: begin if(x==0) ns = E; else ns = A; end E: begin if(x==1) ns = F; else ns = IDLE; end F: begin if(x==1) ns = D; else ns = B; end default: ns = IDLE; endcase end //第三段always--状态寄存输出,判断条件是ns即下一个状态 always @ (posedge clk,negedge rst_n) begin if(!rst_n) z <= 1'b0; else begin case(ns) IDLE,A,B,C,D,E : z <= 1'b0; F : z <= 1'b1; default: z <= 1'b0; endcase end end //assign z = (ns==F); endmodule
特别注意,在三段式FSM描述中,判断状态转移的always模块的case语句判断条件是cs,而在同步时序FSM的寄存输出的always模块中的case语句判断条件是下一个状态ns。
测试代码:
`timescale 1ns/1ns
module seqdet_tb;
localparam T =20;
reg clk,rst;
reg [23:0] data;
wire z,x;
//wire [4:0] q;
assign x = data[23];
initial
begin
clk =0;
rst =1;
#2 rst =0;
#30 rst =1;
data =20'b1000_1101_0110_1011_0100;
#(T*1000) $stop;
end
always #T clk = ~clk;
always @ (posedge clk)
#2 data = {data[22:0],data[23]};
seqdet U1
(
.x(x),
.z(z),
.clk(clk),
// .q(q),
.rst_n(rst)
);
endmodule


最后的输出Z被寄存了,故而输出相对延迟了一个时钟周期
若最后的输出代码改为:
module seqdet ( input wire x, input wire clk, input wire rst_n, output wire z ); //用verilog设计一个 101101 序列的检测器 reg [4:0] cs,ns; localparam [4:0] IDLE =5'd0, A =5'd1, B =5'd2, C =5'd3, D =5'd4, E =5'd5, F =5'd6; //状态转移 always @ (posedge clk,negedge rst_n) if(!rst_n) cs <= IDLE; else cs <= ns; //组合逻辑,产生下一状态译码逻辑,判断条件为cs当前状态 always @ (*) begin ns = 5'bx; case(cs) IDLE: begin if(x==1) ns = A; else ns = IDLE; end A: begin if(x==0) ns = B; else ns = A; end B: begin if(x==1) ns = C; else ns = IDLE; end C: begin if(x==1) ns = D; else ns = B; end D: begin if(x==0) ns = E; else ns = A; end E: begin if(x==1) ns = F; else ns = IDLE; end F: begin if(x==1) ns = D; else ns = B; end default: ns = IDLE; endcase end //第三段always--状态寄存输出,判断条件是ns即下一个状态 /* always @ (posedge clk,negedge rst_n) begin if(!rst_n) z <= 1'b0; else begin case(ns) IDLE,A,B,C,D,E : z <= 1'b0; F : z <= 1'b1; default: z <= 1'b0; endcase end end */ assign z = (ns==F); endmodule


路漫漫其修远兮,吾将上下而求索
浙公网安备 33010602011771号