Skip to content

Commit

Permalink
Remove unsafe code, make compute_needed_until
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Jul 15, 2024
1 parent 854dec6 commit 4806c09
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 34 deletions.
16 changes: 9 additions & 7 deletions src/codegen_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ struct CodeGenerationContext<'g, 'out, Stream: std::fmt::Write> {
program_text: &'out mut Stream,

use_latency: bool,

needed_untils : FlatAlloc<i64, WireIDMarker>
}

fn wire_name_with_latency(wire: &RealWire, absolute_latency: i64, use_latency: bool) -> String {
assert!(wire.absolute_latency <= absolute_latency);
assert!(wire.needed_until >= absolute_latency);

if use_latency && (wire.absolute_latency != absolute_latency) {
format!("{}_D{}", wire.name, absolute_latency)
Expand Down Expand Up @@ -109,12 +110,12 @@ impl<'g, 'out, Stream: std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
result
}

fn add_latency_registers(&mut self, w: &RealWire) -> Result<(), std::fmt::Error> {
fn add_latency_registers(&mut self, wire_id: WireID, w: &RealWire) -> Result<(), std::fmt::Error> {
if self.use_latency {
// Can do 0 iterations, when w.needed_until == w.absolute_latency. Meaning it's only needed this cycle
assert!(w.absolute_latency != CALCULATE_LATENCY_LATER);
assert!(w.needed_until != CALCULATE_LATENCY_LATER);
for i in w.absolute_latency..w.needed_until {
assert!(self.needed_untils[wire_id] != CALCULATE_LATENCY_LATER);
for i in w.absolute_latency..self.needed_untils[wire_id] {
let from = wire_name_with_latency(w, i, self.use_latency);
let to = wire_name_with_latency(w, i + 1, self.use_latency);

Expand Down Expand Up @@ -148,11 +149,11 @@ impl<'g, 'out, Stream: std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
writeln!(self.program_text, ");\n")?;
for (_id, port) in self.instance.interface_ports.iter_valids() {
let port_wire = &self.instance.wires[port.wire];
self.add_latency_registers(port_wire)?;
self.add_latency_registers(port.wire, port_wire)?;
}

// Then output all declarations, and the wires we can already assign
for (_id, w) in &self.instance.wires {
for (wire_id, w) in &self.instance.wires {
// For better readability of output Verilog
if self.can_inline(w) {
continue;
Expand Down Expand Up @@ -217,7 +218,7 @@ impl<'g, 'out, Stream: std::fmt::Write> CodeGenerationContext<'g, 'out, Stream>
}
}
}
self.add_latency_registers(w)?;
self.add_latency_registers(wire_id, w)?;
}

// Output all submodules
Expand Down Expand Up @@ -320,6 +321,7 @@ pub fn gen_verilog_code(md: &Module, instance: &InstantiatedModule, use_latency:
instance,
program_text: &mut program_text,
use_latency,
needed_untils: instance.compute_needed_untils()
};
ctx.write_verilog_code().unwrap();

Expand Down
6 changes: 0 additions & 6 deletions src/instantiation/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,6 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
typ: value.typ,
name: self.unique_name_producer.get_unique_name(""),
absolute_latency: CALCULATE_LATENCY_LATER,
needed_until: CALCULATE_LATENCY_LATER,
})
}
fn get_wire_or_constant_as_wire(
Expand Down Expand Up @@ -481,7 +480,6 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
typ: ConcreteType::Unknown,
name: self.unique_name_producer.get_unique_name(format!("{}_{}", submod_instance.name, port_data.name)),
absolute_latency: CALCULATE_LATENCY_LATER,
needed_until: CALCULATE_LATENCY_LATER,
});

let name_refs = if let Some(sp) = port_name_span {
Expand Down Expand Up @@ -564,7 +562,6 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
domain,
source,
absolute_latency: CALCULATE_LATENCY_LATER,
needed_until: CALCULATE_LATENCY_LATER,
}))
}
fn extend_condition(
Expand All @@ -586,7 +583,6 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
right: additional_condition,
},
absolute_latency: CALCULATE_LATENCY_LATER,
needed_until: CALCULATE_LATENCY_LATER,
})
} else {
additional_condition
Expand Down Expand Up @@ -641,7 +637,6 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
domain: wire_decl.typ.domain.unwrap_physical(),
source,
absolute_latency,
needed_until: CALCULATE_LATENCY_LATER,
});
SubModuleOrWire::Wire(wire_id)
})
Expand Down Expand Up @@ -782,7 +777,6 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
right: condition_wire,
},
absolute_latency: CALCULATE_LATENCY_LATER,
needed_until: CALCULATE_LATENCY_LATER,
});
let else_cond = self.extend_condition(
condition,
Expand Down
36 changes: 19 additions & 17 deletions src/instantiation/latency_count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,25 @@ impl RealWireDataSource {
}
}

impl InstantiatedModule {
/// Is used to add implicit registers to wires that are used longer than one cycle.
///
/// If needed only the same cycle it is generated, then this is equal to [RealWire::absolute_latency].
pub fn compute_needed_untils(&self) -> FlatAlloc<i64, WireIDMarker> {
let mut result = self.wires.map(|(id, w)| w.absolute_latency);

for (_id, w) in &self.wires {
w.source.iter_sources_with_min_latency(|other, _| {
let nu = &mut result[other];

*nu = max(*nu, w.absolute_latency);
});
}

result
}
}

impl<'fl, 'l> InstantiationContext<'fl, 'l> {
fn make_wire_to_latency_map(&self) -> WireToLatencyMap {
const PLACEHOLDER: usize = usize::MAX;
Expand Down Expand Up @@ -338,23 +357,6 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
};
}

// Compute needed_untils
for (_id, w) in &mut self.wires {
w.needed_until = w.absolute_latency;
}
let mut_wires_ref: *mut _ = &mut self.wires;
for (_id, w) in &self.wires {
w.source.iter_sources_with_min_latency(|other, _| {
// SAFETY: Need some unsafe code to modify needed_until while iterating through the wires
// We write to needed_until everywhere, and for the information we need we never read needed_until
unsafe {
let nu = &mut (*mut_wires_ref)[other].needed_until;

*nu = max(*nu, w.absolute_latency);
}
});
}

// Finally update interface absolute latencies
for (_id, port) in self.interface_ports.iter_valids_mut() {
port.absolute_latency = self.wires[port.wire].absolute_latency;
Expand Down
4 changes: 0 additions & 4 deletions src/instantiation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ pub struct RealWire {
pub domain: DomainID,
/// Before latency counting, non i64::MIN values specify specified latency
pub absolute_latency: i64,
/// Is used to add implicit registers to wires that are used longer than one cycle.
///
/// If needed only the same cycle it is generated, then this is equal to [RealWire::absolute_latency].
pub needed_until: i64,
}

#[derive(Debug)]
Expand Down
2 changes: 2 additions & 0 deletions verilog_output/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
*.sv
*.vhdl
*.vh
# Any build directories created by Verilator or other tools
**/

0 comments on commit 4806c09

Please sign in to comment.