Add configurable response to command delay to FSI master

This is required to interface with certain hardware, such as the
IBM POWER9.  Without some delay added, the FSI interface on the
POWER9 processor will send invalid responses and generally malfunction.
parent 9d1aad9d
......@@ -17,6 +17,7 @@ module fsi_master_interface(
output wire cycle_complete,
output wire [2:0] cycle_error,
input wire [1:0] enhanced_error_recovery, // Bit 1 == EER for IPOLL, Bit 0 == EER for all other transmissions
input wire [7:0] internal_cmd_issue_delay,
input wire enable_ipoll,
output wire ipoll_error,
output wire [1:0] interrupt_field,
......@@ -100,6 +101,7 @@ module fsi_master_interface(
parameter FSI_TRANSFER_STATE_IR05 = 52;
parameter FSI_TRANSFER_STATE_TR01 = 64;
parameter FSI_TRANSFER_STATE_TR02 = 65;
parameter FSI_TRANSFER_STATE_DL01 = 96;
reg fsi_data_reg = 0;
wire fsi_data_in_internal;
......@@ -131,7 +133,9 @@ module fsi_master_interface(
reg enable_extended_address_mode_reg = 0;
reg enable_crc_protection_reg = 0;
reg [1:0] enhanced_error_recovery_reg = 0;
reg [7:0] internal_cmd_issue_delay_reg = 0;
reg [8:0] cycle_counter = 0;
reg [7:0] delay_counter = 0;
reg [20:0] last_address = 0;
reg last_address_valid = 0;
reg [7:0] fsi_command_code = 0;
......@@ -143,6 +147,7 @@ module fsi_master_interface(
reg [3:0] crc_data = 0;
reg crc_feedback = 0;
reg [7:0] control_state = 0;
reg [7:0] post_delay_control_state = 0;
reg [1:0] rx_slave_id = 0;
reg [1:0] rx_message_type = 0;
reg [8:0] timeout_counter = 0;
......@@ -208,7 +213,13 @@ module fsi_master_interface(
timeout_counter <= 0;
ipoll_start_timer <= 0;
fsi_data_direction_reg <= 0;
control_state <= FSI_TRANSFER_STATE_IDLE;
if (internal_cmd_issue_delay_reg > 0) begin
delay_counter <= 1;
post_delay_control_state <= FSI_TRANSFER_STATE_IDLE;
control_state <= FSI_TRANSFER_STATE_DL01;
end else begin
control_state <= FSI_TRANSFER_STATE_IDLE;
end
end else begin
cycle_counter <= cycle_counter + 1;
end
......@@ -271,6 +282,7 @@ module fsi_master_interface(
if (!enable_ipoll) begin
ipoll_error_reg <= 0;
end
internal_cmd_issue_delay_reg <= internal_cmd_issue_delay;
cycle_complete_reg <= 0;
end
FSI_TRANSFER_STATE_TX01: begin
......@@ -703,7 +715,13 @@ module fsi_master_interface(
fsi_command_code_set <= 0;
crc_data <= 0;
slave_error_recovery_state <= 2;
control_state <= FSI_TRANSFER_STATE_TX01;
if (internal_cmd_issue_delay_reg > 0) begin
delay_counter <= 1;
post_delay_control_state <= FSI_TRANSFER_STATE_TX01;
control_state <= FSI_TRANSFER_STATE_DL01;
end else begin
control_state <= FSI_TRANSFER_STATE_TX01;
end
end else if (master_error_recovery_state == 1) begin
// Send E_POLL
fsi_command_code <= FSI_CODEWORD_TX_MSG_E_POLL_DAT;
......@@ -712,7 +730,13 @@ module fsi_master_interface(
fsi_command_code_set <= 1;
crc_data <= 0;
master_error_recovery_state <= 2;
control_state <= FSI_TRANSFER_STATE_TX01;
if (internal_cmd_issue_delay_reg > 0) begin
delay_counter <= 1;
post_delay_control_state <= FSI_TRANSFER_STATE_TX01;
control_state <= FSI_TRANSFER_STATE_DL01;
end else begin
control_state <= FSI_TRANSFER_STATE_TX01;
end
end else if (cycle_error_reg == FSI_ERROR_NONE) begin
if (rx_message_type == FSI_CODEWORD_RX_MSG_BUSY) begin
if (fsi_master_timeout_counter < FSI_MASTER_TIMEOUT_CYCLES) begin
......@@ -723,7 +747,13 @@ module fsi_master_interface(
fsi_command_code_set <= 1;
busy_response_in_process <= 1;
crc_data <= 0;
control_state <= FSI_TRANSFER_STATE_IDLE;
if (internal_cmd_issue_delay_reg > 0) begin
delay_counter <= 1;
post_delay_control_state <= FSI_TRANSFER_STATE_IDLE;
control_state <= FSI_TRANSFER_STATE_DL01;
end else begin
control_state <= FSI_TRANSFER_STATE_IDLE;
end
end else begin
// Send TERM
fsi_command_code <= FSI_CODEWORD_TX_MSG_TERM_DAT;
......@@ -738,7 +768,13 @@ module fsi_master_interface(
fsi_command_code_set <= 1;
busy_response_in_process <= 0;
crc_data <= 0;
control_state <= FSI_TRANSFER_STATE_TX01;
if (internal_cmd_issue_delay_reg > 0) begin
delay_counter <= 1;
post_delay_control_state <= FSI_TRANSFER_STATE_TX01;
control_state <= FSI_TRANSFER_STATE_DL01;
end else begin
control_state <= FSI_TRANSFER_STATE_TX01;
end
end
end else begin
// Transfer complete!
......@@ -757,6 +793,7 @@ module fsi_master_interface(
if (!ipoll_in_process) begin
cycle_complete_reg <= 1;
end
busy_response_in_process <= 0;
fsi_master_timeout_counting <= 0;
control_state <= FSI_TRANSFER_STATE_TR02;
slave_error_recovery_state <= 0;
......@@ -777,7 +814,13 @@ module fsi_master_interface(
end
ipoll_start_timer <= 0;
ipoll_in_process <= 0;
control_state <= FSI_TRANSFER_STATE_IDLE;
if (internal_cmd_issue_delay_reg > 0) begin
delay_counter <= 1;
post_delay_control_state <= FSI_TRANSFER_STATE_IDLE;
control_state <= FSI_TRANSFER_STATE_DL01;
end else begin
control_state <= FSI_TRANSFER_STATE_IDLE;
end
end
end
FSI_TRANSFER_STATE_IR01: begin
......@@ -811,6 +854,13 @@ module fsi_master_interface(
cycle_counter <= 4;
control_state <= FSI_TRANSFER_STATE_RX06;
end
FSI_TRANSFER_STATE_DL01: begin
if (delay_counter >= internal_cmd_issue_delay_reg) begin
control_state <= post_delay_control_state;
end else begin
delay_counter <= delay_counter + 1;
end
end
default: begin
// Should never reach this state
cycle_error_reg <= FSI_ERROR_INTERNAL_FAULT;
......
......@@ -49,6 +49,7 @@ module fsi_test();
.cycle_complete(cycle_complete),
.cycle_error(cycle_error),
.enhanced_error_recovery(enhanced_error_recovery),
.internal_cmd_issue_delay(0),
.enable_ipoll(enable_ipoll),
.ipoll_error(ipoll_error),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment