序列检测器(Moore型)
描述
请用Moore型状态机实现序列"1101"从左至右的不重叠检测 。
电路的接口如下图所示。当检测到"1101 ",Y输出一个时钟周期的高电平脉冲。
接口电路图如下:
输入描述:
input clk ,
input rst_n ,
input din ,
输出描述:
output reg Y
解题思路
我们给出以下两种解题思路
- Moore型状态机
- 一般时序逻辑电路
Moore型状态机
moore型状态机的输出仅依赖于当前状态而与输入无关;
设置以下状态:
IDLE(S0):初始状态,表示电路还没有收到任何一个有效数值
S1 :表示电路收到了一个有效的"1";
S2 :表示电路收到了两个连续有效数据"11";
S3 :表示电路收到了三个连续有效数据"110";
S4 :表示电路收到了四个连续有效数据"1101";
原始状态图
根据题目中要求*"当检测到"1101",Y输出一个时钟周期的高电平脉冲。"* ,画出其(Moore型)原始状态图:
原始状态表
对应地,给出其原始状态表:
采用状态机三段式写法:
代码如下:
cpp
`timescale 1ns/1ns
module det_moore(
input clk ,
input rst_n ,
input din ,
output reg Y
);
reg [3:0] current_state, next_state;
parameter [3:0] IDLE =4'b0000;
parameter [3:0] S1 =4'b0001;
parameter [3:0] S2 =4'b0011;
parameter [3:0] S3 =4'b0110;
parameter [3:0] S4 =4'b1101;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) current_state <= IDLE;
else current_state <= next_state;
end
always @(*) begin
case (current_state)
IDLE: begin if(din == 1'b1) next_state = S1; else next_state = IDLE; end
S1: begin if(din == 1'b1) next_state = S2; else next_state = IDLE; end
S2: begin if(din == 1'b0) next_state = S3; else next_state = S2; end
S3: begin if(din == 1'b1) next_state = S4; else next_state = S3; end
S4: begin if(din == 1'b1) next_state = S1; else next_state = IDLE; end
default: next_state = IDLE;
endcase
end
//输出Y仅与当前状态S有关,与输入din取值无关
always @(posedge clk or negedge rst_n) begin
if (!rst_n) Y = 1'b0;
else begin
case (current_state)
IDLE: Y = 1'b0;
S1: Y = 1'b0;
S2: Y = 1'b0;
S3: Y = 1'b0;
S4: Y = 1'b1;
default:Y = 1'b0;
endcase
end
end
endmodule
一般时序逻辑电路设计方法
二进制状态表
将状态S0~S4 进行依次编号,即:000~100 ;因此,可将上述的原始状态表化为如下所示的二进制状态表:
卡诺图
根据二进制状态表画出次态卡诺图:
确定激励函数和输出函数
代码如下:
cpp
`timescale 1ns/1ns
module det_moore(
input clk ,
input rst_n ,
input din ,
output reg Y
);
//代码二
wire d0,d1,d2,q0,q1,q2;
assign d2 = din&q0&q1&~q2;
assign d1 = din&q0&~q1&~q2 | ~q0&q1&~q2;
assign d0 = ~din&~q0&q1&~q2 | din&~q0&~q1;
assign y = ~q0&~q1&q2;
DFF D0(.clk(clk), .rst_n(rst_n), .D(d0), .Q(q0));
DFF D1(.clk(clk), .rst_n(rst_n), .D(d1), .Q(q1));
DFF D2(.clk(clk), .rst_n(rst_n), .D(d2), .Q(q2));
always @(posedge clk or negedge rst_n) begin
if (!rst_n) Y <= 1'b0;
else Y = ~q0&~q1&q2;
end
endmodule
module DFF(
input clk ,
input rst_n ,
input D ,
output reg Q
);
always@(posedge clk or negedge rst_n) begin
if (!rst_n) Q <= 1'b0;
else Q <= D;
end
endmodule