题目需要根据输入的信号in,和当前状态 state[9:0],输出 next_state [9:0],已经相应的输出信号,题目中给出的状态机如图所示:
有几个需要注意的点:
- 输入的状态机为独热码,即每一个状态只有一位会置位
- 本题目中不需要书写图中的独热码状态机,而是只需要根据输入的in 和 state 信号输出 next_state 和 out 信号,即相当于只需要实现状态转换逻辑和输出逻辑,不需要出现状态机寄存器
- 题目的测试用例中虽然说明了使用独热码进行输入,但是也有非独热码的输入保证你没有进行更复杂的逻辑实现(如自己写一个状态机)
首先还是写一写自己当时审题不够认真犯的错误,直接写了一个状态机,这样子功能正确,但逻辑过于复杂,对于非独热码无法处理,无法通过非独热码的测试用例代码如下:
//功能正确,但逻辑过于复杂,对于非独热码无法处理,无法通过非独热码的测试用例
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
parameter S0 = 10'b0000000001;
parameter S1 = 10'b0000000010;
parameter S2 = 10'b0000000100;
parameter S3 = 10'b0000001000;
parameter S4 = 10'b0000010000;
parameter S5 = 10'b0000100000;
parameter S6 = 10'b0001000000;
parameter S7 = 10'b0010000000;
parameter S8 = 10'b0100000000;
parameter S9 = 10'b1000000000;
always @(*) begin
case(state)
S0:begin
if(in == 1'b1) begin
next_state = S1;
end
else begin
next_state = S0;
end
end
S1:begin
if(in == 1'b1) begin
next_state = S2;
end
else begin
next_state = S0;
end
end
S2:begin
if(in == 1'b1) begin
next_state = S3;
end
else begin
next_state = S0;
end
end
S3:begin
if(in == 1'b1) begin
next_state = S4;
end
else begin
next_state = S0;
end
end
S4:begin
if(in == 1'b1) begin
next_state = S5;
end
else begin
next_state = S0;
end
end
S5:begin
if(in == 1'b1) begin
next_state = S6;
end
else begin
next_state = S8;
end
end
S6:begin
if(in == 1'b1) begin
next_state = S7;
end
else begin
next_state = S9;
end
end
S7:begin
if(in == 1'b1) begin
next_state = S7;
end
else begin
next_state = S0;
end
end
S8:begin
if(in == 1'b1) begin
next_state = S1;
end
else begin
next_state = S0;
end
end
S9:begin
if(in == 1'b1) begin
next_state = S1;
end
else begin
next_state = S0;
end
end
default:begin
next_state = S0;
end
endcase
end
always @(*) begin
if((state == S8)|(state == S9)) begin
out1 = 1'b1;
end
else begin
out1 = 1'b0;
end
end
always @(*) begin
if((state == S7)|(state == S9)) begin
out2 = 1'b1;
end
else begin
out2 = 1'b0;
end
end
endmodule
仿真提示无法通过非独热码的测试用例
正确解法:使用assign直接对输入的位进行操作,简单直接,也可以处理输入非独热码的情况
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
assign next_state[0] = (state[0] | state[1] | state[2] | state[3] | state[4] | state[8] | state[9] | state[7]) & (~in);
assign next_state[1] = (state[0] | state[8] | state[9]) & in;
assign next_state[2] = state[1] & in;
assign next_state[3] = state[2] & in;
assign next_state[4] = state[3] & in;
assign next_state[5] = state[4] & in;
assign next_state[6] = state[5] & in;
assign next_state[7] = (state[6] | state[7]) & in;
assign next_state[8] = state[5] & (~in);
assign next_state[9] = state[6] & (~in);
assign out1 = state[8] | state[9];
assign out2 = state[9] | state[7];
endmodule
简单解释下逻辑:
因为是独热码输入,所以独热码的每一位都可以代表一个状态,只要他置位就在对应的状态,所以转到某一个状态的逻辑即是将该位置位的逻辑,只需要找出将该位置位的逻辑表达式即可。