0


C case和UVM TB的交互,tube_print, event_sync

C代码调用

printf

时,打印信息显示在哪个IO上,由

pringf

调用的底层代码决定;软件C中的printf默认在terminal上打印;对于嵌入式C, 运行在开发板上的code,可以借助target自己的显示IO,如LCD屏,将打印信息直接显示在LCD屏上;如果target没有显示IO,也可以retarget到host端的terminal上;simulation仿真时,运行的C代码需要借助主机host的IO,将打印信息显示在simulation terminal上;常见的方式有以下几种:

  1. 仿照实际硬件操作,操作UART,GPIO等外设传递字符串,在平台内监测外设接口,调用系统函数$display, $write等打印到terminal;
  2. 构建tube实现打印,相比1效率更高;
  3. 当仿真运行的不是RTL,而是FastModel时,可以借助semihost机制,利用IDE的界面打印;

完整的可运行代码可以参考
百度网盘链接:https://pan.baidu.com/s/13eKThizYnrKQzyUIkYhCPA
密码:csdn

UART打印

// Retarget.c// 对printf函数retarget处理// 调用UartPutc(ch);struct__FILE{int handle;};
FILE __stdout;
FILE __stdin;intfputc(int ch, FILE *f){return(UartPutc(ch));}
cmsdk_uart_capture_ard.v

中捕获字符串。

Tube打印

直接通过ahb/axi总线往reserved region写数据,在平台中监测并打印;
支持不定参数,需要调用

<stdarg.h>

;
如果需要打印大量信息,建议对信息进行分类,中间通过类似查表法的方式来处理;

//common.h#include<stdarg.h>#include<stdint.h>#definewrite_addr(a,v)((*(volatileuint32_t*)(a))=(v))#defineread_addr(a)(*(volatileuint32_t*)(a))#defineTUBE_BASE_ADDR(0x2f000000)#definesim_char(v)write_addr(TUBE_BASE_ADDR+4,v)#definesim_dec(v)write_addr(TUBE_BASE_ADDR+8,v)#definesim_hex(v)write_addr(TUBE_BASE_ADDR+12,v)#definesim_bin(v)write_addr(TUBE_BASE_ADDR+16,v)#defineSIM_INFO_TAG(0x5a5a0001)#defineSIM_WARNING_TAG(0x5a5a0002)#defineSIM_ERROR_TAG(0x5a5a0003)#defineSIM_FATAL_TAG(0x5a5a0004)#defineSIM_MSG_TAG(0x5a5a0005)#defineLF_VAL(10)#defineCR_VAL(13)#defineset_print_tag(v)write_addr(TUBE_BASE_ADDR+20,v)#definesim_event(v)write_addr(TUBE_BASE_ADDR+24,v)#defineSV2C_HS_ADDR0xfffc#definewait_sv2c_event(FLAG,CLEAR)\do{\if(sv2c_event[FLAG]==0){\while(read_addr(SV2C_HS_ADDR)!= FLAG)\{\delay(10);\}\}\if(CLEAR)\sv2c_event[FLAG]=0;\else\sv2c_event[FLAG]=1;\}while(0)externuint32_t sv2c_event[10];extern va_list sim_print(va_list list,char*format,uint32_t tag);externvoidsim_info(char* format,...);externvoidsim_warning(char* format,...);externvoidsim_error(char* format,...);externvoidsim_fatal(char* format,...);
// common.c#include"common.h"uint32_t sv2c_event[10]={0,0,0,0,0,0,0,0,0,0};

va_list sim_print(va_list list,char*format,uint32_t tag){char*char_h;

    __asm volatile("cpsid i \t\n""cpsid f \t\n");set_print_tag(tag);while(*format !='\0'){if(*format =='%'){
            format++;switch(*format){case'd':sim_dec(va_arg(list,int));break;case'x':sim_hex(va_arg(list,int));break;case'h':sim_hex(va_arg(list,int));break;case'b':sim_bin(va_arg(list,int));break;case's':
                    char_h =va_arg(list,char*);while(*char_h !='\0'){sim_char(*char_h);
                        char_h++;}break;}
            format++;}else{sim_char(*format);
            format++;}}set_print_tag(SIM_MSG_TAG);
    __asm volatile("cpsie i \t\n""cpsie f \t\n");return list;}voidsim_info(char* format,...){
    va_list list;va_start(list,format);
    list =sim_print(list,format,SIM_INFO_TAG);va_end(list);}voidsim_warning(char* format,...){
    va_list list;va_start(list,format);
    list =sim_print(list,format,SIM_WARNING_TAG);va_end(list);}voidsim_error(char* format,...){
    va_list list;va_start(list,format);
    list =sim_print(list,format,SIM_ERROR_TAG);va_end(list);}voidsim_fatal(char* format,...){
    va_list list;va_start(list,format);
    list =sim_print(list,format,SIM_FATAL_TAG);va_end(list);}

C代码调用

sim_info
sim_warning
sim_error
sim_fatal

,UVM侧相应使用

UVM_INFO
UVM_WARNING
UVM_ERROR
UVM_FATAL

实现打印;

event_sync

C和UVM的事件同步,可以通过以下几种方式:

  1. CPU的中断或者事件信号
  2. 通过Tube组件实现

后仿,低功耗仿真需要做一些修改,示例代码还未添加!!!

完整的可运行代码可以参考:
百度网盘链接:https://pan.baidu.com/s/13eKThizYnrKQzyUIkYhCPA
密码:csdn

标签: c语言 Soc tube

本文转载自: https://blog.csdn.net/Holden_Liu/article/details/128374011
版权归原作者 Holden_Liu 所有, 如有侵权,请联系我们删除。

“C case和UVM TB的交互,tube_print, event_sync”的评论:

还没有评论