Skip to content

Commit

Permalink
Start work on IR generation
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Oct 27, 2023
1 parent 44437f0 commit 921545b
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 35 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ console = "0.15.7" # for terminal colors
ariadne = "0.3.0" # for nice errors
num-bigint = "0.4.3"

calyx-ir = {version = "0.6.1", optional = true}
calyx-opt = {version = "0.6.1", optional = true}
calyx-backend = {version = "0.6.1", optional = true}

#lsp
lsp-server = {version = "0.7.1", optional = true}
lsp-types = {version = "0.94.0", optional = true}
Expand All @@ -24,4 +28,4 @@ serde = {version = "1.0.156", optional = true}

[features]
lsp = ["lsp-server", "lsp-types", "serde_json", "serde"]

codegen = ["calyx-ir", "calyx-opt", "calyx-backend"]
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ The main goals of the language are roughly listed below:

## Tasks
### Major Milestones
- [ ] Arbitrary forward pipelines representable
- [ ] Arbitrary FPGA hardware representable
- [ ] Arbitrary forward pipelines full flow
- [ ] Arbitrary FPGA hardware full flow
- [ ] Generative Code
- [ ] Templates
### Parsing
Expand All @@ -43,8 +43,8 @@ The main goals of the language are roughly listed below:
- [x] Function Call Syntax
- [x] Unary and Binary Operators
- [x] Can Parse Multiply-Add pipeline
- [ ] Can Parse Blur2 filter
- [ ] If Statements
- [x] Can Parse Blur2 filter
- [x] If Statements
- [ ] For Loops
- [ ] Multi-Interface Syntax
- [ ] Native Module integration syntax
Expand Down
65 changes: 58 additions & 7 deletions multiply_add.sus
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ module multiply_add : i32 a, i32 b, i32 c -> i32 result, double double_result {
reg double_result = cvt_to_double(result);
}

timeline (a -> /) .. (a -> r)*
/*timeline (a -> /) .. (a -> r)*
module blur : i32'0 a -> i32'1 result {
state int prev = a;
#
Expand All @@ -125,7 +125,7 @@ module blur : i32'0 a -> i32'1 result {
prev = a;
# // timeline step
}
}
}*/

timeline (a -> /) .. (a -> r)*
module my_complex_operation : i32'0 a -> i32'9 result {
Expand Down Expand Up @@ -172,12 +172,48 @@ module use_other_file : int a -> int r {
}


interface maemory_read : int addr -> bool[16] data;

//HandShake hs = hs_0;

module test_hs {
state int st = 5;

gen if HA_HANDSHAKE {}
interface hs {

interface boop {

}
};
interface process : int[10] data -> int[9] data {

}
}

module b: HandShake hs -> {
if hs.event {

}
}








module Tree_Multiply : int[4] values -> int total {
reg int a = values[0] * values[1];
reg int b = values[2] * values[3];
int a = values[0] * values[1];
int b = values[2] * values[3];
reg total = a * b;
}





//timeline (X, false -> /)* .. (X, true -> T)
module Accumulator : int term, bool done -> int total {
state int tot = 0; // Initial value, not a real assignment
Expand All @@ -186,12 +222,27 @@ module Accumulator : int term, bool done -> int total {
if done {
total = new_tot;
tot = 0;
finish; // packet is hereby finished.
//finish; // packet is hereby finished.
} else {
tot = new_tot;
}
}


//timeline (a, true -> /) | (a, false -> /) .. (a, false -> r)* .. (a, true -> r)
module blur : int a, bool done -> int result {
state bool working = false; // Initial value, not a real assignment
state int prev;

if working {
reg result = prev + a; // Add a pipeline stage for shits and giggles
}
prev = a;
working = !done;
}



//timeline (X -> X) .. (/ -> X) .. (/ -> X) .. (/ -> X)
module Unpack4 : int[4] packed -> int out_stream {
state int st = 0; // Initial value, not a real assignment
Expand All @@ -211,7 +262,7 @@ module Unpack4 : int[4] packed -> int out_stream {
st = 3;
} else if st == 3 {
out_stream = stored_packed[2];
st = 0;
finish; // packet is hereby finished.
st = 0; // Must restore initial conditions
//finish; // packet is hereby finished.
}
}
8 changes: 8 additions & 0 deletions philosophy/instantiation.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,11 @@ Because we have a broader vocabulary describing our modules, it becomes possible
Additional modifiers
- Latency-free: All latency registers are removed
- Set latency: sets the latency between two connectors (ports, locals, fields etc), adding or removing latency registers as needed. Mustly used to override latency for tight feedback loops.

# Structs and Modules and Constants
So structs, modules and constants all very much look alike in a certain sense. But modules must be distinct from structs and constants. Because Modules *cannot* be freely copied or moved around. But, one would want it possible to instantiate modules in arrays.

## Templates

## Template - Flow - Lifetime dichotomy
When instantiating
3 changes: 3 additions & 0 deletions philosophy/safety.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Examples:

Compiler warnings or errors on data that sits unused, ports that go unread, or ports that are written when no data is expected are all prevented by the flow descriptor system. Of course, it's not possible to prevent data from being lost within the module state itself.

#### Safe Clock Domain Crossing through rhythms


## Flow Descriptors
On any module or interface we can specify flow descriptors. These describe how and in which patterns data are allowed to flow through a module. Much like rust's borrow checker, this provides an additional layer of code flow analysis that must be verified for correctness. They are written in a kind of regex-like syntax, ideally with the full descriptive power of Linear Temporal Logic (LTL). Like with typing and borrow checking, the additional information describes the *what*, whereas the code describes the *how*.

Expand Down
12 changes: 10 additions & 2 deletions src/arena_alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ pub struct UUID<IndexMarker>(usize, PhantomData<IndexMarker>);

impl<IndexMarker> fmt::Debug for UUID<IndexMarker> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("id_")?;
self.0.fmt(f)
if self.0 == Self::INVALID.0 {
f.write_str("id_INV")
} else {
f.write_str("id_")?;
self.0.fmt(f)
}
}
}

