@@ -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.
1025+ // TODO: fix this later by using the new protocol info
1026+ // provided by the compiler.
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