Compare commits

...

5 Commits

@ -1 +1 @@
Subproject commit 77ff0310b431872b4255dc73c53ecddace57b611 Subproject commit 1d31d2d8e056198929fbef2eaff3a397afbc6640

@ -2,6 +2,56 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "anstream"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
dependencies = [
"windows-sys 0.60.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.60.2",
]
[[package]] [[package]]
name = "binary-serialize-derive" name = "binary-serialize-derive"
version = "0.1.0" version = "0.1.0"
@ -23,6 +73,52 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "clap"
version = "4.5.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.13" version = "0.3.13"
@ -51,6 +147,18 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "json" name = "json"
version = "0.12.4" version = "0.12.4"
@ -91,6 +199,12 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]] [[package]]
name = "piston-float" name = "piston-float"
version = "1.0.1" version = "1.0.1"
@ -143,6 +257,12 @@ dependencies = [
"windows-sys 0.60.2", "windows-sys 0.60.2",
] ]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.106" version = "2.0.106"
@ -173,6 +293,12 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "vecmath" name = "vecmath"
version = "1.0.0" version = "1.0.0"
@ -186,6 +312,7 @@ dependencies = [
name = "verilog2logicworld" name = "verilog2logicworld"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap",
"json", "json",
"logicworld-subassembly", "logicworld-subassembly",
"quaternion", "quaternion",

@ -9,3 +9,4 @@ json = "0.12.4"
quaternion = "2.0.0" quaternion = "2.0.0"
tempfile = "3.20.0" tempfile = "3.20.0"
vecmath = "1.0.0" vecmath = "1.0.0"
clap = { version = "4.5.45", features = ["derive"] }

@ -1,6 +1,6 @@
module gates( module gates(
input a,b,c,d, input [3:0] a,b,c,d,
output wire out, out2 output wire [3:0] out, out2
); );
assign out = a & b | c; assign out = a & b | c;
assign out2 = a & b ^ d; assign out2 = a & b ^ d;

@ -3,18 +3,32 @@ mod verilog;
use std::path::Path; use std::path::Path;
use clap::Parser;
use logicworld_subassembly::create_subassembly; use logicworld_subassembly::create_subassembly;
use verilog::compile_module; use verilog::compile_module;
use verilog::get_modules; use verilog::get_modules;
#[derive(Parser, Debug)]
#[command(version)]
struct Args {
/// Path to submodules directory inside LogicWorld
#[arg(short, long, default_value_t = String::from("output/"))]
output: String,
/// Verilog files to compile
files: Vec<String>,
}
fn main() { fn main() {
let files = ["gates.v"]; let args = Args::parse();
let files: Vec<&str> = args.files.iter().map(|f| f.as_str()).collect();
let result = get_modules(&files); let result = get_modules(&files);
println!("{:?}", result);
let Ok(modules) = result else { let Ok(modules) = result else {
println!("Error while getting modules: {:?}", result); println!("Error while getting modules: {:?}", result);
return; std::process::exit(1);
}; };
for module_name in modules { for module_name in modules {
@ -24,7 +38,7 @@ fn main() {
Ok(module) => module, Ok(module) => module,
Err(err) => { Err(err) => {
println!("Error while compiling module {}: {:?}", module_name, err); println!("Error while compiling module {}: {:?}", module_name, err);
return; std::process::exit(2);
} }
}; };
@ -33,16 +47,18 @@ fn main() {
Ok(pair) => pair, Ok(pair) => pair,
Err(err) => { Err(err) => {
println!("Error while routing module {}: {:?}", module_name, err); println!("Error while routing module {}: {:?}", module_name, err);
return; std::process::exit(3);
} }
}; };
let result = create_subassembly( let result = create_subassembly(module_name, &Path::new(&args.output), &components, &wires);
module_name, match result {
&Path::new("output/"), Ok(_) => {}
&components, Err(err) => {
&wires, println!("Error while creating subassembly: {:?}", err);
); std::process::exit(4);
println!("{:?}", result); }
};
println!("Success");
} }
} }

