三段式状态机的原理/代码/仿真,1001序列检测实例Verilog

状态机分为一段式,两段式以及三段式,其分类是根据module块中always语块的个数来区别。这里说的三段式其优势在于清晰容易看出状态机的结构,代码也更容易维护,因此更推荐使用。

模块结构 

下图是状态机的结构图 

最左边的模块为触发器(具有寄存功能),在Verilog中我们常用异步复位的D触发器,为时序电路,在赋值时使用非阻塞赋值。右边两个模块为组合逻辑的模块,用来描述状态的转移和最终的输出,当然,描述输出的组合逻辑模块也可用时序逻辑来写。

代码模块 

第一个always块,描述当前状态的寄存器

always@(posedge clk or negedge rst_n)
  if(!rst_n)
current_state <= idle;
        else
          current_state <= next_idle;

 第二个always块,描述下一状态

always@(*)
 case(current_state)
   idle :
	 if(…)
		next_state = …;
	 else if(…)
	   next_state = …;
   
	st_1 :
	 if(…)
	   next_state = …;
    else if(…)
	   next_state = …;
.
.
.
 default : next_state = …;
endcase;

 第三个always块,描述最后输出

组合逻辑

always@(*)
  if(!rst_n)
   output = 0;
  else begin
   case(next_state)
       st_1 : output = …;
       .
       .
       .
default : output = …;
         endcase
       end

 时序逻辑

always@(posedge clk or negedge rst_n)begin
  if(!rst_n)
    out<=0;
  else if(next_state==...)
    out<=1;
  else
    out<=0;
end

 实例:三段式状态机实现1001序列检测

1.状态转移图

 

2. 代码

 

//序列检测1001
module xuliejiance(
      input data,
		input clk,
		input rst_n,
		output reg out
    );
	 parameter idle=0;
	 parameter st_1=1;
	 parameter st_2=2;
	 parameter st_3=3;
	 parameter st_4=4;//对状态转移图中5个状态定义常数
	
	 reg[2:0] current_state;
	 reg[2:0] next_state;//5个状态需要3位二进制数
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 :
	 if(data==0)
		next_state = idle;
	 else if(data==1)
	   next_state = st_1;
   
	st_1 :
	 if(data==0)
	   next_state = st_2;
    else if(data==1)
	   next_state = st_1;
	 
   st_2 :
	 if(data==0)
	   next_state = st_3;
    else if(data==1)
	   next_state = st_1;
		
   st_3 :
    if(data==0)
	   next_state = idle;
    else if(data==1)
	   next_state = st_4;
		
		
	st_4 :
	   next_state = idle;
		
	default : next_state = idle;
 endcase
end

always@(posedge clk or negedge rst_n)begin
  if(!rst_n)
    out<=0;
  else if(next_state==st_4)
    out<=1;
  else
    out<=0;
end

endmodule

3.仿真 

module tb_xuliejiance;

	// Inputs
	reg data;
	reg clk;
	reg rst_n;

	// Outputs
	wire out;

	// Instantiate the Unit Under Test (UUT)
	xuliejiance uut (
		.data(data), 
		.clk(clk), 
		.rst_n(rst_n), 
		.out(out)
	);
always #50 clk = ~clk;
	initial begin
		// Initialize Inputs
		data = 0;
		clk = 1;
		rst_n = 0;

		// Wait 100 ns for global reset to finish
		#201;
		rst_n = 1;
		
		#100;
		data = 0;
		#100;
		data = 1;
		#100;
		data = 0;
		#100;
		data = 0;
		#100;
		data = 0;
		#100;
		data = 1;
		#100;
		data = 0;
		#100;
		data = 0;
		#100;
		data = 1;
	
		
        
		// Add stimulus here

	end
      
endmodule

 

 波形图

  • 3
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值