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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章