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( ...@@ -17,6 +17,7 @@ module fsi_master_interface(
output wire cycle_complete, output wire cycle_complete,
output wire [2:0] cycle_error, 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 [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, input wire enable_ipoll,
output wire ipoll_error, output wire ipoll_error,
output wire [1:0] interrupt_field, output wire [1:0] interrupt_field,
...@@ -100,6 +101,7 @@ module fsi_master_interface( ...@@ -100,6 +101,7 @@ module fsi_master_interface(
parameter FSI_TRANSFER_STATE_IR05 = 52; parameter FSI_TRANSFER_STATE_IR05 = 52;
parameter FSI_TRANSFER_STATE_TR01 = 64; parameter FSI_TRANSFER_STATE_TR01 = 64;
parameter FSI_TRANSFER_STATE_TR02 = 65; parameter FSI_TRANSFER_STATE_TR02 = 65;
parameter FSI_TRANSFER_STATE_DL01 = 96;
reg fsi_data_reg = 0; reg fsi_data_reg = 0;
wire fsi_data_in_internal; wire fsi_data_in_internal;
...@@ -131,7 +133,9 @@ module fsi_master_interface( ...@@ -131,7 +133,9 @@ module fsi_master_interface(
reg enable_extended_address_mode_reg = 0; reg enable_extended_address_mode_reg = 0;
reg enable_crc_protection_reg = 0; reg enable_crc_protection_reg = 0;
reg [1:0] enhanced_error_recovery_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 [8:0] cycle_counter = 0;
reg [7:0] delay_counter = 0;
reg [20:0] last_address = 0; reg [20:0] last_address = 0;
reg last_address_valid = 0; reg last_address_valid = 0;
reg [7:0] fsi_command_code = 0; reg [7:0] fsi_command_code = 0;
...@@ -143,6 +147,7 @@ module fsi_master_interface( ...@@ -143,6 +147,7 @@ module fsi_master_interface(
reg [3:0] crc_data = 0; reg [3:0] crc_data = 0;
reg crc_feedback = 0; reg crc_feedback = 0;
reg [7:0] control_state = 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_slave_id = 0;
reg [1:0] rx_message_type = 0; reg [1:0] rx_message_type = 0;
reg [8:0] timeout_counter = 0; reg [8:0] timeout_counter = 0;
...@@ -208,7 +213,13 @@ module fsi_master_interface( ...@@ -208,7 +213,13 @@ module fsi_master_interface(
timeout_counter <= 0; timeout_counter <= 0;
ipoll_start_timer <= 0; ipoll_start_timer <= 0;
fsi_data_direction_reg <= 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 end else begin
cycle_counter <= cycle_counter + 1; cycle_counter <= cycle_counter + 1;
end end
...@@ -271,6 +282,7 @@ module fsi_master_interface( ...@@ -271,6 +282,7 @@ module fsi_master_interface(
if (!enable_ipoll) begin if (!enable_ipoll) begin
ipoll_error_reg <= 0; ipoll_error_reg <= 0;
end end
internal_cmd_issue_delay_reg <= internal_cmd_issue_delay;
cycle_complete_reg <= 0; cycle_complete_reg <= 0;
end end
FSI_TRANSFER_STATE_TX01: begin FSI_TRANSFER_STATE_TX01: begin
...@@ -703,7 +715,13 @@ module fsi_master_interface( ...@@ -703,7 +715,13 @@ module fsi_master_interface(
fsi_command_code_set <= 0; fsi_command_code_set <= 0;
crc_data <= 0; crc_data <= 0;
slave_error_recovery_state <= 2; 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 end else if (master_error_recovery_state == 1) begin
// Send E_POLL // Send E_POLL
fsi_command_code <= FSI_CODEWORD_TX_MSG_E_POLL_DAT; fsi_command_code <= FSI_CODEWORD_TX_MSG_E_POLL_DAT;
...@@ -712,7 +730,13 @@ module fsi_master_interface( ...@@ -712,7 +730,13 @@ module fsi_master_interface(
fsi_command_code_set <= 1; fsi_command_code_set <= 1;
crc_data <= 0; crc_data <= 0;
master_error_recovery_state <= 2; 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 end else if (cycle_error_reg == FSI_ERROR_NONE) begin
if (rx_message_type == FSI_CODEWORD_RX_MSG_BUSY) begin if (rx_message_type == FSI_CODEWORD_RX_MSG_BUSY) begin
if (fsi_master_timeout_counter < FSI_MASTER_TIMEOUT_CYCLES) begin if (fsi_master_timeout_counter < FSI_MASTER_TIMEOUT_CYCLES) begin
...@@ -723,7 +747,13 @@ module fsi_master_interface( ...@@ -723,7 +747,13 @@ module fsi_master_interface(
fsi_command_code_set <= 1; fsi_command_code_set <= 1;
busy_response_in_process <= 1; busy_response_in_process <= 1;
crc_data <= 0; 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 end else begin
// Send TERM // Send TERM
fsi_command_code <= FSI_CODEWORD_TX_MSG_TERM_DAT; fsi_command_code <= FSI_CODEWORD_TX_MSG_TERM_DAT;
...@@ -738,7 +768,13 @@ module fsi_master_interface( ...@@ -738,7 +768,13 @@ module fsi_master_interface(
fsi_command_code_set <= 1; fsi_command_code_set <= 1;
busy_response_in_process <= 0; busy_response_in_process <= 0;
crc_data <= 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
end else begin end else begin
// Transfer complete! // Transfer complete!
...@@ -757,6 +793,7 @@ module fsi_master_interface( ...@@ -757,6 +793,7 @@ module fsi_master_interface(
if (!ipoll_in_process) begin if (!ipoll_in_process) begin
cycle_complete_reg <= 1; cycle_complete_reg <= 1;
end end
busy_response_in_process <= 0;
fsi_master_timeout_counting <= 0; fsi_master_timeout_counting <= 0;
control_state <= FSI_TRANSFER_STATE_TR02; control_state <= FSI_TRANSFER_STATE_TR02;
slave_error_recovery_state <= 0; slave_error_recovery_state <= 0;
...@@ -777,7 +814,13 @@ module fsi_master_interface( ...@@ -777,7 +814,13 @@ module fsi_master_interface(
end end
ipoll_start_timer <= 0; ipoll_start_timer <= 0;
ipoll_in_process <= 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
end end
FSI_TRANSFER_STATE_IR01: begin FSI_TRANSFER_STATE_IR01: begin
...@@ -811,6 +854,13 @@ module fsi_master_interface( ...@@ -811,6 +854,13 @@ module fsi_master_interface(
cycle_counter <= 4; cycle_counter <= 4;
control_state <= FSI_TRANSFER_STATE_RX06; control_state <= FSI_TRANSFER_STATE_RX06;
end 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 default: begin
// Should never reach this state // Should never reach this state
cycle_error_reg <= FSI_ERROR_INTERNAL_FAULT; cycle_error_reg <= FSI_ERROR_INTERNAL_FAULT;
......
...@@ -49,6 +49,7 @@ module fsi_test(); ...@@ -49,6 +49,7 @@ module fsi_test();
.cycle_complete(cycle_complete), .cycle_complete(cycle_complete),
.cycle_error(cycle_error), .cycle_error(cycle_error),
.enhanced_error_recovery(enhanced_error_recovery), .enhanced_error_recovery(enhanced_error_recovery),
.internal_cmd_issue_delay(0),
.enable_ipoll(enable_ipoll), .enable_ipoll(enable_ipoll),
.ipoll_error(ipoll_error), .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