页次: 1
展开来看的话,代码是这样
{
u64 tick_high_64;
u32 tick_low_32;
/* 1.先获取高32位,但是在执行这段的时候,低32位的tick实际还是在增加的 */
tick_high_64 = csi_coret_get_valueh() << 32;
/* 2.后获取低32位,如果在执行"1"之前,低32位已经是满量程0xFFFFFFFF。则这里就有可能溢出成0的概率 */
/* 所以这一段需要在1之前执行 */
tick_low_32 = csi_coret_get_value();
tick_high_64 |= tick_low_32;
return tick_high_64;
}
1、格雷码主要是为了解决跨时钟域异步问题。GTC寄存器自然数->格雷码->CPU寄存器自然数,格雷码两端对自然数的转换都是由硬件进行转换,不需要软件处理。两头寄存器看到的值,都是咱们直接可读的自然数值。
2、GTC自然数的读取有两种方式,一种是读取GTC寄存器GTC_CNTVL GTC_CNTVH的值,一种是读取RISC-V CPU寄存器的值,通过汇编指令(csrr a0, time)(csrr a1, timeh) 获取;第一种方式由于CPU访问GTC寄存器的访问进行各级总线的同步,会占有百纳秒级别的开销,实际不推荐这么使用;建议使用第二种方式,访问CPU寄存器自然数的值,其开销取决于CPU指令的时间。
3、GTC时基250ns,通过读取CPU寄存器的值判断实现1us延迟是可行的。这里还需要特别注意延迟后执行动作耗费的时间,函数调用和寄存器读写都会占用一些时间。
页次: 1