Skip to content

Commit 5c9c8c2

Browse files
committed
Add latency registers to --gen-tb (Resolve #179)
1 parent c61952c commit 5c9c8c2

4 files changed

Lines changed: 83 additions & 5 deletions

File tree

src/codegen/system_verilog.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,8 @@ impl<'g> CodeGenerationContext<'g> {
167167
continue;
168168
}
169169
if matches!(port_wire.is_port, IsPort::Port(_, _)) {
170-
self.add_latency_registers(port_wire_id, port_wire).unwrap();
170+
self.add_latency_registers(port_wire, self.needed_untils[port_wire_id], "")
171+
.unwrap();
171172
}
172173
}
173174
}
@@ -203,13 +204,14 @@ impl<'g> CodeGenerationContext<'g> {
203204

204205
fn add_latency_registers(
205206
&mut self,
206-
wire_id: WireID,
207207
w: &RealWire,
208+
needed_until: i64,
209+
indent: &str,
208210
) -> Result<(), std::fmt::Error> {
209211
assert!(!w.typ.is_zero_sized());
210212

211213
// Can do 0 iterations, when w.needed_until == w.absolute_latency. Meaning it instantiates no registers
212-
for i in w.absolute_latency.unwrap()..self.needed_untils[wire_id] {
214+
for i in w.absolute_latency.unwrap()..needed_until {
213215
let from = self.wire_name_no_inling(w, AbsLat::new(i));
214216
let to = self.wire_name_no_inling(w, AbsLat::new(i + 1));
215217

@@ -218,7 +220,7 @@ impl<'g> CodeGenerationContext<'g> {
218220
let clk_name = &self.instance.clocks[w.clock].name;
219221
writeln!(
220222
self.program_text,
221-
"/*latency*/ logic{to_decl}; always_ff @(posedge {clk_name}) begin {to} <= {from}; end"
223+
"{indent}/*latency*/ logic{to_decl}; always_ff @(posedge {clk_name}) begin {to} <= {from}; end"
222224
).unwrap();
223225
}
224226
Ok(())
@@ -691,7 +693,8 @@ impl<'g> CodeGenerationContext<'g> {
691693
writeln!(self.program_text, "{decl_stm};").unwrap();
692694
}
693695
}
694-
self.add_latency_registers(wire_id, w).unwrap();
696+
self.add_latency_registers(w, self.needed_untils[wire_id], "")
697+
.unwrap();
695698
}
696699
}
697700

@@ -1087,6 +1090,25 @@ impl<'g> CodeGenerationContext<'g> {
10871090
}
10881091
}
10891092

1093+
let mut max_latency_per_domain = self.md.latency_domains.map(|_| i64::MIN);
1094+
for (_, port) in &self.instance.interface_ports {
1095+
let Some(port) = port else { continue };
1096+
let port_lat = port.absolute_latency.unwrap();
1097+
if port_lat > max_latency_per_domain[port.latency_domain] {
1098+
max_latency_per_domain[port.latency_domain] = port_lat;
1099+
}
1100+
}
1101+
1102+
writeln!(self.program_text, "\n\t// Latency Registers").unwrap();
1103+
for (_, port) in &self.instance.interface_ports {
1104+
let Some(port) = port else { continue };
1105+
1106+
let port_wire = &self.instance.wires[port.wire];
1107+
let needed_until = max_latency_per_domain[port.latency_domain];
1108+
self.add_latency_registers(port_wire, needed_until, "\t")
1109+
.unwrap();
1110+
}
1111+
10901112
writeln!(self.program_text, "\n\t// DUT").unwrap();
10911113
writeln!(
10921114
self.program_text,

test.sus

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,3 +1872,14 @@ module WeirdlyNamedClock {
18721872
state output bool y_st
18731873
y_st = y_i
18741874
}
1875+
1876+
module TwoDomainsWithLatRegs {
1877+
domain a
1878+
input bool a_i'9
1879+
reg reg reg output bool a_o = a_i
1880+
output bool a_o2'20 = a_i
1881+
1882+
domain b
1883+
input bool b_i'-20
1884+
output bool b_o = b_i
1885+
}

test.sus_codegen.sv

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test.sus_errors.txt

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)