Add flag to support undocumented extended address (23-bit address) mode in...

Add flag to support undocumented extended address (23-bit address) mode in both FSI master and slave
Add external configuration interface for FSI slave ID
parent b0a4bce2
......@@ -11,6 +11,7 @@ module fsi_master_interface(
input wire [1:0] data_length, // 0 == 8 bit, 1 == 16 bit, 2 = 32 bit (NOTE: the lower two address bits may be forced if 16 bit / 32 bit transfer length is set)
input wire data_direction, // 0 == read from slave, 1 == write to slave
input wire enable_relative_address,
input wire enable_extended_address_mode, // In 23-bit extended address mode, the complete address is {slave_id, address}
input wire enable_crc_protection,
input wire start_cycle,
output wire cycle_complete,
......@@ -127,6 +128,7 @@ module fsi_master_interface(
reg [31:0] tx_data_reg = 0;
reg [31:0] rx_data_reg = 0;
reg enable_relative_address_reg = 0;
reg enable_extended_address_mode_reg = 0;
reg enable_crc_protection_reg = 0;
reg [1:0] enhanced_error_recovery_reg = 0;
reg [8:0] cycle_counter = 0;
......@@ -231,6 +233,7 @@ module fsi_master_interface(
endcase
tx_data_reg <= tx_data;
enable_relative_address_reg <= enable_relative_address;
enable_extended_address_mode_reg <= enable_extended_address_mode;
enable_crc_protection_reg <= enable_crc_protection;
enhanced_error_recovery_reg <= enhanced_error_recovery;
slave_error_recovery_state <= 0;
......@@ -477,7 +480,11 @@ module fsi_master_interface(
// Wait for start signal
if (fsi_data_in_internal) begin
crc_protected_bits_receiving = 1;
control_state <= FSI_TRANSFER_STATE_RX01;
if (enable_extended_address_mode_reg) begin
control_state <= FSI_TRANSFER_STATE_RX03;
end else begin
control_state <= FSI_TRANSFER_STATE_RX01;
end
end else begin
if (timeout_counter >= (FSI_TIMEOUT_CYCLES - 1)) begin
if (ipoll_in_process) begin
......@@ -666,7 +673,7 @@ module fsi_master_interface(
control_state <= FSI_TRANSFER_STATE_TR01;
end
end else begin
if (rx_slave_id != slave_id_reg) begin
if (!enable_extended_address_mode_reg && (rx_slave_id != slave_id_reg)) begin
// Slave message was not meant for this master
// Keep listening, but do not reset timeout counter here!
rx_data_reg <= 0;
......
......@@ -4,11 +4,13 @@
// See the LICENSE file for full details
module fsi_slave_interface(
input wire [1:0] slave_id, // Valid IDs are 0 - 3 inclusive
output wire [20:0] address,
input wire [31:0] tx_data,
output wire [31:0] rx_data,
output wire [1:0] data_length, // 0 == 8 bit, 1 == 16 bit, 2 = 32 bit
output wire data_direction, // 0 == read from slave, 1 == write to slave
input wire enable_extended_address_mode, // In 23-bit extended address mode, the complete address is {slave_id, address}
input wire enable_crc_protection,
output wire data_request_strobe,
input wire data_ready_strobe,
......@@ -28,9 +30,6 @@ module fsi_slave_interface(
input wire peripheral_clock
);
// Slave configuration
parameter FSI_SLAVE_ID = 0; // Valid IDs are 0 - 3 inclusive
// General FSI parameters
// NOTE: Must match standard / master parameters!
parameter FSI_TIMEOUT_CYCLES = 256;
......@@ -103,6 +102,7 @@ module fsi_slave_interface(
reg fsi_data_reg = 0;
wire fsi_data_in_internal;
reg fsi_data_direction_reg = 0;
reg [1:0] slave_id_reg = 0;
reg [20:0] address_reg = 0;
reg [31:0] rx_data_reg = 0;
reg data_direction_reg = 0;
......@@ -122,6 +122,7 @@ module fsi_slave_interface(
reg fsi_data_in_internal_prev = 0;
reg [20:0] address_rx_reg = 0;
reg [31:0] tx_data_reg = 0;
reg enable_extended_address_mode_reg = 0;
reg enable_crc_protection_reg = 0;
reg [1:0] enhanced_error_recovery_reg = 0;
reg [8:0] cycle_counter = 0;
......@@ -186,6 +187,8 @@ module fsi_slave_interface(
// of a received BREAK command, it would result in continual
// error generation until the end of the command was received!
if (fsi_data_in_internal && !fsi_data_in_internal_prev) begin
slave_id_reg <= slave_id;
enable_extended_address_mode_reg <= enable_extended_address_mode;
enable_crc_protection_reg <= enable_crc_protection;
enhanced_error_recovery_reg <= enhanced_error_recovery;
crc_protected_bits_receiving = 1;
......@@ -461,7 +464,7 @@ module fsi_slave_interface(
control_state <= FSI_TRANSFER_STATE_TR01;
end
end else begin
if (rx_slave_id != FSI_SLAVE_ID) begin
if (!enable_extended_address_mode_reg && (rx_slave_id != slave_id_reg)) begin
// Message was not meant for this slave
// Return to idle
address_reg <= 0;
......@@ -548,43 +551,49 @@ module fsi_slave_interface(
fsi_data_direction_reg <= 1;
crc_protected_bits_transmitting = 1;
fsi_data_reg_internal = 1;
control_state <= FSI_TRANSFER_STATE_TX02;
// Set up response code
if (fsi_response_code_set) begin
// Response code already set up, transmit as-is...
cycle_counter <= 2;
fsi_response_code_set <= 1;
control_state <= FSI_TRANSFER_STATE_TX02;
end else begin
// Set based on command...
if (((fsi_command_code_length == FSI_CODEWORD_TX_MSG_ABS_ADR_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_ABS_ADR_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_REL_ADR_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_REL_ADR_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_SAME_ADR_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_SAME_ADR_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_D_POLL_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_D_POLL_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_TERM_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_TERM_DAT))) begin
fsi_response_code <= FSI_CODEWORD_RX_MSG_ACK;
cycle_counter <= 2;
fsi_response_code_set <= 1;
if (enable_extended_address_mode_reg) begin
control_state <= FSI_TRANSFER_STATE_TX04;
end else begin
control_state <= FSI_TRANSFER_STATE_TX02;
end
end else begin
busy_response_in_process <= 0;
cycle_error_reg <= FSI_ERROR_INVALID_COMMAND;
control_state <= FSI_TRANSFER_STATE_IDLE;
end
end
end
end
FSI_TRANSFER_STATE_TX02: begin
// Send slave ID bit 1
fsi_data_direction_reg <= 1;
crc_protected_bits_transmitting = 1;
fsi_data_reg_internal = (FSI_SLAVE_ID >> 1) & 1'b1;
fsi_data_reg_internal = (slave_id_reg >> 1) & 1'b1;
control_state <= FSI_TRANSFER_STATE_TX03;
end
FSI_TRANSFER_STATE_TX03: begin
// Send slave ID bit 2
fsi_data_direction_reg <= 1;
crc_protected_bits_transmitting = 1;
fsi_data_reg_internal = FSI_SLAVE_ID & 1'b1;
if (fsi_response_code_set) begin
// Response code already set up, transmit as-is...
cycle_counter <= 2;
fsi_response_code_set <= 1;
control_state <= FSI_TRANSFER_STATE_TX04;
end else begin
// Set based on command...
if (((fsi_command_code_length == FSI_CODEWORD_TX_MSG_ABS_ADR_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_ABS_ADR_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_REL_ADR_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_REL_ADR_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_SAME_ADR_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_SAME_ADR_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_D_POLL_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_D_POLL_DAT))
|| ((fsi_command_code_length == FSI_CODEWORD_TX_MSG_TERM_LEN) && (fsi_command_code == FSI_CODEWORD_TX_MSG_TERM_DAT))) begin
fsi_response_code <= FSI_CODEWORD_RX_MSG_ACK;
cycle_counter <= 2;
fsi_response_code_set <= 1;
control_state <= FSI_TRANSFER_STATE_TX04;
end else begin
busy_response_in_process <= 0;
cycle_error_reg <= FSI_ERROR_INVALID_COMMAND;
control_state <= FSI_TRANSFER_STATE_IDLE;
end
end
fsi_data_reg_internal = slave_id_reg & 1'b1;
control_state <= FSI_TRANSFER_STATE_TX04;
end
FSI_TRANSFER_STATE_TX04: begin
// Send response code
......@@ -706,14 +715,14 @@ module fsi_slave_interface(
// Send slave ID bit 1
fsi_data_direction_reg <= 1;
crc_protected_bits_transmitting = 1;
fsi_data_reg_internal = (FSI_SLAVE_ID >> 1) & 1'b1;
fsi_data_reg_internal = (slave_id_reg >> 1) & 1'b1;
control_state <= FSI_TRANSFER_STATE_IR03;
end
FSI_TRANSFER_STATE_IR03: begin
// Send slave ID bit 2
fsi_data_direction_reg <= 1;
crc_protected_bits_transmitting = 1;
fsi_data_reg_internal = FSI_SLAVE_ID & 1'b1;
fsi_data_reg_internal = slave_id_reg & 1'b1;
control_state <= FSI_TRANSFER_STATE_IR04;
end
FSI_TRANSFER_STATE_IR04: begin
......
......@@ -42,6 +42,9 @@ module fsi_test();
.rx_data(rx_data),
.data_length(data_length),
.data_direction(data_direction),
.enable_relative_address(1'b1),
.enable_extended_address_mode(1'b0),
.enable_crc_protection(1'b1),
.start_cycle(start_cycle),
.cycle_complete(cycle_complete),
.cycle_error(cycle_error),
......@@ -76,11 +79,14 @@ module fsi_test();
wire slave_fsi_clock_in;
fsi_slave_interface U2(
.slave_id(2'b00),
.address(slave_address),
.tx_data(slave_tx_data),
.rx_data(slave_rx_data),
.data_length(slave_data_length),
.data_direction(slave_data_direction),
.enable_extended_address_mode(1'b0),
.enable_crc_protection(1'b1),
.data_request_strobe(slave_data_request_strobe),
.data_ready_strobe(slave_data_ready_strobe),
.enhanced_error_recovery(slave_enhanced_error_recovery),
......@@ -124,13 +130,13 @@ module fsi_test();
//address = 21'h050321; // 33'b100100100101000000110010000110101, CRC protected portion: 29'h124A0643, CRC: 4'h5
data_length = 2; // 32 bit transfer
start_cycle = 1; // Start cycle
#222
#234
`ifdef TEST_SLAVE_CORE
slave_tx_data = 32'hfacefeed; // Send response via slave core
slave_data_ready_strobe = 1;
#12
slave_data_ready_strobe = 0;
#222
#234
start_cycle = 0; // End cycle
#48
data_direction = 0; // Drive read request
......@@ -147,7 +153,7 @@ module fsi_test();
slave_data_ready_strobe = 1;
#12
slave_data_ready_strobe = 0;
#222
#234
slave_data_ready_strobe = 1;
#12
slave_data_ready_strobe = 0;
......
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