2010年7月23日 星期五

Bus communication with thread emulator @c

底下我們利用 "pthread" 的方式模擬 Bus 的 communication, 因為還是在 High Level Architecture view, 所以在Protocol 部份我們用 Package 來傳輸, 可節省實際在設計上的複雜度,也可以加速驗證的流程. sample part @ c
void *AHB2APB_MASTER_DO(void *t){
    long my_id = (long)t;

    int i;
    srand ( time(NULL) );
  
 for(;;){
     AHB2APB_MASTER_MESSAGE_INFO(MS_CUR_ST);

    switch(MS_CUR_ST){
        case BG_MS_IDLE     : 
                               WT_SEL = ( rand()%2 == 0)? AMBA_ON : AMBA_OFF;
                               MS_NXT_ST = BG_MS_REQ;     
                               break;
 
        case BG_MS_REQ      :  MS_NXT_ST = BG_MS_NONSEQ; 
                               break;

        case BG_MS_NONSEQ   :  pthread_mutex_lock(&count_mutex);
                               pthread_cond_signal(&master2slave); 
                               pthread_mutex_unlock(&count_mutex);
                           
                               pthread_mutex_lock(&count_mutex);
                                     // for Write Case
                                     if( WT_SEL == AMBA_ON  && AHB2APB_fifo.FIFO_INX != FIFO_DEP ){
                                         AHB2APB_fifo.VEC_LIST[AHB2APB_fifo.FIFO_INX++] = &vecptr_1;
                                     // for Read Case
                               }else if ( WT_SEL == AMBA_OFF && AHB2APB_fifo.FIFO_INX != FIFO_DEP ){
                                         AHB2APB_fifo.VEC_LIST[AHB2APB_fifo.FIFO_INX++] = &vecptr_2;
                               }

                               MS_NXT_ST = BG_MS_SEQ;
                               pthread_mutex_unlock(&count_mutex);
                               break;

        case BG_MS_SEQ      :  MS_NXT_ST = ( WT_SEL == AMBA_ON )? BG_MS_WT_DON : BG_MS_RD_DON;
                               break;

        case BG_MS_RD_DON   :  pthread_mutex_lock(&count_mutex);
                               while( APB2AHB_fifo.FIFO_INX ==0 ) {
                                      pthread_cond_wait(&slave2master, &count_mutex);
                               }
                               pthread_mutex_unlock(&count_mutex);

                               pthread_mutex_lock(&count_mutex);
                               for(i=0; i< APB2AHB_fifo.FIFO_INX; i++){
                                  AHB2APB_TESTVEC_MESSAGE_INFO(APB2AHB_fifo.VEC_LIST[i]); 
                                 }
                               APB2AHB_fifo.FIFO_INX =0;
                               MS_NXT_ST = BG_MS_IDLE; 
                               COT++;
                               pthread_mutex_unlock(&count_mutex); 
                               break;

        case BG_MS_WT_DON   :  pthread_mutex_lock(&count_mutex);
                               //APB2AHB_fifo.FIFO_INX =0;
                               MS_NXT_ST = BG_MS_IDLE;
                               COT++;
                               pthread_mutex_unlock(&count_mutex);                           
                               break;
    }
      
     MS_CUR_ST = MS_NXT_ST;

    if( COT == DON_COT ){ pthread_exit(NULL); }
  }
}


int main(int argc,char *argv[]){
 long t1=1, t2=2;

//=======================
//    Pattern Gen
//=======================
AHB2APB_TESTVEC_GEN_1(&vecptr_1);
//AHB2APB_TESTVEC_MESSAGE_INFO(&vecptr_1); 

AHB2APB_TESTVEC_GEN_2(&vecptr_2);
//AHB2APB_TESTVEC_MESSAGE_INFO(&vecptr_2); 

//=======================
// Reset FIFO 
//=======================
AHB2APB_fifo.FIFO_INX =0;
APB2AHB_fifo.FIFO_INX =0;

//AHB2APB_fifo.VEC_LIST[0] = &vecptr_1;
//AHB2APB_TESTVEC_MESSAGE_INFO(AHB2APB_fifo.VEC_LIST[0]); 


  pthread_t threads[2];
  pthread_attr_t attr;
 
  pthread_mutex_init(&count_mutex, NULL);
  pthread_cond_init (&master2slave, NULL);


  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  pthread_create(&threads[0], &attr, AHB2APB_SLAVE_DO,(void *)t1);
  pthread_create(&threads[1], &attr, AHB2APB_MASTER_DO,(void *)t2);


  pthread_join(threads[0], NULL);
  pthread_join(threads[1], NULL);


  pthread_attr_destroy(&attr);
  pthread_cond_destroy(&master2slave);

  pthread_mutex_destroy(&count_mutex);
  pthread_exit(NULL);


}
code download here compile %gcc -lpthread -o tt bridge.c Refs: https://computing.llnl.gov/tutorials/pthreads/ http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

沒有留言:

張貼留言