题解主体
1、确定题目要求
根据输入,有两种状态转移:
1.5:
0 0.5 1 1.5 2 S0-S4
现态 |
d1 |
d2 |
|||
现态值 |
现态代号 |
次态值 |
次态代号 |
次态值 |
次态代号 |
0 |
S0 |
0.5 |
S1 |
1 |
S2 |
0.5 |
S1 |
1 |
S2 |
1.5 O3=0 |
S3 |
1 |
S2 |
1.5 O3=0 |
S3 |
2 O3=1 |
S4 |
1.5 |
S3 |
||||
2 |
S4 |
蓝色格子代表输出
注意没有写输入为0,对于输入为0非蓝色格子状态保持,对于蓝色格子,状态转移至S0
2.5:
0 0.5 1 1.5 2 2.5 3 S0-S6
现态 |
d1 |
d2 |
|||
现态值 |
现态代号 |
次态值 |
次态代号 |
次态值 |
次态代号 |
0 |
S0 |
0.5 |
S1 |
1 |
S2 |
0.5 |
S1 |
1 |
S2 |
1.5 |
S3 |
1 |
S2 |
1.5 |
S3 |
2 |
S4 |
1.5 |
S3 |
2 |
S4 |
2.5 |
S5 |
2 |
S4 |
2.5 |
S5 |
3 |
S6 |
2.5 |
S5 |
||||
3 |
S6 |
蓝色格子代表输出
注意没有写输入为0,对于输入为0非蓝色格子状态保持,对于蓝色格子,状态转移至S0
2、按照状态转移写出三段式状态机
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 [1:0] input_state;
assign input_state = {d1,d2};
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
if (!sel) begin
case(current_state)
S0:begin
case(input_state)
2'b10 :next_state = S1 ;
2'b01 :next_state = S2 ;
default:next_state = next_state;
endcase
end
S1:begin
case(input_state)
2'b10 :next_state = S2 ;
2'b01 :next_state = S3 ;
default:next_state = next_state;
endcase
end
S2:begin
case(input_state)
2'b10 :next_state = S3 ;
2'b01 :next_state = S4 ;
default:next_state = next_state;
endcase
end
default: next_state = S0;
endcase
end
else begin
case(current_state)
S0:begin
case(input_state)
2'b10 :next_state = S1 ;
2'b01 :next_state = S2 ;
default:next_state = next_state;
endcase
end
S1:begin
case(input_state)
2'b10 :next_state = S2 ;
2'b01 :next_state = S3 ;
default:next_state = next_state;
endcase
end
S2:begin
case(input_state)
2'b10 :next_state = S3 ;
2'b01 :next_state = S4 ;
default:next_state = next_state;
endcase
end
S3:begin
case(input_state)
2'b10 :next_state = S4 ;
2'b01 :next_state = S5 ;
default:next_state = next_state;
endcase
end
S4:begin
case(input_state)
2'b10 :next_state = S5 ;
2'b01 :next_state = S6 ;
default:next_state = next_state;
endcase
end
default: next_state = S0;
endcase
end
end
always@(posedge clk or negedge rst)begin
if(rst == 1'b0)begin
out1 <= 1'b0;
out2 <= 1'b0;
out3 <= 1'b0;
end
else begin
if(!sel)begin
case (next_state)
S3: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b0;end
S4: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b1;end
default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end
endcase
end
else begin
case (next_state)
S5: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b0;end
S6: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b1;end
default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end
endcase
end
end
end
endmodule
参考答案
`timescale 1ns/1ns module seller2( input wire clk , input wire rst , input wire d1 , input wire d2 , input wire sel , output reg out1, output reg out2, output reg out3 ); 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 [1:0] input_state; assign input_state = {d1,d2}; 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 if (!sel) begin case(current_state) S0:begin case(input_state) 2'b10 :next_state = S1 ; 2'b01 :next_state = S2 ; default:next_state = next_state; endcase end S1:begin case(input_state) 2'b10 :next_state = S2 ; 2'b01 :next_state = S3 ; default:next_state = next_state; endcase end S2:begin case(input_state) 2'b10 :next_state = S3 ; 2'b01 :next_state = S4 ; default:next_state = next_state; endcase end default: next_state = S0; endcase end else begin case(current_state) S0:begin case(input_state) 2'b10 :next_state = S1 ; 2'b01 :next_state = S2 ; default:next_state = next_state; endcase end S1:begin case(input_state) 2'b10 :next_state = S2 ; 2'b01 :next_state = S3 ; default:next_state = next_state; endcase end S2:begin case(input_state) 2'b10 :next_state = S3 ; 2'b01 :next_state = S4 ; default:next_state = next_state; endcase end S3:begin case(input_state) 2'b10 :next_state = S4 ; 2'b01 :next_state = S5 ; default:next_state = next_state; endcase end S4:begin case(input_state) 2'b10 :next_state = S5 ; 2'b01 :next_state = S6 ; default:next_state = next_state; endcase end default: next_state = S0; endcase end end always@(posedge clk or negedge rst)begin if(rst == 1'b0)begin out1 <= 1'b0; out2 <= 1'b0; out3 <= 1'b0; end else begin if(!sel)begin case (next_state) S3: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b0;end S4: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b1;end default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end endcase end else begin case (next_state) S5: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b0;end S6: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b1;end default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end endcase end end end endmodule