多时钟系统-3 Crossing clock domains - Task
Crossing clock domains - Task
Getting a task done in another clock domain
If the clkA domain has a task that needs to be completed in the clkB domain, you can use the following design.
Here's one way to do it.
module TaskAck_CrossDomain( clkA, TaskStart_clkA, TaskBusy_clkA, TaskDone_clkA, clkB, TaskStart_clkB, TaskBusy_clkB, TaskDone_clkB); // clkA domain signals input clkA; input TaskStart_clkA; output TaskBusy_clkA, TaskDone_clkA; // clkB domain signals input clkB; output TaskBusy_clkB, TaskStart_clkB; input TaskDone_clkB; reg FlagToggle_clkA, Busyhold_clkB; reg [2:0] SyncA_clkB, SyncB_clkA; always @(posedge clkA) if(TaskStart_clkA & ~TaskBusy_clkA) FlagToggle_clkA <= ~FlagToggle_clkA; always @(posedge clkB) SyncA_clkB <= {SyncA_clkB[1:0], FlagToggle_clkA}; assign TaskStart_clkB = (SyncA_clkB[2] ^ SyncA_clkB[1]); assign TaskBusy_clkB = TaskStart_clkB | Busyhold_clkB; always @(posedge clkB) Busyhold_clkB <= ~TaskDone_clkB & TaskBusy_clkB; always @(posedge clkA) SyncB_clkA <= {SyncB_clkA[1:0], Busyhold_clkB ^ SyncA_clkB[2]}; assign TaskBusy_clkA = FlagToggle_clkA ^ SyncB_clkA[2]; assign TaskDone_clkA = SyncB_clkA[2] ^ SyncB_clkA[1]; endmodule