题解主体
1、确定题目要求
首先根据信号端口图:
考虑状态转移,需要考虑的是有三输入二输出,存在状态0 0.5 1 1.5 2 2.5 3 七个状态,
这样输出信号的特性应该为: out1饮料为一位,out2找零为2位(0 1 2 3个0.5元)
因此先做转移表格:(需要注意的是,0.5/1/2是不会同时给信号的)
现态 |
d1 |
d2 |
d3 |
||||
现态值 |
现态代号 |
次态值 |
次态代号 |
次态值 |
次态代号 |
次态值 |
次态代号 |
0 |
S0 |
0.5 |
S1 |
1 |
S2 |
2 O2=1 |
S4 |
0.5 |
S1 |
1 |
S2 |
1.5 O2=0 |
S3 |
2.5 O2=2 |
S5 |
1 |
S2 |
1.5 O2=0 |
S3 |
2 O2=1 |
S4 |
3 O2=3 |
S6 |
1.5 |
S3 |
||||||
2 |
S4 |
||||||
2.5 |
S5 |
||||||
3 |
S6 |
蓝色格子代表输出
注意没有写输入为0,对于输入为0非蓝色格子状态保持,对于蓝色格子,状态转移至S0
2、画出状态转移
3、按照状态转移写出三段式状态机
parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5 , S6 = 'd6;
reg [2:0] current_state;
reg [2:0] next_state;
wire [2:0] input_state;//将输入组合起来
assign input_state = {d1,d2,d3};
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
current_state <= S0;
end
else begin
current_state <= next_state;
end
end
always@(*)begin
case(current_state)
S0:begin
case(input_state)
3'b100:next_state = S1 ;
3'b010:next_state = S2 ;
3'b001:next_state = S4 ;
default:next_state = next_state;
endcase
end
S1:begin
case(input_state)
3'b100:next_state = S2 ;
3'b010:next_state = S3 ;
3'b001:next_state = S5 ;
default:next_state = next_state;
endcase
end
S2:begin
case(input_state)
3'b100:next_state = S3 ;
3'b010:next_state = S4 ;
3'b001:next_state = S6 ;
default:next_state = next_state;
endcase
end
default:begin
next_state = S0;
end
endcase
end
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
out1 <= 1'b0;
out2 <= 2'b0;
end
else begin
case(next_state)
S3: begin out1 <= 1'b1;out2 <= 2'b0; end
S4: begin out1 <= 1'b1;out2 <= 2'b1; end
S5: begin out1 <= 1'b1;out2 <= 2'b10; end
S6: begin out1 <= 1'b1;out2 <= 2'b11; end
default: begin out1 <= 1'b0;out2 <= 2'b0; end
endcase
end
end
参考答案
`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 ); parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5 , S6 = 'd6; reg [2:0] current_state; reg [2:0] next_state; wire [2:0] input_state;//将输入组合起来 assign input_state = {d1,d2,d3}; always@(posedge clk or negedge rst)begin if(rst == 1'b0)begin current_state <= S0; end else begin current_state <= next_state; end end always@(*)begin case(current_state) S0:begin case(input_state) 3'b100:next_state = S1 ; 3'b010:next_state = S2 ; 3'b001:next_state = S4 ; default:next_state = next_state; endcase end S1:begin case(input_state) 3'b100:next_state = S2 ; 3'b010:next_state = S3 ; 3'b001:next_state = S5 ; default:next_state = next_state; endcase end S2:begin case(input_state) 3'b100:next_state = S3 ; 3'b010:next_state = S4 ; 3'b001:next_state = S6 ; default:next_state = next_state; endcase end default:begin next_state = S0; end endcase end always@(posedge clk or negedge rst)begin if(rst == 1'b0)begin out1 <= 1'b0; out2 <= 2'b0; end else begin case(next_state) S3: begin out1 <= 1'b1;out2 <= 2'b0; end S4: begin out1 <= 1'b1;out2 <= 2'b1; end S5: begin out1 <= 1'b1;out2 <= 2'b10; end S6: begin out1 <= 1'b1;out2 <= 2'b11; end default: begin out1 <= 1'b0;out2 <= 2'b0; end endcase end end endmodule