calyxir/calyx

Default nettype of inline verilog primitives is unset

Closed this issue · 3 comments

Can we explicitly set the default_nettype directive for inlined Verilog primitives? Most cases we probably want to set it to wire. For inlined primitives, is there ever a time where we don't want it set to wire? It is causing issues when trying to synthesize the output of calyx -b verilog --synthesis with Vivado.

To elaborate, the core.futil primitives are the last thing to update the default nettype:

`default_nettype none
module std_slice #(
parameter IN_WIDTH = 32,

These are included before compile.futil which are printed to verilog without an explicit type:
for (idx, port) in prim.signature.iter().enumerate() {
// NOTE: The signature port definitions are reversed inside the component.
match port.direction {
ir::Direction::Input => {
write!(f, " input")?;
}
ir::Direction::Output => {
write!(f, " output")?;
}
ir::Direction::Inout => {
panic!("Unexpected Inout port on Component: {}", port.name())
}
}

As a result, I get errors on things like std_add and my own external components with Vivado.

ERROR: [Synth 8-6735] net type must be explicitly specified for 'in' when default_nettype is none [/work/shared/users/phd/mrh259/calyx/vivado/benchmark.srcs/sources_1/imports/mrh259/calyx/benchmark.sv:602]
ERROR: [Synth 8-6735] net type must be explicitly specified for 'left' when default_nettype is none [/work/shared/users/phd/mrh259/calyx/vivado/benchmark.srcs/sources_1/imports/mrh259/calyx/benchmark.sv:611]
ERROR: [Synth 8-6735] net type must be explicitly specified for 'right' when default_nettype is none [/work/shared/users/phd/mrh259/calyx/vivado/benchmark.srcs/sources_1/imports/mrh259/calyx/benchmark.sv:612]

Thanks for looping me in to this issue.

What would the solution to this be? Would it basically be: allowing inlined primitives to parse default_nettype <any_string> and then print default_nettype <any_string> (i.e., the same string) right before we print the inlined primitives in the Verilog backend?

My personal pick on what to do would be to avoid using the default_nettype directive. Then, try not to use any implicit declarations of nets. So remove default_nettype none from core.sv. Then I would adjust the inline Verilog emitter to write output logic for each output of the primitive and input wire for each input.

This way we try not to have any implicit types. But we don't crash if we do. I could draft up a PR later if we think this the right idea.

Sounds like the right idea to me!