Skip to content

Commit

Permalink
Extract struct InterfacePorts, minor latency work
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Jan 20, 2024
1 parent 4cd04c8 commit e4f047a
Show file tree
Hide file tree
Showing 7 changed files with 289 additions and 196 deletions.
50 changes: 43 additions & 7 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{tokenizer::{TokenTypeIdx, get_token_type_name}, linker::FileUUID, flattening::FlattenedModule, arena_alloc::{UUIDMarker, UUID, FlatAlloc}, instantiation::InstantiationList, value::Value, errors::ErrorCollector};
use core::ops::Range;
use std::fmt::Display;
use std::{fmt::Display, iter::zip};

// Token span. Indices are INCLUSIVE
#[derive(Clone,Copy,Debug,PartialEq,Eq)]
Expand Down Expand Up @@ -155,13 +155,49 @@ impl LinkInfo {
}
}


#[derive(Debug, Clone)]
pub struct InterfacePorts<ID : Clone + Copy> {
pub outputs_start : usize,
pub ports : Box<[ID]>
}

impl<ID : Clone + Copy> InterfacePorts<ID> {
pub fn empty() -> Self {
InterfacePorts{outputs_start : 0, ports : Box::new([])}
}

// Todo, just treat all inputs and outputs as function call interface
pub fn func_call_syntax_inputs(&self) -> Range<usize> {
0..self.outputs_start
}
pub fn func_call_syntax_outputs(&self) -> Range<usize> {
self.outputs_start..self.ports.len()
}
pub fn inputs(&self) -> &[ID] {
&self.ports[..self.outputs_start]
}
pub fn outputs(&self) -> &[ID] {
&self.ports[self.outputs_start..]
}

pub fn map<OtherID : Clone + Copy, MapFn : FnMut(ID, /*is_input : */bool) -> OtherID>(&self, f : &mut MapFn) -> InterfacePorts<OtherID> {
InterfacePorts{
ports : self.ports.iter().enumerate().map(|(idx, v)| f(*v, idx < self.outputs_start)).collect(),
outputs_start : self.outputs_start
}
}
pub fn iter(&self) -> impl Iterator<Item = (ID, /*is_input : */bool)> + '_ {
self.ports.iter().enumerate().map(|(idx, v)| (*v, idx < self.outputs_start))
}
}

#[derive(Debug)]
pub struct Module {
pub link_info : LinkInfo,

pub declarations : FlatAlloc<SignalDeclaration, DeclIDMarker>,
pub ports : Box<[DeclID]>,
pub outputs_start : usize,
pub ports : InterfacePorts<DeclID>,
pub code : CodeBlock,

pub flattened : FlattenedModule,
Expand All @@ -172,10 +208,10 @@ pub struct Module {
impl Module {
pub fn print_flattened_module(&self) {
println!("Interface:");
for (port_idx, port) in self.flattened.interface_ports.iter().enumerate() {
let port_direction = if port_idx < self.flattened.outputs_start {"input"} else {"output"};
let port_name = &self.declarations[self.ports[port_idx]].name;
println!(" {port_direction} {port_name} -> {:?}", *port);
for ((port, is_input), port_decl) in zip(self.flattened.interface_ports.iter(), self.ports.ports.iter()) {
let port_direction = if is_input {"input"} else {"output"};
let port_name = &self.declarations[*port_decl].name;
println!(" {port_direction} {port_name} -> {:?}", port);
}
println!("Instantiations:");
for (id, inst) in &self.flattened.instantiations {
Expand Down
14 changes: 7 additions & 7 deletions src/codegen_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ pub fn gen_verilog_code(md : &Module, instance : &InstantiatedModule) -> String
assert!(!instance.errors.did_error.get(), "Module cannot have experienced an error");
let mut program_text : String = format!("module {}(\n\tinput clk, \n", md.link_info.name);
let submodule_interface = instance.interface.as_ref().unwrap();
for (port_idx, real_port) in submodule_interface.iter().enumerate() {
let wire = &instance.wires[*real_port];
program_text.push_str(if port_idx < md.flattened.outputs_start {"\tinput"} else {"\toutput /*mux_wire*/ reg"});
for (real_port, is_input) in submodule_interface.iter() {
let wire = &instance.wires[real_port];
program_text.push_str(if is_input {"\tinput"} else {"\toutput /*mux_wire*/ reg"});
program_text.push_str(&typ_to_verilog_array(&wire.typ));
program_text.push(' ');
program_text.push_str(&wire.name);
Expand Down Expand Up @@ -114,12 +114,12 @@ pub fn gen_verilog_code(md : &Module, instance : &InstantiatedModule) -> String
program_text.push(' ');
program_text.push_str(&sm.name);
program_text.push_str("(\n.clk(clk)");
let Some(sm_interface) = &sm.instance.interface else {unreachable!()}; // Having an invalid interface in a submodule is an error! This should have been caught before!
for (port, wire) in zip(sm_interface, &sm.wires) {
let sm_interface = sm.instance.interface.as_ref().unwrap(); // Having an invalid interface in a submodule is an error! This should have been caught before!
for (port, wire) in zip(sm_interface.iter(), sm.wires.iter()) {
program_text.push_str(",\n.");
program_text.push_str(&sm.instance.wires[*port].name);
program_text.push_str(&sm.instance.wires[port.0].name);
program_text.push('(');
program_text.push_str(&instance.wires[*wire].name);
program_text.push_str(&instance.wires[wire.0].name);
program_text.push_str(")");
}
program_text.push_str("\n);\n");
Expand Down
Loading

0 comments on commit e4f047a

Please sign in to comment.