## 时钟域(Clock domains) ### 一、激励API(Stimulus API) 以下是`ClockDomain`激励函数的列表: | 时钟域激励函数 | 描述 | | :--------------------------------: | :------------------------------------------------------------------------: | | `forkStimulus(period)` | 分化仿真流程来产生时钟域激励(clock, reset, softReset, clockEnable singals) | | `forkSimSpeedPrinter(printPeriod)` | 分化仿真流程定期以实时秒数下的千-周期打印仿真速度。`printPeriod`是实时秒数 | | `clockToggle()` | 切换时钟信号 | | `fallingEdge()` | 清空时钟信号 | | `risingEdge()` | 设置时钟信号 | | `assertReset()` | 将复位信号设置为有效电平 | | `deassertReset()` | 将复位信号设置为无效电平 | | `assertClockEnable()` | 将时钟使能信号设置为有效电平 | | `deassertClockEnable()` | 将时钟使能信号设置为无效电平 | | `assertSoftReset()` | 将软复位设置为有效电平 | | `deassertSoftReset()` | 将软复位信号设置为无效电平 | ### 二、等待API(Wait API) 以下是可用于等待时钟域中给定事件的`ClockDomain`实用程序列表: | 时钟域等待函数 | 描述 | | :-------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | | `waitSampling([cyclesCount])` | 一直等待直到`ClockDomain`采样(active clock edge && deassertReset && assertClockEnable) | | `waitRisingEdge([cyclesCount])` | 等待`cyclesCount`个时钟上升沿, `cyclesCount`默认是1周期。注意, `cyclesCount=0`是合法的, 并且该函数对reset/softReset/clockEnable不敏感 | | `waitFallingEdge([cyclesCount])` | 与`waitRisingEdge`相同但是针对下降沿 | | `waitActiveEdge([cyclesCount])` | 与`waitRisingEdge`相同但是针对由`ClockDomainConfig`指定的边沿 | | `waitRisingEdgeWhere(condition)` | 与`waitRisingEdge`相同但要是退出, 当上升沿触发Boolean`condition`必须为真 | | `waitFallingEdgeWhere(condition)` | 与`waitRisingEdgeWhere`相同但是针对下降沿 | | `waitActiveEdgeWhere(condition)` | 与`waitRisingEdgeWhere`相同但是针对由`ClockDomainConfig`指定的边沿 | > 注意:所有的等待API的功能只能从线程内部调用, 不能从传回调用。 ### 三、传回API(Callback API) 以下是可以用于传回时钟域中给定事件的`ClockDomain`实用程序列表: | 时钟域传回函数 | 描述 | | :--------------------------: | :----------------------------------------------------------------------------------: | | `onNextSampling{ callback }` | 只在下一个`ClockDomain`采样时执行传回代码(active edge + reset off + clock enable on) | | `onSamplings{ callback }` | 每次`ClockDomain`采样时执行传回代码(active edge + reset off + clock enable on) | | `onActiveEdges{ callback }` | 每次`ClockDomain`生成配置边沿时执行传回代码 | | `onEdges{ callback }` | 每次`ClockDomain`生成上升或下降边沿时执行传回代码 | | `onRisingEdges{ callback }` | 每次`ClockDomain`生成上升边沿时执行传回代码 | | `onFallingEdges{ callback }` | 每次`ClockDomain`生成下降边沿时执行传回代码 | ### 四、默认时钟域(Default ClockDomain) 你可以如下所示访存顶层的默认`ClockDomain`: ```Scala //线程分叉以产生复位的例子, 并且之后每5个单位时间翻转一次时钟。 //dut.clockDomain参考在模块例化期间产生的隐含的时钟域 fork { dut.clockDomain.assertReset() dut.clockDomain.fallingEdge() sleep(10) while(true) { dut.clockDomain.clockToggle() sleep(5) } } ``` > 备注:你也可以直接分化一个标准reset/clock进程: > ```Scala > dut.clockDomain.forkStimulus(period = 10) 下例所如何等待时钟上升沿的例子: ```Scala dut.clockDomain.waitRisingEdge() ``` ### 五、新时钟域(New ClockDomain) 如果你顶层定义了一些时钟并且复位输入没有直接集成到`ClockDomain`中, 你可以直接在testbench中定义他们对应的`ClockDomain`: ```Scala //在testbench中 ClockDomain(dut.io.coreClk, dut.io.coreReset).forkStimulus(10) ```