rocket-chip某些模块具有clock gating的功能,在进行等待状态时,会关闭该模块的时钟。
下面看一下sifive的一些介绍《SiFive U74-MC Manual v19.05》。
第一张是目录说明。
第二张是dcache flush的操作说明。
第三张是feature disable CSR寄存器的介绍,关闭时钟的操作就是这个CSR寄存器。
再看一下scala代码。
在tile/CustomCSRs.scala中有定义。
0x7c1为chickenCSRId,其中bit[0]为disableDCacheClockGate,而bit[1]为disableICacheClockGate,然后bit[2]为disableCoreClockGate。
其他的功能大家可以自己再研究一下。
测试代码如下:
#include "encoding.h"
#include "L1Dcache.h"
#define U32 *(volatile unsigned int *)
#define DEBUG_SIG 0x70000000
#define DEBUG_VAL 0x70000004
#define DATA_SIZE 100
int input1_data[DATA_SIZE] =
{
41, 833, 564, 187, 749, 350, 132, 949, 584, 805, 621, 6, 931, 890, 392, 694, 961, 110, 116, 296,
426, 314, 659, 774, 319, 678, 875, 376, 474, 938, 539, 569, 203, 280, 759, 606, 511, 657, 195, 81,
267, 229, 337, 944, 902, 241, 913, 826, 933, 985, 195, 960, 566, 350, 649, 657, 181, 111, 859, 65,
288, 349, 141, 905, 886, 264, 576, 979, 761, 241, 478, 499, 403, 222, 444, 721, 676, 317, 224, 937,
288, 119, 615, 606, 389, 351, 455, 278, 367, 358, 584, 62, 985, 403, 346, 517, 559, 908, 775, 255
};
int input2_data[DATA_SIZE] =
{
454, 335, 1, 989, 365, 572, 64, 153, 216, 140, 210, 572, 339, 593, 898, 228, 12, 883, 750, 646,
500, 436, 701, 812, 981, 150, 696, 564, 272, 258, 647, 509, 88, 703, 669, 375, 551, 936, 592, 569,
952, 800, 584, 643, 368, 489, 328, 313, 592, 388, 543, 649, 979, 997, 814, 79, 208, 998, 629, 847,
704, 997, 253, 715, 430, 415, 538, 700, 4, 494, 100, 864, 693, 416, 296, 285, 620, 78, 351, 540,
646, 169, 527, 289, 796, 801, 720, 758, 745, 92, 989, 271, 853, 788, 531, 222, 461, 241, 358, 332
};
//--------------------------------------------------------------------------
// handle_trap function
void handle_trap()
{
asm volatile ("nop");
while(1);
}
//--------------------------------------------------------------------------
// cache function
void cache( int n, int a[], int b[])
{
int i;
for ( i = 0; i < n; i++ )
U32(0x80001000+4*i) = a[i] + b[i];
for ( i = 0; i < n; i++ )
U32(0x60001000+4*i) = U32(0x80001000+4*i);
FLUSH_D_REG(0x80001000);
FLUSH_D_ALL();
for ( i = 0; i < n; i++ )
U32(0x60001000+4*i) = U32(0x80001000+4*i);
}
//--------------------------------------------------------------------------
// clock gating function
void clock_gating()
{
U32(0x60000000) = read_csr(0x7C1);
write_csr(0x7C1,read_csr(0x7C1) & 0xFFFFFFF0);
}
//--------------------------------------------------------------------------
// Main
void main()
{
cache(DATA_SIZE, input1_data, input2_data);
clock_gating();
//U32(DEBUG_SIG) = 0xFF;
while(1) {asm volatile ("wfi");}
}
仿真波形如下图。
蓝色箭头:clock_gating函数,用于配置0x7c1 CSR寄存器的bit[2:0]。
黄色箭头:wfi指令,等待中断来临指令,只有进入进入wfi指令,core、icache和dcache模块的时钟才会关闭,不进入此指令前,时钟会常开,即使进入while(1);死循环,也不能使core、icache和dcache模块的时钟关闭,必须进入wfi指令才能。
红色箭头:可以看到运行pc 0x8000_01b0(wfi)后,CPU进入等待状态,同时core模块的时钟关闭。
再过一段时间后,icache模块的时钟也关闭。
dcache模块的时钟同理。