From f56effc1972ad981d2d0777e6f19129eaa7ead3c Mon Sep 17 00:00:00 2001 From: D4VID Date: Sat, 30 Aug 2025 18:02:36 +0200 Subject: [PATCH] Use layer builder for input and outputs --- verilog2logicworld/src/cells/input_port.rs | 73 ++++++++++ verilog2logicworld/src/cells/mod.rs | 8 +- verilog2logicworld/src/cells/output_port.rs | 73 ++++++++++ verilog2logicworld/src/router.rs | 141 +++----------------- 4 files changed, 171 insertions(+), 124 deletions(-) create mode 100644 verilog2logicworld/src/cells/input_port.rs create mode 100644 verilog2logicworld/src/cells/output_port.rs diff --git a/verilog2logicworld/src/cells/input_port.rs b/verilog2logicworld/src/cells/input_port.rs new file mode 100644 index 0000000..5beb748 --- /dev/null +++ b/verilog2logicworld/src/cells/input_port.rs @@ -0,0 +1,73 @@ +use std::f32::consts::PI; + +use logicworld_subassembly::{lw, COMPONENT_MAP}; +use vecmath::{vec3_add, Vector3}; + +use crate::cells::builder; +use crate::router::{Connection, ConnectionMap, SQUARE}; + +pub fn input_port( + bits: &Vec, + port_name: &str, + parent_address: u32, + next_address: &mut u32, + next_position: &mut Vector3, + connection_map: &mut ConnectionMap, +) -> Vec { + let mut components = vec![]; + let mut wires = vec![]; // discard + builder( + bits.len(), + parent_address, + next_address, + next_position, + &mut components, + &mut wires, + connection_map, + |i_bit, next_address, parent, next_position_within, components, _wires, connection_map| { + let bit_id = bits[i_bit]; + let label = lw::Component { + address: *next_address, + parent, + numeric_id: COMPONENT_MAP["MHG.PanelLabel"], + position: *next_position_within, + rotation: quaternion::euler_angles(0.0, -PI / 2.0, 0.0), + inputs: vec![], + outputs: vec![], + custom_data: lw::Label::new(&format!("{}[{}]", port_name, i_bit)) + .with_size(2.0) + .custom_data(), + }; + + *next_address += 1; + + let peg = lw::Component { + address: *next_address, + parent, + numeric_id: COMPONENT_MAP["MHG.Peg"], + position: vec3_add(*next_position_within, [0, 0, SQUARE]), + rotation: quaternion::id(), + inputs: vec![lw::Input::new(bit_id as lw::Int)], + outputs: vec![], + custom_data: vec![], + }; + connection_map.insert( + Connection { + cell_index: bit_id, + port_name: "input", + bit_index: 0, + }, + lw::PegAddress::input(peg.address, 0), + ); + + components.push(label); + components.push(peg); + + *next_address += 1; + }, + ); + + next_position[0] += SQUARE / 3; // third of a square + + return components; +} diff --git a/verilog2logicworld/src/cells/mod.rs b/verilog2logicworld/src/cells/mod.rs index d7ae14d..c1bd9c9 100644 --- a/verilog2logicworld/src/cells/mod.rs +++ b/verilog2logicworld/src/cells/mod.rs @@ -2,7 +2,11 @@ mod builder; use builder::builder; pub mod unary_op; -pub use unary_op::unary_op; - pub mod binary_op; +pub mod input_port; +pub mod output_port; + +pub use unary_op::unary_op; pub use binary_op::binary_op; +pub use output_port::output_port; +pub use input_port::input_port; diff --git a/verilog2logicworld/src/cells/output_port.rs b/verilog2logicworld/src/cells/output_port.rs new file mode 100644 index 0000000..ef735f6 --- /dev/null +++ b/verilog2logicworld/src/cells/output_port.rs @@ -0,0 +1,73 @@ +use std::f32::consts::PI; + +use logicworld_subassembly::{lw, COMPONENT_MAP}; +use vecmath::{vec3_add, Vector3}; + +use crate::cells::builder; +use crate::router::{Connection, ConnectionMap, SQUARE}; + +pub fn output_port( + bits: &Vec, + port_name: &str, + parent_address: u32, + next_address: &mut u32, + next_position: &mut Vector3, + connection_map: &mut ConnectionMap, +) -> Vec { + let mut components = vec![]; + let mut wires = vec![]; // discard + builder( + bits.len(), + parent_address, + next_address, + next_position, + &mut components, + &mut wires, + connection_map, + |i_bit, next_address, parent, next_position_within, components, _wires, connection_map| { + let bit_id = bits[i_bit]; + let label = lw::Component { + address: *next_address, + parent, + numeric_id: COMPONENT_MAP["MHG.PanelLabel"], + position: vec3_add(*next_position_within, [0, 0, SQUARE]), + rotation: quaternion::euler_angles(0.0, -PI / 2.0, 0.0), + inputs: vec![], + outputs: vec![], + custom_data: lw::Label::new(&format!("{}[{}]", port_name, i_bit)) + .with_size(2.0) + .custom_data(), + }; + + *next_address += 1; + + let peg = lw::Component { + address: *next_address, + parent, + numeric_id: COMPONENT_MAP["MHG.Peg"], + position: *next_position_within, + rotation: quaternion::id(), + inputs: vec![lw::Input::new(bit_id as lw::Int)], + outputs: vec![], + custom_data: vec![], + }; + + connection_map.insert( + Connection { + cell_index: bit_id, + port_name: "output", + bit_index: 0, + }, + lw::PegAddress::input(peg.address, 0), + ); + + components.push(label); + components.push(peg); + + *next_address += 1; + }, + ); + next_position[0] += SQUARE / 3; // third of a square + + return components; +} diff --git a/verilog2logicworld/src/router.rs b/verilog2logicworld/src/router.rs index 5ddd536..0285708 100644 --- a/verilog2logicworld/src/router.rs +++ b/verilog2logicworld/src/router.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, f32::consts::PI, fmt::Debug}; use logicworld_subassembly::{lw, COMPONENT_MAP}; -use vecmath::{vec3_add, Vector3}; +use vecmath::vec3_add; use crate::verilog::{Error, Module}; use crate::cells::*; @@ -107,20 +107,15 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro let mut next_input_position = origin.clone(); for input in &module.inputs { - for bit in &input.bits { - input_ports.extend(input_port( - *bit, - &input.name, - board_address, - &mut next_address, - &mut next_input_position, - &mut connection_map, - )); - } - // align back to middle - next_input_position[0] += SQUARE / 2; - next_input_position[0] -= next_input_position[0] % SQUARE; - next_input_position[0] += SQUARE / 2; + input_ports.extend(input_port( + &input.bits, + &input.name, + board_address, + &mut next_address, + &mut next_input_position, + &mut connection_map, + )); + next_input_position[0] += 3 * SQUARE; } let mut next_position = vec3_add(origin, [1 * SQUARE, 0, 3 * SQUARE]); @@ -171,20 +166,15 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro let mut next_output_position = next_position.clone(); for output in &module.outputs { - for bit in &output.bits { - output_ports.extend(output_port( - *bit, - &output.name, - board_address, - &mut next_address, - &mut next_output_position, - &mut connection_map, - )); - } - // align back to middle - next_output_position[0] += SQUARE / 2; - next_output_position[0] -= next_output_position[0] % SQUARE; - next_output_position[0] += SQUARE / 2; + output_ports.extend(output_port( + &output.bits, + &output.name, + board_address, + &mut next_address, + &mut next_output_position, + &mut connection_map, + )); + next_output_position[0] += 3 * SQUARE; } let board = lw::Component { @@ -245,96 +235,3 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro return Ok((components, wires)); } - -fn input_port( - bit_id: usize, - port_name: &str, - parent_address: u32, - next_address: &mut u32, - next_position: &mut Vector3, - connection_map: &mut ConnectionMap, -) -> Vec { - let label = lw::Component { - address: *next_address, - parent: parent_address, - numeric_id: COMPONENT_MAP["MHG.PanelLabel"], - position: *next_position, - rotation: quaternion::euler_angles(0.0, -PI / 2.0, 0.0), - inputs: vec![], - outputs: vec![], - custom_data: lw::Label::new(port_name).with_size(2.0).custom_data(), - }; - - *next_address += 1; - - let peg = lw::Component { - address: *next_address, - parent: parent_address, - numeric_id: COMPONENT_MAP["MHG.Peg"], - position: vec3_add(*next_position, [0, 0, SQUARE]), - rotation: quaternion::id(), - inputs: vec![lw::Input::new(bit_id as lw::Int)], - outputs: vec![], - custom_data: vec![], - }; - connection_map.insert( - Connection { - cell_index: bit_id, - port_name: "input", - bit_index: 0, - }, - lw::PegAddress::input(peg.address, 0), - ); - - *next_address += 1; - next_position[0] += SQUARE / 3; // third of a square - - return vec![peg, label]; -} - -fn output_port( - bit_id: usize, - port_name: &str, - parent_address: u32, - next_address: &mut u32, - next_position: &mut Vector3, - connection_map: &mut ConnectionMap, -) -> Vec { - let label = lw::Component { - address: *next_address, - parent: parent_address, - numeric_id: COMPONENT_MAP["MHG.PanelLabel"], - position: vec3_add(*next_position, [0, 0, SQUARE]), - rotation: quaternion::euler_angles(0.0, -PI / 2.0, 0.0), - inputs: vec![], - outputs: vec![], - custom_data: lw::Label::new(port_name).with_size(2.0).custom_data(), - }; - - *next_address += 1; - - let peg = lw::Component { - address: *next_address, - parent: parent_address, - numeric_id: COMPONENT_MAP["MHG.Peg"], - position: *next_position, - rotation: quaternion::id(), - inputs: vec![lw::Input::new(bit_id as lw::Int)], - outputs: vec![], - custom_data: vec![], - }; - connection_map.insert( - Connection { - cell_index: bit_id, - port_name: "output", - bit_index: 0, - }, - lw::PegAddress::input(peg.address, 0), - ); - - *next_address += 1; - next_position[0] += SQUARE / 3; // third of a square - - return vec![peg, label]; -} -