HDLBits 状态机练习题目 water reservoir 蓄水池控制器

在这里插入图片描述
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).

题目地址:Exams/ece241 2013 q4 - HDLBits

一、不用状态机

我觉得不用状态机是比较简单的,只不过要多费点脑子,我是画状态图时想出来的。

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

always @(posedge clk) begin
    if (reset == 1'b1)
        {fr1, fr2, fr3} <= 3'b111;
    else begin
        fr1 <= (s == 3'b000) | (s == 3'b001) | (s == 3'b011);
        fr2 <= (s == 3'b000) | (s == 3'b001);
        fr3 <= (s == 3'b000);
    end
end

reg [3:1] s_prev; // 记录之前的水位
always @(posedge clk) begin
    if (reset == 1'b1)
        s_prev <= 3'b000;
    else
        s_prev <= s;
end

// 水位越高,s越大
// 之前的水位比现在的水位高,则dfr打开
always @(posedge clk) begin
    if (reset == 1'b1)
        dfr <= 1'b1;
    else
        dfr <= (s_prev > s) ? 1'b1 :
               (s_prev < s) ? 1'b0 : dfr;
end

endmodule

二、官方给的参考答案

在这里插入图片描述

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


	// Give state names and assignments. I'm lazy, so I like to use decimal numbers.
	// It doesn't really matter what assignment is used, as long as they're unique.
	// We have 6 states here.
	parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
	reg [2:0] state, next;		// Make sure these are big enough to hold the state encodings.
	


    // Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.	
	always @(posedge clk) begin
		if (reset) state <= A2;
		else state <= next;
	end



    // Combinational always block for state transition logic. Given the current state and inputs,
    // what should be next state be?
    // Combinational always block: Use blocking assignments.    
	always@(*) begin
		case (state)
			A2: next = s[1] ? B1 : A2;
			B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
			B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
			C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
			C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
			D1: next = s[3] ? D1 : C2;
			default: next = 'x;
		endcase
	end
	
	
	
	// Combinational output logic. In this problem, a procedural block (combinational always block) 
	// is more convenient. Be careful not to create a latch.
	always@(*) begin
		case (state)
			A2: {fr3, fr2, fr1, dfr} = 4'b1111;
			B1: {fr3, fr2, fr1, dfr} = 4'b0110;
			B2: {fr3, fr2, fr1, dfr} = 4'b0111;
			C1: {fr3, fr2, fr1, dfr} = 4'b0010;
			C2: {fr3, fr2, fr1, dfr} = 4'b0011;
			D1: {fr3, fr2, fr1, dfr} = 4'b0000;
			default: {fr3, fr2, fr1, dfr} = 'x;
		endcase
	end
	
endmodule

三、自己写的状态机

对比一下状态图可以发现,其实差不多,的确参考答案更精简一点。

在这里插入图片描述

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

parameter START = 3'd0, W1 = 3'd1, W2 = 3'd2, W3 = 3'd3, W4 = 3'd4, W5 = 3'd5, W6 = 3'd6, W7 = 3'd7;

reg [2:0] curr_state, next_state;

always @(posedge clk) begin
    if (reset == 1'b1)
        curr_state <= START;
    else
        curr_state <= next_state;
end

always @(*) begin
    case (curr_state)
        START: next_state = (s == 3'b000) ? W1 :
                         (s == 3'b001) ? W2 :
                         (s == 3'b011) ? W3 :
                         (s == 3'b111) ? W4 : START;
        W1: next_state = (s == 3'b001) ? W2 : W1;
        W2: next_state = (s == 3'b011) ? W3 : 
                         (s == 3'b000) ? W5 : W2;
        W3: next_state = (s == 3'b111) ? W4 : 
                         (s == 3'b001) ? W6 : W3;
        W4: next_state = (s == 3'b011) ? W7 : W4;
        W5: next_state = (s == 3'b001) ? W2 : W5;
        W6: next_state = (s == 3'b011) ? W3 :
                         (s == 3'b000) ? W5 : W6;
        W7: next_state = (s == 3'b111) ? W4 : 
                         (s == 3'b001) ? W6 : W7;
    endcase
end

always @(*) begin
    case (curr_state)
        START: {fr3, fr2, fr1, dfr} = 4'b1111;
        W1: {fr3, fr2, fr1, dfr} = 4'b1110;
        W2: {fr3, fr2, fr1, dfr} = 4'b0110;
        W3: {fr3, fr2, fr1, dfr} = 4'b0010;
        W4: {fr3, fr2, fr1, dfr} = 4'b0000;
        W5: {fr3, fr2, fr1, dfr} = 4'b1111;
        W6: {fr3, fr2, fr1, dfr} = 4'b0111;
        W7: {fr3, fr2, fr1, dfr} = 4'b0011;
    endcase
end
endmodule

三种方法的比较 Vivado

不用状态机

elab电路图(综合的电路图可读性差)
在这里插入图片描述
综合出的资源占用情况
在这里插入图片描述

参考答案的状态机

在这里插入图片描述
在这里插入图片描述

自己写的状态机

在这里插入图片描述
在这里插入图片描述

结论:对比综合后的资源占用,好像都差不多的样子。LUT/FF的数量分别是 5/7, 6/6, 7/3

三种方法的比较 Quartus

不用状态机

在这里插入图片描述

参考答案的状态机

在这里插入图片描述

Quartus的RTL Viewer把状态机单独识别出来,很贴心了。

在这里插入图片描述

自己写的状态机

在这里插入图片描述

在这里插入图片描述

结论:Quartus综合结果和Vivado的差别蛮大的。我自己的状态机比较糟糕,不用状态机最好。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值