解题思路
经典三段式,没啥花里胡哨的。 但需要注意几个细节:
①中间段采用的组合逻辑实现,可以有一些冗余状态,如ONE_HALF、TWO、TWO_HALF、THREE这些,是为了输出的时候书写方便。当然简化为只有3个状态(IDLE、HALF、ONE)也是完全可以的,只是输出要麻烦一点,可以参考我的另一篇类似题目的题解(#自动售卖机#),采用了状态简化。
②这种有冗余状态的三段式的第三段输出,状态判断需要用next_state,而不是state。
代码实现
`timescale 1ns/1ns
module seller1(
input wire clk ,
input wire rst ,
input wire d1 ,
input wire d2 ,
input wire d3 ,
output reg out1 ,
output reg [1:0] out2
);
reg [2:0] state, next_state;
parameter IDLE = 3'd0;
parameter HALF = 3'd1;
parameter ONE = 3'd2;
parameter ONE_HALF = 3'd3;
parameter TWO = 3'd4;
parameter TWO_HALF = 3'd5;
parameter THREE = 3'd6;
//第一段:状态跳转
always@(posedge clk or negedge rst) begin
if(!rst)
state <= IDLE;
else
state <= next_state;
end
//第二段:状态转移(与输入的关系)
always@(*) begin
case(state)
IDLE : next_state = d1 ? HALF :(d2 ? ONE : (d3? TWO : next_state));
HALF : next_state = d1 ? ONE :(d2 ? ONE_HALF : (d3? TWO_HALF : next_state));
ONE : next_state = d1 ? ONE_HALF :(d2 ? TWO : (d3? THREE : next_state));
ONE_HALF ,
TWO ,
TWO_HALF ,
THREE : next_state = IDLE;
default : next_state = IDLE;
endcase
end
//第三段:输出(out1)
always@(posedge clk or negedge rst) begin
if(!rst)
out1 <= 1'b0;
else if((next_state == ONE_HALF)||(next_state == TWO)||(next_state == TWO_HALF)||(next_state == THREE))
out1 <= 1'b1;
else
out1 <= 1'b0;
end
//第三段:输出(out2)
always@(posedge clk or negedge rst) begin
if(!rst)
out2 <= 2'd0;
else if(next_state == TWO)
out2 <= 2'd1;
else if(next_state == TWO_HALF)
out2 <= 2'd2;
else if(next_state == THREE)
out2 <= 2'd3;
else
out2 <= 2'd0;
end
endmodule