@ -1,21 +1,41 @@
use std::{collections::HashMap, f32::consts::PI}; use std::{collections::HashMap, f32::consts::PI, fmt::Debug};
use logicworld_subassembly::{lw, COMPONENT_MAP}; use logicworld_subassembly::{lw, COMPONENT_MAP};
use vecmath::{vec3_add, Vector3}; use vecmath::{vec3_add, Vector3};
use crate::verilog::{Cell, Error, Module}; use crate::verilog::{Cell, Error, Module};
// https://yosyshq.readthedocs.io/projects/yosys/en/0.39/CHAPTER_CellLib.html
const SQUARE: lw::Int = 300; const SQUARE: lw::Int = 300;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
struct Connection<'a> {
cell_index: usize,
port_name: &'a str,
bit_index: usize,
}
impl<'a> Debug for Connection<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}-{}-{}",
self.cell_index, self.port_name, self.bit_index
)
}
}
#[derive(Default, Debug)] #[derive(Default, Debug)]
struct Net<'a> { struct Net<'a> {
/// Index of cell that is outputting into this net (or None, if it's the module input) /// Index of cell that is outputting into this net (or None, if it's the module input)
connected_output: Option<(usize, &'a str)>, connected_output: Option<Connection<'a>>,
/// Indicies and names of ports of cells whose inputs are connected to this net /// Indicies and names of ports of cells whose inputs are connected to this net
connected_inputs: Vec<(usize, &'a str)>, connected_inputs: Vec<Connection<'a>>,
} }
type ConnectionMap<'a> = HashMap<Connection<'a>, lw::PegAddress>;
pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Error> { pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Error> {
let mut net_list: HashMap<usize, Net> = HashMap::new(); let mut net_list: HashMap<usize, Net> = HashMap::new();
@ -37,22 +57,30 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
); );
} }
} }
for (i, cell) in module.cells.iter().enumerate() { for (i_cell, cell) in module.cells.iter().enumerate() {
for (key, bits) in &cell.inputs { for (key, bits) in &cell.inputs {
for bit in bits { for (i_bit, bit) in bits.iter().enumerate() {
net_list net_list
.entry(*bit) .entry(*bit)
.or_insert(Net::default()) .or_insert(Net::default())
.connected_inputs .connected_inputs
.push((i, key)); .push(Connection {
cell_index: i_cell,
port_name: key,
bit_index: i_bit,
});
} }
} }
for (key, bits) in &cell.outputs { for (key, bits) in &cell.outputs {
for bit in bits { for (i_bit, bit) in bits.iter().enumerate() {
net_list net_list
.entry(*bit) .entry(*bit)
.or_insert(Net::default()) .or_insert(Net::default())
.connected_output = Some((i, key)); .connected_output = Some(Connection {
cell_index: i_cell,
port_name: key,
bit_index: i_bit,
});
} }
} }
} }
@ -69,7 +97,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
let mut input_ports: Vec<lw::Component> = vec![]; let mut input_ports: Vec<lw::Component> = vec![];
let mut output_ports: Vec<lw::Component> = vec![]; let mut output_ports: Vec<lw::Component> = vec![];
let mut connection_map: HashMap<(usize, &str), lw::PegAddress> = HashMap::new(); let mut connection_map: ConnectionMap = HashMap::new();
// the size of squares is 300 units // the size of squares is 300 units
// 150, 150, 150 is the middle of the first square // 150, 150, 150 is the middle of the first square
@ -105,6 +133,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
&mut wires,
&mut connection_map, &mut connection_map,
), ),
"$xor" => binary_op( "$xor" => binary_op(
@ -113,10 +142,12 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
&mut wires,
&mut connection_map, &mut connection_map,
), ),
"$or" => or_gate( "$or" => binary_op(
cell, cell,
"Custom.OrGate",
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
@ -129,6 +160,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
&mut wires,
&mut connection_map, &mut connection_map,
), ),
_ => return Err(Error::UnsupportedCell), _ => return Err(Error::UnsupportedCell),
@ -178,10 +210,15 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
for (id, net) in &net_list { for (id, net) in &net_list {
println!(); println!();
println!("{}: {:?}", id, net); println!("{}: {:#?}", id, net);
println!("map; {:?}", connection_map.keys()); println!("map; {:#?}", connection_map.keys());
let output_address = &connection_map[&net.connected_output.unwrap_or((*id, "input"))]; let output_address = &connection_map[&net.connected_output.unwrap_or(Connection {
cell_index: *id,
port_name: "input",
bit_index: 0, // TODO: figure out
})];
for input in &net.connected_inputs { for input in &net.connected_inputs {
println!("input: {:?}", input);
let input_address = &connection_map[input]; let input_address = &connection_map[input];
wires.push(lw::Wire { wires.push(lw::Wire {
first_point: output_address.clone(), first_point: output_address.clone(),
@ -192,7 +229,11 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
} }
if net.connected_inputs.is_empty() { if net.connected_inputs.is_empty() {
let input_address = &connection_map[&(*id, "output")]; let input_address = &connection_map[&Connection {
cell_index: *id,
port_name: "output",
bit_index: 0, // TODO: figure out
}];
wires.push(lw::Wire { wires.push(lw::Wire {
first_point: output_address.clone(), first_point: output_address.clone(),
second_point: input_address.clone(), second_point: input_address.clone(),
@ -211,9 +252,8 @@ fn input_port(
parent_address: u32, parent_address: u32,
next_address: &mut u32, next_address: &mut u32,
next_position: &mut Vector3<lw::Int>, next_position: &mut Vector3<lw::Int>,
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>, connection_map: &mut ConnectionMap,
) -> Vec<lw::Component> { ) -> Vec<lw::Component> {
let label = lw::Component { let label = lw::Component {
address: *next_address, address: *next_address,
parent: parent_address, parent: parent_address,
@ -237,7 +277,14 @@ fn input_port(
outputs: vec![], outputs: vec![],
custom_data: vec![], custom_data: vec![],
}; };
connection_map.insert((bit_id, "input"), lw::PegAddress::input(peg.address, 0)); connection_map.insert(
Connection {
cell_index: bit_id,
port_name: "input",
bit_index: 0,
},
lw::PegAddress::input(peg.address, 0),
);
*next_address += 1; *next_address += 1;
next_position[0] += SQUARE / 3; // third of a square next_position[0] += SQUARE / 3; // third of a square
@ -251,9 +298,8 @@ fn output_port(
parent_address: u32, parent_address: u32,
next_address: &mut u32, next_address: &mut u32,
next_position: &mut Vector3<lw::Int>, next_position: &mut Vector3<lw::Int>,
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>, connection_map: &mut ConnectionMap,
) -> Vec<lw::Component> { ) -> Vec<lw::Component> {
let label = lw::Component { let label = lw::Component {
address: *next_address, address: *next_address,
parent: parent_address, parent: parent_address,
@ -277,7 +323,14 @@ fn output_port(
outputs: vec![], outputs: vec![],
custom_data: vec![], custom_data: vec![],
}; };
connection_map.insert((bit_id, "output"), lw::PegAddress::input(peg.address, 0)); connection_map.insert(
Connection {
cell_index: bit_id,
port_name: "output",
bit_index: 0,
},
lw::PegAddress::input(peg.address, 0),
);
*next_address += 1; *next_address += 1;
next_position[0] += SQUARE / 3; // third of a square next_position[0] += SQUARE / 3; // third of a square
@ -291,97 +344,49 @@ fn binary_op(
parent_address: u32, parent_address: u32,
next_address: &mut u32, next_address: &mut u32,
next_position: &mut Vector3<i32>, next_position: &mut Vector3<i32>,
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>, wires: &mut Vec<lw::Wire>,
connection_map: &mut ConnectionMap,
) -> Vec<lw::Component> { ) -> Vec<lw::Component> {
let input_a = lw::Input::new(cell.inputs["A"][0] as i32); // All binary RTL cells have two input ports \A and \B and one output port \Y. They also have the following parameters:
let input_b = lw::Input::new(cell.inputs["B"][0] as i32);
let output = lw::Output::new(cell.outputs["Y"][0] as i32);
let component = lw::Component {
address: *next_address,
parent: parent_address,
numeric_id: COMPONENT_MAP[text_id],
position: *next_position,
rotation: quaternion::id(),
inputs: vec![input_a, input_b],
outputs: vec![output],
custom_data: vec![],
};
connection_map.insert( // Set to a non-zero value if the input \A is signed and therefore should be sign-extended when needed.
(cell.index, "A"), let a_signed = cell.parameters["A_SIGNED"] > 0;
lw::PegAddress::input(component.address, 0),
);
connection_map.insert(
(cell.index, "B"),
lw::PegAddress::input(component.address, 1),
);
connection_map.insert(
(cell.index, "Y"),
lw::PegAddress::output(component.address, 0),
);
*next_address += 1; // The width of the input port \A.
next_position[2] += 3 * SQUARE; let a_width = cell.parameters["A_WIDTH"];
return vec![component]; // Set to a non-zero value if the input \B is signed and therefore should be sign-extended when needed.
} let b_signed = cell.parameters["B_SIGNED"] > 0;
fn unary_op( // The width of the input port \B.
cell: &Cell, let b_width = cell.parameters["B_WIDTH"];
text_id: &str,
parent_address: u32,
next_address: &mut u32,
next_position: &mut Vector3<i32>,
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>,
) -> Vec<lw::Component> {
let input = lw::Input::new(cell.inputs["A"][0] as i32);
let output = lw::Output::new(cell.outputs["Y"][0] as i32);
let component = lw::Component {
address: *next_address,
parent: parent_address,
numeric_id: COMPONENT_MAP[text_id],
position: *next_position,
rotation: quaternion::id(),
inputs: vec![input],
outputs: vec![output],
custom_data: vec![],
};
connection_map.insert( // The width of the output port \Y.
(cell.index, "A"), let _y_width = cell.parameters["Y_WIDTH"];
lw::PegAddress::input(component.address, 0),
);
connection_map.insert(
(cell.index, "Y"),
lw::PegAddress::output(component.address, 0),
);
*next_address += 1; assert!(a_width == b_width, "Different widths not yet supported");
next_position[2] += 3 * SQUARE; assert!(!a_signed && !b_signed, "Signed not yet supported");
return vec![component]; // let mut next_parent = parent_address;
}
fn or_gate( let mut components = vec![];
cell: &Cell,
parent_address: u32, for i_bit in 0..a_width {
next_address: &mut u32, let input_a = lw::Input::new(cell.inputs["A"][i_bit] as i32);
next_position: &mut Vector3<lw::Int>, let input_b = lw::Input::new(cell.inputs["B"][i_bit] as i32);
wires: &mut Vec<lw::Wire>, let output_state_id = cell.outputs["Y"][i_bit] as lw::Int;
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>, let output = lw::Output::new(output_state_id);
) -> Vec<lw::Component> { if text_id == "Custom.OrGate" {
let input_a = lw::Input::new(cell.inputs["A"][0] as lw::Int); let input_a = lw::Input::new(cell.inputs["A"][0] as lw::Int);
let input_b = lw::Input::new(cell.inputs["B"][0] as lw::Int); let input_b = lw::Input::new(cell.inputs["B"][0] as lw::Int);
let output_state_id = cell.outputs["Y"][0] as lw::Int;
let output_a = lw::Output::new(output_state_id); let output_a = lw::Output::new(output_state_id);
let output_b = lw::Output::new(output_state_id); let output_b = lw::Output::new(output_state_id);
let peg = lw::Input::new(output_state_id); let peg = lw::Input::new(output_state_id);
let buffer_a = lw::Component { let buffer_a = lw::Component {
address: *next_address, address: *next_address,
parent: parent_address, parent: parent_address,
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"], numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
position: *next_position, position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]),
rotation: quaternion::id(), rotation: quaternion::id(),
inputs: vec![input_a], inputs: vec![input_a],
outputs: vec![output_a], outputs: vec![output_a],
@ -391,7 +396,7 @@ fn or_gate(
address: *next_address + 1, address: *next_address + 1,
parent: parent_address, parent: parent_address,
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"], numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
position: vec3_add(*next_position, [SQUARE, 0, 0]), position: vec3_add(*next_position, [SQUARE, (i_bit as lw::Int) * 2 * SQUARE, 0]),
rotation: quaternion::id(), rotation: quaternion::id(),
inputs: vec![input_b], inputs: vec![input_b],
outputs: vec![output_b], outputs: vec![output_b],
@ -401,7 +406,10 @@ fn or_gate(
address: *next_address + 2, address: *next_address + 2,
parent: parent_address, parent: parent_address,
numeric_id: COMPONENT_MAP["MHG.Peg"], numeric_id: COMPONENT_MAP["MHG.Peg"],
position: vec3_add(*next_position, [0, 0, 2 * SQUARE]), position: vec3_add(
*next_position,
[0, (i_bit as lw::Int) * 2 * SQUARE, 2 * SQUARE],
),
rotation: quaternion::id(), rotation: quaternion::id(),
inputs: vec![peg], inputs: vec![peg],
outputs: vec![], outputs: vec![],
@ -409,14 +417,29 @@ fn or_gate(
}; };
connection_map.insert( connection_map.insert(
(cell.index, "A"), Connection {
cell_index: cell.index,
port_name: "A",
bit_index: i_bit,
},
lw::PegAddress::input(buffer_a.address, 0), lw::PegAddress::input(buffer_a.address, 0),
); );
connection_map.insert( connection_map.insert(
(cell.index, "B"), Connection {
cell_index: cell.index,
port_name: "B",
bit_index: i_bit,
},
lw::PegAddress::input(buffer_b.address, 0), lw::PegAddress::input(buffer_b.address, 0),
); );
connection_map.insert((cell.index, "Y"), lw::PegAddress::input(peg.address, 0)); connection_map.insert(
Connection {
cell_index: cell.index,
port_name: "Y",
bit_index: i_bit,
},
lw::PegAddress::input(peg.address, 0),
);
wires.push(lw::Wire { wires.push(lw::Wire {
first_point: lw::PegAddress::output(buffer_a.address, 0), first_point: lw::PegAddress::output(buffer_a.address, 0),
@ -431,8 +454,98 @@ fn or_gate(
wire_rotation: 0.0, wire_rotation: 0.0,
}); });
components.push(buffer_a);
components.push(buffer_b);
components.push(peg);
*next_address += 3; *next_address += 3;
} else {
let component = lw::Component {
address: *next_address,
parent: parent_address,
numeric_id: COMPONENT_MAP[text_id],
position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]),
rotation: quaternion::id(),
inputs: vec![input_a, input_b],
outputs: vec![output],
custom_data: vec![],
};
*next_address += 1;
connection_map.insert(
Connection {
cell_index: cell.index,
port_name: "A",
bit_index: i_bit,
},
lw::PegAddress::input(component.address, 0),
);
connection_map.insert(
Connection {
cell_index: cell.index,
port_name: "B",
bit_index: i_bit,
},
lw::PegAddress::input(component.address, 1),
);
connection_map.insert(
Connection {
cell_index: cell.index,
port_name: "Y",
bit_index: i_bit,
},
lw::PegAddress::output(component.address, 0),
);
components.push(component);
}
}
next_position[2] += 5 * SQUARE; next_position[2] += 5 * SQUARE;
return vec![buffer_a, buffer_b, peg]; return components;
}
fn unary_op(
cell: &Cell,
text_id: &str,
parent_address: u32,
next_address: &mut u32,
next_position: &mut Vector3<i32>,
wires: &mut Vec<lw::Wire>,
connection_map: &mut ConnectionMap,
) -> Vec<lw::Component> {
let input = lw::Input::new(cell.inputs["A"][0] as i32);
let output = lw::Output::new(cell.outputs["Y"][0] as i32);
let component = lw::Component {
address: *next_address,
parent: parent_address,
numeric_id: COMPONENT_MAP[text_id],
position: *next_position,
rotation: quaternion::id(),
inputs: vec![input],
outputs: vec![output],
custom_data: vec![],
};
connection_map.insert(
Connection {
cell_index: cell.index,
port_name: "A",
bit_index: 0,
},
lw::PegAddress::input(component.address, 0),
);
connection_map.insert(
Connection {
cell_index: cell.index,
port_name: "Y",
bit_index: 0,
},
lw::PegAddress::output(component.address, 0),
);
*next_address += 1;
next_position[2] += 3 * SQUARE;
return vec![component];
} }

Loading…
Cancel
Save