底层原理,  技术人生

Verilog实现FSM有限状态机

本文使用Verilog搭建一个基础的FSM有限状态机。该FSM仅包含控制模块,无数据链路。

程序要求:

输入:h,reset信号,时钟信号

输出:q

FSM状态转换示意图:

FSM状态转换图

该状态机将在接收到连续的3个h信号“1,0,1”后输出q高电平,其他状态维持低电平。

FSM模块大致可以分为三部分:1. 根据当前状态和输入信号计算下一状态;2. 在时钟信号上升沿更新当前状态,或是在接收到reset信号后重置为初始状态;3. 根据当前状态计算输出信号。

FSM总体设计
module FSM (input R, h, CLK, output reg q);

reg [1:0] next_st, current_st;

always @ (*) //next state logic
	case (current_st)
		2'b00:	if(h == 1)	next_st = 2'b01;
				else		next_st = 2'b00;
		2'b01:	if(h == 0)	next_st = 2'b10;
				else		next_st = 2'b00;
		2'b10:	if(h == 1)	next_st = 2'b11;
				else		next_st = 2'b00;
		2'b11:	next_st = 2'b00;
		default: next_st = 2'hX;
	endcase

always @ (posedge CLK, posedge R)
	if(R)
		current_st <= 2'b00;
	else
		current_st <= next_st;

always @ (*)  // output logic
	case (current_st)
		2'b11:	q = 1;
		default: q = 0;
	endcase

endmodule

编写一个简单的测试脚本。

module mux4to1_tb();

// Internal connections
reg R, h, CLK;
wire q;

// Instantiate mu0_alu as dut (device under test)
FSM dut(R, h, CLK, q);

// Test vectors
initial
begin
CLK=0;
#100 R=1; h=0;
#100 R=0;
#100 h=1;
#100 h=0;
#100 h=1;
#100 ;


#100 $finish;   // end the simulation
end

always #50 CLK = ~CLK;
 
// Save results as VCD file 
// Do not change
initial
 begin
  $dumpfile("FSM_tb_results.vcd");  // Save simulation waveforms in this file
  $dumpvars; // Capture all simulation waveforms
 end

endmodule 

注:该脚本测试用例并不完善,理论上测试应涵盖FSM的所有数据路径。

验证输出波形可以发现输出信号q在输入信号h经历“1,0,1”的变换后在下一个时钟信号上升沿正确切换为高电平输出。

FSM输出波形

A WindRunner. VoyagingOne

留言

您的邮箱地址不会被公开。 必填项已用 * 标注