【HDLBits刷题笔记】Exams/ece241 2013 q4

【HDLBits刷题笔记】Exams/ece241 2013 q4
【HDLBits刷题笔记】Exams/ece241 2013 q4_第1张图片
Also include an active-high synchronous reset that resets the state machine to a state equivalent to if the water level had been low for a long time (no sensors asserted, and all four outputs asserted).

下面是第一种写法,按状态机的思路写的,引入了记录上一次状态的寄存器,画状态图的时候上一状态可以作为输入。代码写得这么飘逸,不确定能不能综合。

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output reg fr3,
    output reg fr2,
    output reg fr1,
    output reg dfr
); 

parameter				BELOW_S1 = 0;
parameter				BETWEEN_S2_S1 = 2;
parameter				BETWEEN_S3_S2 = 4;
parameter				ABOVE_S3 = 5;

reg [3:0]				state,next_state,last_state;

always@(posedge clk) begin
	if(reset) begin
		state <= BELOW_S1;
	end
	else begin
		state <= next_state;
		last_state <= state;
	end
end

always@(*) begin
	case(state)
		BELOW_S1:
			case(s)
				3'b000: next_state = BELOW_S1;
				3'b001: next_state = BETWEEN_S2_S1;
				default: next_state = BETWEEN_S2_S1;
			endcase
		BETWEEN_S2_S1:
			case(s)
				3'b001: next_state = BETWEEN_S2_S1;
				3'b000: next_state = BELOW_S1;
				3'b011: next_state = BETWEEN_S3_S2;
				default: next_state = BETWEEN_S3_S2;
			endcase
		BETWEEN_S3_S2:
			case(s)
				3'b011: next_state = BETWEEN_S3_S2;
				3'b001: next_state = BETWEEN_S2_S1;
				3'b111: next_state = ABOVE_S3;
				default: next_state = BETWEEN_S2_S1;
			endcase
		ABOVE_S3:
			case(s)
				3'b111: next_state = ABOVE_S3;
				3'b011: next_state = BETWEEN_S3_S2;
				default: next_state = BETWEEN_S3_S2;
			endcase
	endcase
end

always@(*) begin
	case(state)
		BELOW_S1: begin
			fr1 = 1; fr2 = 1; fr3 = 1; dfr = 1;
		end
		BETWEEN_S2_S1: begin
			fr1 = 1; fr2 = 1; fr3 = 0;
			if(last_state == BETWEEN_S3_S2) begin
				dfr = 1;
			end
			else if(last_state == BETWEEN_S2_S1) begin
				dfr = dfr;
			end
			else begin
				dfr = 0;
			end
		end
		BETWEEN_S3_S2: begin
			fr1 = 1; fr2 = 0; fr3 = 0;
			if(last_state == ABOVE_S3) begin
				dfr = 1;
			end
			else if(last_state == BETWEEN_S3_S2) begin
				dfr = dfr;
			end
			else begin
				dfr = 0;
			end
		end
		ABOVE_S3: begin
			fr1 = 0; fr2 = 0; fr3 = 0; dfr = 0;
		end
	endcase
end

endmodule

第二种写法
罗列出全部状态,然后按状态图写的,为了省事,用输出为状态编码,状态的编码就是相应状态的输出。
【HDLBits刷题笔记】Exams/ece241 2013 q4_第2张图片

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 

parameter				S0 = 4'b0111;		//状态不存在
parameter				S1 = 4'b1111;
parameter				S2 = 4'b0110;
parameter				S3 = 4'b1110;
parameter				S4 = 4'b0100;
parameter				S5 = 4'b1100;
parameter				S6 = 4'b0000;
parameter				S7 = 4'b1000;		//状态不存在

reg [3:0]				state,next_state;
reg [3:0]				out;

assign	{dfr,fr1,fr2,fr3} = out;

always@(posedge clk) begin
	if(reset) begin
		state <= S1;
	end
	else begin
		state <= next_state;
	end
end

always@(*) begin
	case(state)
		S1: next_state <= ((~s[3])&(~s[2])&s[1])?S2:S1;
		S2: next_state <= ((~s[3])&(~s[2])&(~s[1]))?S1:((~s[3])&(s[2])&(s[1]))?S4:S2;
		S3: next_state <= ((~s[3])&(~s[2])&(~s[1]))?S1:(((~s[3])&s[2]&s[1]))?S4:S3;
		S4: next_state <= ((~s[3])&(~s[2])&s[1])?S3:(s[3]&s[2]&s[1])?S6:S4;
		S5: next_state <= ((~s[3])&(~s[2])&s[1])?S3:(s[3]&s[2]&s[1])?S6:S5;
		S6: next_state <= ((~s[3])&s[2]&s[1])?S5:S6;
		default: next_state <= S1;
	endcase
end

always@(*) begin
	case(state)
		S1: out = S1;
		S2: out = S2;
		S3: out = S3;
		S4: out = S4;
		S5: out = S5;
		S6: out = S6;
	endcase
end

endmodule

你可能感兴趣的:(fpga开发)