FPGA学习笔记-------状态机结构01

时序检测模块
理解4段状态机的思路

//四段状态机
//第一段
//一个always模块采用同步时序的方式描述状态转移
always @(posedge clk or negedge rst_n)
	begin 
		if(!rst_n == 1'b0)
			begin
				state_c <= HEAD;
			end
		else 
			begin 
				state_c <= state_n;
			end
	end

//第二段
//一个always采用组合逻辑的方式判断状态转移条件
always @(*)
	begin
		case(state_c)
			HEAD:
				begin
					if(hea2typ_start)
						begin
							state_n = TYPE;
						end
					else
						begin
							state_n = state_c;
						end
				end
			TYPE:
				begin
					if(typ2len_start)
						begin
							state_n = LEN;
						end
					else if(typ2dat_start)
						begin
							state_n = DATA;
						end
					else
						begin
							state_n = state_c;
						end
				end
			LEN:
				begin
					if(len2dat_start)
						begin
							state_n = DATA;
						end
					else
						begin
							state_n = state_c;
						end
				end
			DATA:
				begin
					if(dat2fcs_start)
						begin
							state_n = FCS;
						end
					else
						begin
							state_n = state_c;
						end
				end
			FCS:
				begin
					if(fcs2hea_start)
						begin
							state_n = HEAD;
						end
					else
						begin
							state_n = state_c;
						end
				end
		endcase
	end

//第三段
//用assign定义转移条件。注意一定要加上现态
assign hea2typ_start = state_c == HEAD && din_ff0 == 8'h55 && din == 8'hd5;
assign typ2len_start = state_c == TYPE && din != 0;
assign len2dat_start = state_c == LEN && end_cnt;
assign typ2dat_start = state_c == TYPE && din = 0;
assign dat2fcs_start = state_c == DATA && end_cnt;
assign fcs2hea_start = state_c == FCS && end_cnt;

//第四段
//采用同步时序电路设计每一个状态的输出
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				cnt <= 1'b0;
			end
		else if(add_cnt)
			begin
				if(end_cnt)
					begin
						cnt <= 1'b0;
					end
				else				
					begin
						cnt <= cnt + 1'b1;
					end
			end					
	end
assign add_cnt = state_c != HEAD;
assign end_cnt = add_cnt && cnt = x - 1;
	
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				din_ff0 <= 0;
			end
		else 
			begin
				din_ff0 <= din;
			end
	end

always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin	
				length <= 0;
			end
		else if(state_c == LEN)
			begin
				length <= {length[7:0],din};  //length为最大计数65535的16位计数器
			end
	end

always @(*)
	begin
		if(state_c == LEN)
			x = 2;
		else if(state_c == DATA)
			x = length;
		else if(state_c == TYPE)
			x = 1;
		else 
			x = 4;
	end

always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				dout <= 1'b0;
			end
		else 
			begin
				dout <= din;
			end
	end
	
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				dout_sop <= 1'b0;
			end
		else if(state_c == TYPE)
			begin
				dout_sop <= 1'b1;
			end
		else 
			begin
				dout_sop <= 1'b0;
			end
	end
	
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				dout_eop <= 1'b0;
			end
		else if(state_c == FCS && end_cnt)
			begin
				dout_eop <= 1'b1;
			end
		else 
			begin
				dout_eop <= 1'b0;
			end
	end
	
always @(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			begin
				dout_vld <= 1'b0;
			end
		else if(state_c != HEAD)
			begin
				dout_vld <= 1'b1;
			end
		else 
			begin
				dout_vld <= 1'b0;
			end
	end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值