以下两种是用状态机实现1110010的序列检测器,采用三段式的写法,如有错误,敬请指出!
module sequen(clk,
rst,
in,
out);
input clk;
input rst;
input in;
output out;
reg[2:0] curr_state,next_state;
reg out;
parameter S0 = 3'b000,
S1 = 3'b001,
S2 = 3'b011,
S3 = 3'b010,
S4 = 3'b110,
S5 = 3'b100,
S6 = 3'b101,
S7 = 3'b111;
always@(posedge clk or negedge rst) begin
if(~rst)
curr_state <= S0;
else
curr_state <= next_state;
end
always@(*) begin
case(curr_state)
S0:begin
if(in)
next_state = S1;
else
next_state = S0;
end
S1:begin
if(in)
next_state = S2;
else
next_state = S0;
end
S2:begin
if(in)
next_state = S3;
else
next_state = S1;
end
S3:begin
if(in)
next_state = S3;
else
next_state = S4;
end
S4:begin
if(in)
next_state = S1;
else
next_state = S5;
end
S5:begin
if(in)
next_state = S6;
else
next_state = S0;
end
S6:begin
if(in)
next_state = S2;
else
next_state = S7;
end
S7:begin
if(in)
next_state = S1;
else
next_state = S0;
end
endcase
end
always@(posedge clk) begin
if(curr_state == S7)
out <= 1;
else
out <= 0;
end
endmodule
testbench
module sequentb;
reg clk ,rst;
wire out;
reg[31:0] data;
initial begin
clk = 0;
rst = 0;
data = 32'b1110_0101_1100_1011_1001_0111_1010_0000;
#100 rst = 1;
#1000000 $stop;
end
assign in = data[31];
always@(posedge clk) begin
data <= {data[30:0],data[31]};
end
always #10 clk = ~clk;
initial begin
$vcdpluson;
end
sequen u(.clk(clk),.in(in),.rst(rst),.out(out));
endmodule
仿真波形
2.
module sequen(clk,
rst,
in,
out);
input clk;
input rst;
input in;
output out;
reg[2:0] curr_state,next_state;
parameter S0 = 3'b000,
S1 = 3'b001,
S2 = 3'b011,
S3 = 3'b010,
S4 = 3'b110,
S5 = 3'b100,
S6 = 3'b101,
S7 = 3'b111;
always@(posedge clk or negedge rst) begin
if(~rst)
curr_state <= S0;
else
curr_state <= next_state;
end
always@(*) begin
case(curr_state)
S0:begin
if(in)
next_state = S1;
else
next_state = S0;
end
S1:begin
if(in)
next_state = S2;
else
next_state = S0;
end
S2:begin
if(in)
next_state = S3;
else
next_state = S1;
end
S3:begin
if(in)
next_state = S3;
else
next_state = S4;
end
S4:begin
if(in)
next_state = S1;
else
next_state = S5;
end
S5:begin
if(in)
next_state = S6;
else
next_state = S0;
end
S6:begin
if(in)
next_state = S2;
else
next_state = S7;
end
S7:begin
if(in)
next_state = S1;
else
next_state = S0;
end
endcase
end
assign out = (curr_state == S7) ? 1:0;
endmodule
testbench同上述一样,就不再赘述
在三段式的末尾,如果是采用时序逻辑电路,那么out的高电平会在序列全部检测出后跳变,如果是组合逻辑电路,那么out的高电平会和最后一位同时到达。