Clock Domain Annotation
If there are some clocks in a module, explicit clock domain annotation like 'a is required.
The annotation shows which clock domain each signals belong.
module ModuleA (
// belong clock domain 'a
i_clk_a: input 'a clock,
i_dat_a: input 'a logic,
o_dat_a: output 'a logic,
// belong clock domain 'b
i_clk_b: input 'b clock,
i_dat_b: input 'b logic,
o_dat_b: output 'b logic,
) {
// assignment in the same clock domain is safe
assign o_dat_a = i_dat_a;
assign o_dat_b = i_dat_b;
}
If there is single clock only in a module, the annotation can be omitted.
module ModuleA (
i_clk: input clock,
i_dat: input logic,
o_dat: output logic,
) {
assign o_dat = i_dat;
}
'_ is a special clock domain which means implicit clock domain.
This can be used to specify that some clocks belong the same implicit clock domain.
module ModuleA (
// all signals belong implicit clock domain
i_clk : input '_ clock,
i_clk_x2: input '_ clock,
i_dat : input logic,
o_dat : output logic,
) {
assign o_dat = i_dat;
}
Interface instances can have clock domain annotation.
module ModuleA {
inst intf: 'a InterfaceA;
}
interface InterfaceA {}
Clock domain inference
Variables declared without clock domain annotation can have their domain inferred automatically.
The domain is inferred from the right-hand side of assign statements or the clock of always_ff blocks.
Note that clock domain annotation on port declarations cannot be omitted even if inference is possible, because port declarations are public interfaces and should be explicit.
module ModuleA (
i_clk_a: input 'a clock,
i_rst_a: input 'a reset,
i_dat_a: input 'a logic,
o_dat_a: output 'a logic,
i_clk_b: input 'b clock,
i_rst_b: input 'b reset,
i_dat_b: input 'b logic,
o_dat_b: output 'b logic,
) {
// inferred as 'a from assign RHS
var x: logic;
assign x = i_dat_a;
assign o_dat_a = x;
// inferred as 'b from always_ff clock
var y: logic;
always_ff (i_clk_b, i_rst_b) {
if_reset {
y = 0;
} else {
y = i_dat_b;
}
}
assign o_dat_b = y;
}