diff options
| author | Adam Izraelevitz | 2020-08-21 14:40:05 -0700 |
|---|---|---|
| committer | GitHub | 2020-08-21 21:40:05 +0000 |
| commit | 52dcf10d59b88b026adab0f5d9f127bfac18b36a (patch) | |
| tree | 2ba4cf902f6e21bf71e6137f3d600e66e978bb32 /docs/src/explanations/multi-clock.md | |
| parent | 7edba2d10f980016462f917c6d21d64585ddfd6b (diff) | |
Move multi-clock to explanations (#1561)
Diffstat (limited to 'docs/src/explanations/multi-clock.md')
| -rw-r--r-- | docs/src/explanations/multi-clock.md | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/docs/src/explanations/multi-clock.md b/docs/src/explanations/multi-clock.md new file mode 100644 index 00000000..6e9afd5a --- /dev/null +++ b/docs/src/explanations/multi-clock.md @@ -0,0 +1,98 @@ +--- +layout: docs +title: "Multiple Clock Domains" +section: "chisel3" +--- +Chisel 3 supports multiple clock domains as follows. + +Note that in order to cross clock domains safely, you will need appropriate synchronization logic (such as an asynchronous FIFO). You can use the [AsyncQueue library](https://github.com/ucb-bar/asyncqueue) to do this easily. + +```scala mdoc:silent:reset +import chisel3._ + +class MultiClockModule extends Module { + val io = IO(new Bundle { + val clockB = Input(Clock()) + val resetB = Input(Bool()) + val stuff = Input(Bool()) + }) + + // This register is clocked against the module clock. + val regClock = RegNext(io.stuff) + + withClockAndReset (io.clockB, io.resetB) { + // In this withClock scope, all synchronous elements are clocked against io.clockB. + // Reset for flops in this domain is using the explicitly provided reset io.resetB. + + // This register is clocked against io.clockB. + val regClockB = RegNext(io.stuff) + } + + // This register is also clocked against the module clock. + val regClock2 = RegNext(io.stuff) +} +``` + +You can also instantiate modules in another clock domain: + +```scala mdoc:silent:reset +import chisel3._ + +class ChildModule extends Module { + val io = IO(new Bundle{ + val in = Input(Bool()) + }) +} +class MultiClockModule extends Module { + val io = IO(new Bundle { + val clockB = Input(Clock()) + val resetB = Input(Bool()) + val stuff = Input(Bool()) + }) + val clockB_child = withClockAndReset(io.clockB, io.resetB) { Module(new ChildModule) } + clockB_child.io.in := io.stuff +} +``` + +If you only want to connect your clock to a new clock domain and use the regular implicit reset signal, you can use `withClock(clock)` instead of `withClockAndReset`. + +```scala mdoc:silent:reset +import chisel3._ + +class MultiClockModule extends Module { + val io = IO(new Bundle { + val clockB = Input(Clock()) + val stuff = Input(Bool()) + }) + + // This register is clocked against the module clock. + val regClock = RegNext(io.stuff) + + withClock (io.clockB) { + // In this withClock scope, all synchronous elements are clocked against io.clockB. + + // This register is clocked against io.clockB, but uses implict reset from the parent context. + val regClockB = RegNext(io.stuff) + } + + // This register is also clocked against the module clock. + val regClock2 = RegNext(io.stuff) +} + +// Instantiate module in another clock domain with implicit reset. +class MultiClockModule2 extends Module { + val io = IO(new Bundle { + val clockB = Input(Clock()) + val stuff = Input(Bool()) + }) + val clockB_child = withClock(io.clockB) { Module(new ChildModule) } + clockB_child.io.in := io.stuff +} + +class ChildModule extends Module { + val io = IO(new Bundle{ + val in = Input(Bool()) + }) +} + +``` |
