Skip to content

Commit

Permalink
Further work on latency counting
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Dec 12, 2023
1 parent 3a331f9 commit 04e11ae
Show file tree
Hide file tree
Showing 10 changed files with 302 additions and 73 deletions.
19 changes: 19 additions & 0 deletions src/arena_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ impl<T, IndexMarker : UUIDMarker> FlatAlloc<T, IndexMarker> {
self.data.push(value);
UUID(uuid, PhantomData)
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn iter<'a>(&'a self) -> FlatAllocIter<'a, T, IndexMarker> {
self.into_iter()
}
Expand Down Expand Up @@ -397,6 +400,14 @@ impl<'a, T, IndexMarker : UUIDMarker> Iterator for FlatAllocIter<'a, T, IndexMar
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(id, v)| (UUID(id, PhantomData), v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, T, IndexMarker : UUIDMarker> ExactSizeIterator for FlatAllocIter<'a, T, IndexMarker> {
fn len(&self) -> usize {
self.iter.len()
}
}

impl<'a, T, IndexMarker : UUIDMarker> IntoIterator for &'a FlatAlloc<T, IndexMarker> {
Expand All @@ -421,6 +432,14 @@ impl<'a, T, IndexMarker : UUIDMarker> Iterator for FlatAllocIterMut<'a, T, Index
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(id, v)| (UUID(id, PhantomData), v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, T, IndexMarker : UUIDMarker> ExactSizeIterator for FlatAllocIterMut<'a, T, IndexMarker> {
fn len(&self) -> usize {
self.iter.len()
}
}

impl<'a, T, IndexMarker : UUIDMarker> IntoIterator for &'a mut FlatAlloc<T, IndexMarker> {
Expand Down
2 changes: 1 addition & 1 deletion src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub enum AssignableExpression {
#[derive(Debug)]
pub struct AssignableExpressionWithModifiers {
pub expr : SpanAssignableExpression,
pub num_regs : u32
pub num_regs : i64
}

#[derive(Debug)]
Expand Down
9 changes: 7 additions & 2 deletions src/codegen.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{ops::Deref, io};

use crate::{linker::Linker, flattening::{FlattenedModule, FlatID}, ast::{Module, Span}, arena_alloc::ListAllocator};
use crate::{linker::Linker, flattening::{FlattenedModule, FlatID}, ast::{Module, Span}, arena_alloc::ListAllocator, instantiation::InstantiatedModule};


use moore_circt::{hw, comb, mlir::{self, Owned, builder, OperationExt, SingleBlockOp}, mlir::{Context, OwnedContext, DialectHandle, Builder, Value, Type}};
Expand All @@ -19,7 +19,7 @@ impl GenerationContext {
Self{global_ctx}
}

pub fn to_circt(&self) {
pub fn to_circt(&self, instance : &InstantiatedModule) {
let ctx = *self.global_ctx.deref();
//moore_circt::hw::
let module = moore_circt::ModuleOp::new(ctx);
Expand All @@ -29,6 +29,11 @@ impl GenerationContext {
let mut builder = Builder::new(mod_ctx);
builder.set_insertion_point_to_start(module.block());

//let mut wire_names = instance.wires.iter().map(|a| builder.)
for (id, w) in &instance.wires {

}

//mlir_builder.set_loc(span_to_loc(mod_ctx, hir.span()));
//mlir_builder.set_insertion_point_to_end(self.into_mlir.block());

Expand Down
32 changes: 20 additions & 12 deletions src/dev_aid/syntax_highlighting.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

use std::{ops::Range, path::PathBuf};
use std::{ops::Range, path::{PathBuf, Path}};

use crate::{ast::*, tokenizer::*, parser::*, linker::{PreLinker, FileData, Links, NamedUUID, Named, Linkable}, arena_alloc::ArenaVector};
use crate::{ast::*, tokenizer::*, parser::*, linker::{PreLinker, FileData, Links, NamedUUID, Named, Linkable, Linker, FileUUIDMarker, FileUUID}, arena_alloc::ArenaVector};

use ariadne::FileCache;
use console::Style;
Expand Down Expand Up @@ -210,7 +210,7 @@ fn generate_character_offsets(file_text : &str, tokens : &[Token]) -> Vec<Range<
character_offsets
}

pub fn syntax_highlight_file(file_paths : Vec<PathBuf>, settings : &SyntaxHighlightSettings) {
pub fn compile_all(file_paths : Vec<PathBuf>) -> (Linker, ArenaVector<PathBuf, FileUUIDMarker>) {
let mut prelinker : PreLinker = PreLinker::new();
let mut paths_arena = ArenaVector::new();
for file_path in file_paths {
Expand All @@ -233,18 +233,15 @@ pub fn syntax_highlight_file(file_paths : Vec<PathBuf>, settings : &SyntaxHighli

let mut linker = prelinker.link();

let mut file_cache : FileCache = Default::default();

linker.recompile_all();

for (file_uuid, f) in &linker.files {
if settings.show_tokens {
print_tokens(&f.file_text, &f.tokens);
}

let ide_tokens = create_token_ide_info(f, &linker.links);
pretty_print(&f.file_text, &f.tokens, &ide_tokens);
(linker, paths_arena)
}

pub fn print_all_errors(linker : &Linker, paths_arena : &ArenaVector<PathBuf, FileUUIDMarker>) {
let mut file_cache : FileCache = Default::default();

for (file_uuid, f) in &linker.files {
let token_offsets = generate_character_offsets(&f.file_text, &f.tokens);

let mut errors = f.parsing_errors.clone();
Expand All @@ -255,3 +252,14 @@ pub fn syntax_highlight_file(file_paths : Vec<PathBuf>, settings : &SyntaxHighli
}
}
}

pub fn syntax_highlight_file(linker : &Linker, file_uuid : FileUUID, settings : &SyntaxHighlightSettings) {
let f = &linker.files[file_uuid];

if settings.show_tokens {
print_tokens(&f.file_text, &f.tokens);
}

let ide_tokens = create_token_ide_info(f, &linker.links);
pretty_print(&f.file_text, &f.tokens, &ide_tokens);
}
12 changes: 6 additions & 6 deletions src/flattening.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ impl ConnectionWrite {
}
}

#[derive(Debug)]
pub struct InterfacePort<UID> {
#[derive(Debug,Clone,Copy)]
pub struct InterfacePort {
pub is_input : bool,
pub id : UID
pub id : FlatID
}

#[derive(Debug)]
pub enum Instantiation {
SubModule{module_uuid : NamedUUID, typ_span : Span, interface_wires : Vec<InterfacePort<FlatID>>},
SubModule{module_uuid : NamedUUID, typ_span : Span, interface_wires : Vec<InterfacePort>},
PlainWire{read_only : bool, typ : Type, decl_id : Option<DeclID>},
UnaryOp{typ : Type, op : Operator, right : SpanFlatID},
BinaryOp{typ : Type, op : Operator, left : SpanFlatID, right : SpanFlatID},
Expand Down Expand Up @@ -86,7 +86,7 @@ impl Instantiation {

#[derive(Debug)]
pub struct Connection {
pub num_regs : u32,
pub num_regs : i64,
pub from : SpanFlatID,
pub to : ConnectionWrite,
pub condition : FlatID
Expand Down Expand Up @@ -148,7 +148,7 @@ impl<'l, 'm, 'fl> FlatteningContext<'l, 'm, 'fl> {

Instantiation::SubModule{module_uuid, typ_span, interface_wires}
}
fn desugar_func_call(&self, func_and_args : &[SpanExpression], closing_bracket_pos : usize, condition : FlatID) -> Option<(&Module, &[InterfacePort<FlatID>])> {
fn desugar_func_call(&self, func_and_args : &[SpanExpression], closing_bracket_pos : usize, condition : FlatID) -> Option<(&Module, &[InterfacePort])> {
let (name_expr, name_expr_span) = &func_and_args[0]; // Function name is always there
let func_instantiation_id = match name_expr {
Expression::Named(LocalOrGlobal::Local(l)) => {
Expand Down
150 changes: 150 additions & 0 deletions src/instantiation/latency.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
use std::{iter::zip, collections::VecDeque};

use crate::arena_alloc::FlatAlloc;

use super::{WireID, WireIDMarker, RealWire, SubModule, SubModuleIDMarker};




struct FanInOut {
other : WireID,
delta_latency : i64
}

/*
Algorithm:
Initialize all inputs at latency 0
Perform full forward pass, making latencies the maximum of all incoming latencies
Then backward pass, moving nodes forward in latency as much as possible.
Only moving forward is possible, and only when not confliciting with a later node
*/
struct LatencyComputer {
fanins : FlatAlloc<Vec<FanInOut>, WireIDMarker>,
fanouts : FlatAlloc<Vec<FanInOut>, WireIDMarker>
}

impl LatencyComputer {
fn setup(wires : &FlatAlloc<RealWire, WireIDMarker>, submodules : &FlatAlloc<SubModule, SubModuleIDMarker>) -> Self {
// Wire to wire Fanin
let mut fanins : FlatAlloc<Vec<FanInOut>, WireIDMarker> = wires.iter().map(|(id, wire)| {
let mut fanin = Vec::new();
wire.source.iter_sources_with_min_latency(|from, delta_latency| {
fanin.push(FanInOut{other : from, delta_latency});
});
fanin
}).collect();

// Submodules Fanin
for (_id, sub_mod) in submodules {
for (input_wire, input_port) in zip(&sub_mod.wires, &sub_mod.instance.interface) {
if !input_port.is_input {continue;}
for (output_wire, output_port) in zip(&sub_mod.wires, &sub_mod.instance.interface) {
if output_port.is_input {continue;}

let delta_latency = output_port.absolute_latency - input_port.absolute_latency;

fanins[*output_wire].push(FanInOut{other: *input_wire, delta_latency});
}
}
}

// Process fanouts
let mut fanouts : FlatAlloc<Vec<FanInOut>, WireIDMarker> = wires.iter().map(|(id, wire)| {
Vec::new()
}).collect();

for (id, fin) in &fanins {
for f in fin {
fanouts[f.other].push(FanInOut { other: id, delta_latency: f.delta_latency })
}
}

Self {fanins, fanouts}
}

fn compute_latencies_forward(&self) -> FlatAlloc<i64, WireIDMarker> {
let mut latencies : FlatAlloc<i64, WireIDMarker> = self.fanins.iter().map(|_| 0).collect();

let mut queue : VecDeque<WireID> = VecDeque::new();
queue.reserve(self.fanins.len());

let mut order : Vec<WireID> = Vec::new();
order.reserve(self.fanins.len());

for (id, v) in &self.fanouts {
if v.is_empty() {
queue.push_back(id);
latencies[id] = 1; // Initialize with 1
}
}

while let Some(s) = queue.pop_front() {
let mut all_explored = false;
for from in &self.fanins[s] {

}
}

latencies
}
}

struct RuntimeData {
part_of_path : bool,
eliminated : bool,
maps_to : WireID
}
struct GraphDecycler<'f> {
runtime_data : FlatAlloc<RuntimeData, WireIDMarker>,
fanins : &'f FlatAlloc<Vec<FanInOut>, WireIDMarker>
}

impl<'f> GraphDecycler<'f> {
fn new(fanins : &FlatAlloc<Vec<FanInOut>, WireIDMarker>) -> GraphDecycler {
GraphDecycler {
runtime_data : fanins.iter().map(|(maps_to, _)| RuntimeData{ part_of_path: false, eliminated: false, maps_to }).collect(),
fanins
}
}

fn is_part_of_cycle(&mut self, id : WireID) -> Option<WireID> {
if self.runtime_data[id].eliminated {return None;}

if self.runtime_data[id].part_of_path {
// TODO Handle start removing cycle
return Some(id); // New node was part of path, remove it!
}

self.runtime_data[id].part_of_path = true;

for fi in &self.fanins[id] {
if let Some(cycle_root) = self.is_part_of_cycle(fi.other) {
if id == cycle_root {
// We have returned to the root
// Cycle is now removed
// So we just continue
} else {
// Part of the chain towards the root
return Some(cycle_root)
}
}
}

self.runtime_data[id].eliminated = true; // Once we finish a node, eliminate it
None
}

fn eliminate_cycles(&mut self) {
for (id, wire_fanin) in self.fanins {
if wire_fanin.is_empty() {
// New root to iterate from
self.is_part_of_cycle(id);
}


}

todo!()
}
}
Loading

0 comments on commit 04e11ae

Please sign in to comment.