Expand Down Expand Up @@ -237,6 +241,10 @@ impl<T, IndexMarker> ListAllocator<T, IndexMarker> {
pub fn iter_mut<'a>(&'a mut self) -> ListAllocIteratorMut<'a, T, IndexMarker> {
self.into_iter()
}
pub fn map<OutT, F : FnMut(UUID<IndexMarker>, &T) -> OutT>(&self, f : &mut F) -> ListAllocator<OutT, IndexMarker> {
let data = self.iter().map(|(a, v)| f(a, v)).collect();
ListAllocator{data, _ph : PhantomData}
}
}

impl<T, IndexMarker> Index<UUID<IndexMarker>> for ListAllocator<T, IndexMarker> {
Expand Down
69 changes: 67 additions & 2 deletions src/codegen.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,74 @@
use crate::linker::Linker;
use crate::{linker::Linker, flattening::{FlattenedModule, WireID}, ast::{Module, Span}, arena_alloc::ListAllocator};


use calyx_ir::*;


pub fn gen_code(linker : &mut Linker, ) {
pub fn to_calyx(md : &Module, flattened : &FlattenedModule, linker : &Linker) {
calyx_ir::
//calyx_ir::Builder::new(component, lib);
calyx_ir::build_assignments!();

let mut test_comp = calyx_ir::Component::new("name", vec![], true, true, None);
test_comp.

let builder = calyx_ir::Builder::new(component, lib)

let ctx : calyx_ir::Context = calyx_ir::Builder;

let backend = calyx_backend::VerilogBackend;

let res : CalyxResult<()> = backend.emit(ctx: &ir::Context, file: &mut OutputFile)
}


pub fn gen_verilog_code(md : &Module, flattened : &FlattenedModule, linker : &Linker) {
let mut cur_wire_id : usize = 0;
let mut wire_names = flattened.wires.map(&mut |_id, _| {
let name = format!("w_{cur_wire_id}");
cur_wire_id += 1;
name
});

let mut cur_inst_id : usize = 0;
let mut instance_names = flattened.instantiations.map(&mut |_id, _| {
let name = format!("inst_{cur_inst_id}");
cur_inst_id += 1;
name
});

let file = &linker.files[md.link_info.file];
for (idx, v) in md.declarations.iter().enumerate() {
let name = file.file_text[v.name.clone()].to_owned();
match &flattened.local_map[idx].wire_or_instance {
crate::flattening::WireOrInstantiation::Wire(w_idx) => {
wire_names[*w_idx] = name;
},
crate::flattening::WireOrInstantiation::Instantiation(i_idx) => {
instance_names[*i_idx] = name;
},
crate::flattening::WireOrInstantiation::Other(_) => {},
}
}

println!("Module {} {{", &file.file_text[file.tokens[md.link_info.name_token].get_range()]);
for (id, w) in &flattened.wires {
println!("\twire {:?} {};", w.typ, &wire_names[id]);
}
println!();
for (id, i) in &flattened.instantiations {
println!("\tinstantiation {:?} {};", i, &instance_names[id]);
}
println!();
for conn in &flattened.connections {
let regs = "reg ".repeat(conn.num_regs as usize);


if conn.condition != WireID::INVALID {

}
println!("\t·{regs}{:?} {};", i, &instance_names[id]);
}
println!("}}")
}

37 changes: 19 additions & 18 deletions src/flattening.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ use crate::{
};

#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Hash)]
struct WireIDMarker;
type WireID = UUID<WireIDMarker>;
pub struct WireIDMarker;
pub type WireID = UUID<WireIDMarker>;

#[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Hash)]
struct InstantiationIDMarker;
type InstantiationID = UUID<InstantiationIDMarker>;
pub struct InstantiationIDMarker;
pub type InstantiationID = UUID<InstantiationIDMarker>;

#[derive(Debug)]
enum WireOrInstantiation {
pub enum WireOrInstantiation {
Wire(WireID),
Instantiation(InstantiationID),
Other(ValueUUID)
}

#[derive(Debug)]
struct LocalVariable {
pub struct LocalVariable {
pub location : Span,
pub wire_or_instance : WireOrInstantiation
}
Expand All @@ -47,18 +47,18 @@ enum ConnectionWrite {
type SpanConnectionRead = (ConnectionRead, Span);

#[derive(Debug)]
enum Instantiation {
pub enum Instantiation {
Named(ValueUUID),
UnaryOp(Operator),
BinaryOp(Operator)
}

#[derive(Debug)]
struct Connection {
num_regs : u32,
from : SpanConnectionRead,
to : ConnectionWrite,
condition : WireID
pub struct Connection {
pub num_regs : u32,
pub from : SpanConnectionRead,
pub to : ConnectionWrite,
pub condition : WireID
}
impl Connection {
fn new(to : ConnectionWrite, from : SpanConnectionRead, condition : WireID) -> Connection {
Expand All @@ -67,8 +67,8 @@ impl Connection {
}

#[derive(Debug)]
struct Wire {
typ : Option<TypeExpression>
pub struct Wire {
pub typ : Option<TypeExpression>
}

struct FlatteningContext<'l, 'm, 'e> {
Expand Down Expand Up @@ -372,14 +372,15 @@ pub fn flatten(module : &Module, linker : &Linker, errors : &mut ErrorCollector)
let mut result = FlatteningContext::new(module, linker, errors);
result.flatten_code(&module.code, WireID::INVALID);

FlattenedModule { wires : result.wires, instantiations: result.instantiations, connections: result.connections }
FlattenedModule { local_map : result.named_locals_to_object_map, wires : result.wires, instantiations: result.instantiations, connections: result.connections }
}

#[derive(Debug)]
pub struct FlattenedModule {
wires : ListAllocator<Wire, WireIDMarker>,
instantiations : ListAllocator<Instantiation, InstantiationIDMarker>,
connections : Vec<Connection>
pub local_map : Vec<LocalVariable>,
pub wires : ListAllocator<Wire, WireIDMarker>,
pub instantiations : ListAllocator<Instantiation, InstantiationIDMarker>,
pub connections : Vec<Connection>
}


Expand Down
2 changes: 1 addition & 1 deletion src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ impl Linker {
pub fn flatten_all_modules_in_file(&self, file : FileUUID, errors : &mut ErrorCollector) {
for md_uuid in &self.files[file].associated_values {
let named = &self.links.globals[*md_uuid];
eprintln!("Flattening {}", named.get_name(self));
println!("Flattening {}", named.get_name(self));
if let Named::Module(md) = named {
if !md.link_info.is_fully_linked {
continue;
Expand Down
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ mod parser;
mod errors;
mod ast;
mod flattening;

#[cfg(feature = "codegen")]
mod codegen;

mod dev_aid;
Expand Down

0 comments on commit 921545b

Please sign in to comment.