Skip to content

Commit 3084722

Browse files
committed
Fix csr pipe write handshaking
1. If blocking, read valid reg, wait until valid is 0. 2. If non-blocking, read valid reg once ->return failure if valid is 1. 3. write to the pipe. 4. write 1 to the valid.
1 parent 9ca3207 commit 3084722

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

src/acl_hostch.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,13 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) {
966966

967967
if (host_pipe_info.implement_in_csr) {
968968
// Get CSR address
969+
970+
// Here is the logic for CSR pipe write
971+
// 1. If blocking, read valid reg, wait until valid is 0.
972+
// 2. If non-blocking, read valid reg once ->return failure if valid is 1.
973+
// 3. write to the pipe.
974+
// 4. write 1 to the valid.
975+
969976
unsigned long long parsed;
970977
uintptr_t data_reg, valid_reg;
971978
try {
@@ -979,7 +986,30 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) {
979986
parsed +
980987
csr_pipe_address_offet); // valid reg is data reg shift by 8 byte, move
981988
// this to the autodiscovery string maybe
982-
unsigned int valid = 1;
989+
990+
unsigned valid_value = 1;
991+
unsigned *valid_value_pointer = &valid_value;
992+
993+
if (blocking) {
994+
// Wait until the valid reg is 0, before the write.
995+
while (valid_value != 0) {
996+
acl_get_hal()->read_csr(host_pipe_info.m_physical_device_id, valid_reg,
997+
(void *)valid_value_pointer,
998+
(size_t)sizeof(uintptr_t));
999+
}
1000+
} else {
1001+
// Non-blocking, if valid reg is 1, return failure.
1002+
acl_get_hal()->read_csr(host_pipe_info.m_physical_device_id, valid_reg,
1003+
(void *)valid_value_pointer,
1004+
(size_t)sizeof(uintptr_t));
1005+
1006+
if (valid_value == 1) {
1007+
acl_mutex_unlock(&(host_pipe_info.m_lock));
1008+
acl_set_device_op_execution_status(op, -1);
1009+
return;
1010+
}
1011+
}
1012+
9831013
// start the write
9841014
auto status = acl_get_hal()->write_csr(
9851015
host_pipe_info.m_physical_device_id, data_reg,
@@ -991,24 +1021,14 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) {
9911021
return;
9921022
}
9931023

994-
// In non-blocking case, there is no need to write into valid register.
995-
// We only care about valid register if the protocol is
996-
// avalon_mm_uses_ready.
997-
if (blocking && host_pipe_info.protocol == 3) {
998-
// Tell CSR it's valid
999-
acl_get_hal()->write_csr(host_pipe_info.m_physical_device_id, valid_reg,
1000-
(void *)&valid, (size_t)sizeof(uintptr_t));
1024+
// For now, we trust the AVALON_MM by default uses valid. TODO: fix this
1025+
// later by use the new protocol info Provided by the compiler Tell CSR it's
1026+
// valid.
10011027

1002-
// Wait until the valid reg is 0
1003-
unsigned valid_value = 1;
1004-
unsigned *valid_value_pointer = &valid_value;
1028+
const unsigned valid = 1;
1029+
acl_get_hal()->write_csr(host_pipe_info.m_physical_device_id, valid_reg,
1030+
(void *)&valid, (size_t)sizeof(uintptr_t));
10051031

1006-
while (valid_value != 0) {
1007-
acl_get_hal()->read_csr(host_pipe_info.m_physical_device_id, valid_reg,
1008-
(void *)valid_value_pointer,
1009-
(size_t)sizeof(uintptr_t));
1010-
}
1011-
}
10121032
} else {
10131033
// Regular hostpipe
10141034
// Attempt to write once

0 commit comments

Comments
 (0)