@@ -823,9 +823,24 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) {
823
823
acl_set_device_op_execution_status (op, CL_RUNNING);
824
824
825
825
if (host_pipe_info.implement_in_csr ) {
826
- // CSR read, currently only blocking version is implemented
826
+ // Here is the logic for CSR pipe read
827
+ // Compiler initializes ready register to 1, if ready register exist
828
+ // Non-Blocking uses_ready<true>
829
+ // 1. if ready == 1, fail.
830
+ // 2. Read data.
831
+ // 3. write 1 to ready.
832
+
833
+ // Blocking uses_ready<true>
834
+ // 1. wait until ready = 0.
835
+ // 2. read data.
836
+ // 3. write 1 to ready.
837
+
838
+ // uses_ready<false>
839
+ // Both Blocking and NonBlocking
840
+ // 1. Read data (always succeeds)
841
+
827
842
unsigned long long parsed;
828
- uintptr_t data_reg, ready_reg, valid_reg ;
843
+ uintptr_t data_reg, ready_reg;
829
844
// Convert the CSR address to a pointer
830
845
try {
831
846
parsed = std::stoull (host_pipe_info.csr_address , nullptr );
@@ -839,27 +854,21 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) {
839
854
ready_reg = static_cast <uintptr_t >(
840
855
parsed +
841
856
csr_pipe_address_offet); // ready reg is data reg shift by 8 byte
842
- valid_reg = static_cast <uintptr_t >(
843
- parsed +
844
- csr_pipe_address_offet * 2 ); // valid reg is ready reg shift by 8 byte
845
857
unsigned ready = 1 ;
846
- unsigned valid_value ;
847
- unsigned *valid_value_pointer = &valid_value ;
858
+ unsigned ready_value ;
859
+ unsigned *ready_value_pointer = &ready_value ;
848
860
849
- // protocol 3 is the avalon_mm_uses_ready protocol
850
- // Only this uses_ready protocol requires reading/writing to ready&valid
851
- // signals
852
- if (host_pipe_info.protocol == 3 ) {
853
- // If Blocking, wait until the data is valid.
854
- // If Non-blocking, just read once and report failure if not valid.
861
+ if (host_pipe_info.is_stall_free == 0 ) {
862
+ // If Blocking, wait until the ready register = 0
863
+ // If Non-blocking, just read once and report failure if ready == 1
855
864
do {
856
- acl_get_hal ()->read_csr (host_pipe_info.m_physical_device_id , valid_reg ,
857
- (void *)valid_value_pointer ,
865
+ acl_get_hal ()->read_csr (host_pipe_info.m_physical_device_id , ready_reg ,
866
+ (void *)ready_value_pointer ,
858
867
(size_t )sizeof (uintptr_t ));
859
- } while (blocking && valid_value != 1 );
868
+ } while (blocking && ready_value != 0 );
860
869
861
- // If non-blocking and valid bit is not set , set the op to fail.
862
- if (!blocking && valid_value == 0 ) {
870
+ // If non-blocking and ready bit is 1 , set the op to fail.
871
+ if (!blocking && ready_value == 1 ) {
863
872
acl_mutex_unlock (&(host_pipe_info.m_lock ));
864
873
acl_set_device_op_execution_status (op, -1 );
865
874
return ;
@@ -875,9 +884,8 @@ void acl_read_program_hostpipe(void *user_data, acl_device_op_t *op) {
875
884
acl_set_device_op_execution_status (op, -1 );
876
885
return ;
877
886
}
878
- // Tell CSR it's ready
879
- // Same reason as above, only avalon_mm_uses_ready needs to do this.
880
- if (host_pipe_info.protocol == 3 ) {
887
+ // Tell CSR it's ready if ready register exist
888
+ if (host_pipe_info.is_stall_free == 0 ) {
881
889
acl_get_hal ()->write_csr (host_pipe_info.m_physical_device_id , ready_reg,
882
890
(void *)&ready, (size_t )sizeof (uintptr_t ));
883
891
}
@@ -968,10 +976,19 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) {
968
976
// Get CSR address
969
977
970
978
// 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.
979
+ // Blocking uses_valid<true>:
980
+ // 1. read valid reg, wait until valid is 0
981
+ // 2. write to the pipe.
982
+ // 3. write 1 to the valid.
983
+
984
+ // Non-blocking uses_valid<true>
985
+ // 1. read valid reg once ->return failure if valid is 1
986
+ // 2. write to the pipe.
987
+ // 3. write 1 to the valid.
988
+
989
+ // uses_valid<false>
990
+ // Both Blocking and NonBlocking
991
+ // 1. Write data (always succeeds)
975
992
976
993
unsigned long long parsed;
977
994
uintptr_t data_reg, valid_reg;
@@ -990,23 +1007,24 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) {
990
1007
unsigned valid_value = 1 ;
991
1008
unsigned *valid_value_pointer = &valid_value;
992
1009
993
- if (blocking) {
994
- // Wait until the valid reg is 0, before the write.
995
- while (valid_value != 0 ) {
1010
+ if (host_pipe_info.is_stall_free == 0 ) {
1011
+ if (blocking) {
1012
+ while (valid_value != 0 ) {
1013
+ acl_get_hal ()->read_csr (host_pipe_info.m_physical_device_id ,
1014
+ valid_reg, (void *)valid_value_pointer,
1015
+ (size_t )sizeof (uintptr_t ));
1016
+ }
1017
+ } else {
1018
+ // Non-blocking, if valid reg is 1, return failure.
996
1019
acl_get_hal ()->read_csr (host_pipe_info.m_physical_device_id , valid_reg,
997
1020
(void *)valid_value_pointer,
998
1021
(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
1022
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 ;
1023
+ if (valid_value == 1 ) {
1024
+ acl_mutex_unlock (&(host_pipe_info.m_lock ));
1025
+ acl_set_device_op_execution_status (op, -1 );
1026
+ return ;
1027
+ }
1010
1028
}
1011
1029
}
1012
1030
@@ -1015,19 +1033,18 @@ void acl_write_program_hostpipe(void *user_data, acl_device_op_t *op) {
1015
1033
host_pipe_info.m_physical_device_id , data_reg,
1016
1034
event->cmd .info .host_pipe_dynamic_info .write_ptr ,
1017
1035
event->cmd .info .host_pipe_dynamic_info .size );
1036
+
1018
1037
if (status != 0 ) {
1019
1038
acl_mutex_unlock (&(host_pipe_info.m_lock ));
1020
1039
acl_set_device_op_execution_status (op, -1 );
1021
1040
return ;
1022
1041
}
1023
1042
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.
1027
-
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 ));
1043
+ if (host_pipe_info.is_stall_free == 0 ) {
1044
+ const unsigned valid = 1 ;
1045
+ acl_get_hal ()->write_csr (host_pipe_info.m_physical_device_id , valid_reg,
1046
+ (void *)&valid, (size_t )sizeof (uintptr_t ));
1047
+ }
1031
1048
1032
1049
} else {
1033
1050
// Regular hostpipe
0 commit comments