Fix KeyboardCtrl.v: if-else problem and optimize nested if statements

This commit is contained in:
Samuel Huang 2021-11-27 11:47:14 +08:00
parent 8e80429bc1
commit 56f40b1a75

View File

@ -34,137 +34,133 @@ module KeyboardCtrl#(
parameter NUM_LOCK = 8'h77;
parameter SCR_LOCK = 8'h7E;
reg next_is_extend, next_is_break, next_valid;
wire [7:0] rx_data;
wire rx_valid;
wire busy;
reg [7:0] tx_data;
reg tx_valid;
reg [2:0] state;
reg [2:0] lock_status;
reg [7:0] tx_data, next_tx_data;
reg tx_valid, next_tx_valid;
reg [2:0] state, next_state;
reg [2:0] lock_status, next_lock_status;
always @ (posedge clk, posedge rst)
if(rst)
key_in <= 0;
else if(rx_valid)
key_in <= rx_data;
else
key_in <= key_in;
if(rst)
key_in <= 0;
else if(rx_valid)
key_in <= rx_data;
else
key_in <= key_in;
always @ (posedge clk, posedge rst)begin
if(rst)begin
state <= RESET;
is_extend <= 1'b0;
is_break <= 1'b1;
valid <= 1'b0;
lock_status <= 3'b0;
tx_data <= 8'h00;
tx_valid <= 1'b0;
end else begin
is_extend <= 1'b0;
is_break <= 1'b0;
valid <= 1'b0;
lock_status <= lock_status;
tx_data <= tx_data;
tx_valid <= 1'b0;
case(state)
RESET:begin
is_extend <= 1'b0;
is_break <= 1'b1;
valid <= 1'b0;
lock_status <= 3'b0;
tx_data <= CMD_RESET;
tx_valid <= 1'b0;
state <= SEND_CMD;
end
SEND_CMD:begin
if(busy == 1'b0)begin
tx_valid <= 1'b1;
state <= WAIT_ACK;
end else begin
tx_valid <= 1'b0;
state <= SEND_CMD;
end
end
WAIT_ACK:begin
if(rx_valid == 1'b1)begin
if(rx_data == RSP_ACK && tx_data == CMD_RESET)begin
state <= RESET_WAIT_BAT;
end else if(rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS)begin
tx_data <= {5'b00000, lock_status};
state <= SEND_CMD;
if(rst)begin
state <= RESET;
is_extend <= 1'b0;
is_break <= 1'b1;
valid <= 1'b0;
lock_status <= 3'b0;
tx_data <= 8'h00;
tx_valid <= 1'b0;
end else begin
state <= next_state;
is_extend <= next_is_extend;
is_break <= next_is_break;
valid <= next_valid;
lock_status <= next_lock_status;
tx_data <= next_tx_data;
tx_valid <= next_tx_valid;
end
end
always @ (*) begin
case (state)
RESET: next_state = SEND_CMD;
SEND_CMD: next_state = (busy == 1'b0) ? WAIT_ACK : SEND_CMD;
WAIT_ACK: begin
if(rx_valid == 1'b1) begin
if(rx_data == RSP_ACK && tx_data == CMD_RESET) begin
next_state = RESET_WAIT_BAT;
end else if(rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS) begin
next_state = SEND_CMD;
end else begin
next_state = WAIT_KEYIN;
end
end else if(err == 1'b1)begin
next_state = RESET;
end else begin
state <= WAIT_KEYIN;
next_state = WAIT_ACK;
end
end else if(err == 1'b1)begin
state <= RESET;
end else begin
state <= WAIT_ACK;
end
end
WAIT_KEYIN:begin
if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin
state <= GET_BREAK;
end else if(rx_valid == 1'b1 && rx_data == EXTEND_CODE)begin
state <= GET_EXTEND;
end else if(rx_valid == 1'b1)begin
state <= WAIT_KEYIN;
valid <= 1'b1;
end else if(err == 1'b1)begin
state <= RESET;
end else begin
state <= WAIT_KEYIN;
end
WAIT_KEYIN: begin
if (rx_valid == 1'b1) begin
case (rx_data)
BREAK_CODE: next_state = GET_BREAK;
EXTEND_CODE: next_state = GET_EXTEND;
default: next_state = WAIT_KEYIN;
endcase
end else begin
next_state = (err == 1'b1) ? RESET : WAIT_KEYIN;
end
end
GET_BREAK:begin
is_extend <= is_extend;
if(rx_valid == 1'b1)begin
state <= WAIT_KEYIN;
valid <= 1'b1;
is_break <= 1'b1;
end else if(err == 1'b1)begin
state <= RESET;
end else begin
state <= GET_BREAK;
end
GET_BREAK: begin
if (rx_valid == 1'b1)
next_state = WAIT_KEYIN;
else
next_state = (err == 1'b1) ? RESET : GET_BREAK;
end
GET_EXTEND:begin
if(rx_valid == 1'b1 && rx_data == BREAK_CODE)begin
state <= GET_BREAK;
is_extend <= 1'b1;
end else if(rx_valid == 1'b1)begin
state <= WAIT_KEYIN;
valid <= 1'b1;
is_extend <= 1'b1;
end else if(err == 1'b1)begin
state <= RESET;
end else begin
state <= GET_EXTEND;
end
GET_EXTEND: begin
if (rx_valid == 1'b1)
next_state = (rx_data == BREAK_CODE) ? GET_BREAK : WAIT_KEYIN;
else
next_state = (err == 1'b1) ? RESET : GET_EXTEND;
end
RESET_WAIT_BAT:begin
if(rx_valid == 1'b1 && rx_data == RSP_BAT_PASS)begin
state <= WAIT_KEYIN;
end else if(rx_valid == 1'b1)begin
state <= RESET;
end else if(err == 1'b1)begin
state <= RESET;
end else begin
state <= RESET_WAIT_BAT;
end
end
default:begin
state <= RESET;
valid <= 1'b0;
RESET_WAIT_BAT: begin
if (rx_valid == 1'b1)
next_state = (rx_data == RSP_BAT_PASS) ? WAIT_KEYIN : RESET;
else
next_state = (err == 1'b1) ? RESET : RESET_WAIT_BAT;
end
default: next_state = RESET;
endcase
end
always @ (*) begin
next_tx_valid = 1'b0;
case (state)
RESET: next_tx_valid = 1'b0;
SEND_CMD: next_tx_valid = ~busy;
default: next_tx_valid = next_tx_valid;
endcase
end
always @ (*) begin
next_tx_data = tx_data;
case (state)
RESET: next_tx_data = CMD_RESET;
WAIT_ACK: next_tx_data = (rx_data == RSP_ACK && tx_data == CMD_SET_STATUS_LEDS) ? {5'b00000, lock_status} : next_tx_data;
default: next_tx_data = next_tx_data;
endcase
end
always @ (*) begin
next_lock_status = (state == RESET) ? 3'b0 : lock_status;
end
always @ (*) begin
next_valid = 1'b0;
case (state)
RESET: next_valid = 1'b0;
WAIT_KEYIN: next_valid = (rx_valid == 1'b1 && rx_data != BREAK_CODE && rx_data != EXTEND_CODE) ? 1'b1 : next_valid;
GET_BREAK: next_valid = (rx_valid == 1'b1) ? 1'b1 : next_valid;
GET_EXTEND: next_valid = (rx_valid == 1'b1 && rx_data != BREAK_CODE) ? 1'b1 : next_valid;
default: next_valid = next_valid;
endcase
end
always @ (*) begin
next_is_break = ((state == RESET) || (state == GET_BREAK && rx_valid == 1'b1)) ? 1'b1 : 1'b0;
next_is_extend = 1'b0;
case (state)
RESET: next_is_extend = 1'b0;
GET_BREAK: next_is_extend = is_extend;
GET_EXTEND: next_is_extend = (rx_valid == 1'b1) ? 1'b1 : next_is_extend;
default: next_is_extend = next_is_extend;
endcase
end
end
Ps2Interface #(