FPGA三段式状态机
某同步时序电路的状态转换图如下,→上表示“C/Y”,圆圈内为现态,→指向次态。
请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。
电路的接口如下图所示,C是单bit数据输入端。
答:利用三段式状态机,本题牛客上最后使用组合逻辑描述输出,博主感觉应该用时序来描述输出。如大家有知道的,望解答。
module seq_circuit(
input C ,
input clk ,
input rst_n,
output wire Y
);
localparam Inital_state = 2'b00; // 定义初状态
// 各种状态定义
localparam S00 = 2'b00;
localparam S01 = 2'b01;
localparam S10 = 2'b10;
localparam S11 = 2'b11;
reg next_Y = 0;
reg current_Y = 0;
reg [1:0] current_state; //定义现态寄存器
reg [1:0] next_state; //定义现态寄存器
//-----------------------------------------------------------------------
//--状态机第一段:同步时序描述状态转移
//-----------------------------------------------------------------------
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
current_state <= Inital_state;
end
else
current_state <= next_state;
end
//-----------------------------------------------------------------------
//--状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
//-----------------------------------------------------------------------
always @(*) begin
case (current_state)
S00: begin
if (C) begin
next_state = S01;
end
else begin
next_state = S00;
end
end
S01: begin
if (C) begin
next_state = S01;
end
else begin
next_state = S11;
end
end
S10: begin
if (C) begin
next_state = S10;
end
else begin
next_state = S00;
end
end
S11: begin
if (C) begin
next_state = S10;
end
else begin
next_state = S11;
end
end
default: begin
next_state = Inital_state;
end
endcase
end
//-----------------------------------------------------------------------
//--状态机第三段:时序逻辑描述输出
//-----------------------------------------------------------------------
// always @(posedge clk or negedge rst_n) begin
// if (!rst_n) begin
// current_Y <= 0;
// end
// else begin
// case(next_state)
// S00: current_Y <= 1'b0;
// S01: current_Y <= 1'b0;
// S11: current_Y <= 1'b1;
// S10:begin
// if(C) // 与输入有关
// current_Y <= 1'b1;
// else
// current_Y <= 1'b0;
// end
// default:current_Y <= 0;
// endcase
// end
// end
always @(*) begin
if (!rst_n) begin
current_Y = 0;
end
else begin
case(current_state)
S00: current_Y = 1'b0;
S01: current_Y = 1'b0;
S11: current_Y = 1'b1;
S10:begin
if(C) // 与输入有关
current_Y = 1'b1;
else
current_Y = 1'b0;
end
default:current_Y = 0;
endcase
end
end
assign Y = current_Y;
endmodule