diff --git a/verilog2logicworld/src/router.rs b/verilog2logicworld/src/router.rs index ccca821..ddcdce4 100644 --- a/verilog2logicworld/src/router.rs +++ b/verilog2logicworld/src/router.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, f32::consts::PI, fmt::Debug}; +use std::{cmp::max, collections::HashMap, f32::consts::PI, fmt::Debug}; use logicworld_subassembly::{lw, COMPONENT_MAP}; use vecmath::{vec3_add, Vector3}; @@ -362,16 +362,73 @@ fn binary_op( let b_width = cell.parameters["B_WIDTH"]; // The width of the output port \Y. - let _y_width = cell.parameters["Y_WIDTH"]; + let y_width = cell.parameters["Y_WIDTH"]; assert!(a_width == b_width, "Different widths not yet supported"); assert!(!a_signed && !b_signed, "Signed not yet supported"); + assert!( + a_width == y_width, + "Different widths of input and output not yet supported" + ); - // let mut next_parent = parent_address; + let mut next_parent = parent_address; let mut components = vec![]; - for i_bit in 0..a_width { + let height = max(max(a_width, b_width), y_width); + + let mount = lw::Component { + address: *next_address, + parent: next_parent, + numeric_id: COMPONENT_MAP["MHG.Mount"], + position: *next_position, + rotation: quaternion::id(), + inputs: vec![], + outputs: vec![], + custom_data: lw::Mount::new(8).custom_data(), + }; + let next_board = lw::Component { + address: *next_address + 1, + parent: mount.address, + numeric_id: COMPONENT_MAP["MHG.CircuitBoard"], + position: [-SQUARE / 2, 3 * SQUARE - SQUARE / 3, -SQUARE / 2], + rotation: quaternion::id(), + inputs: vec![], + outputs: vec![], + custom_data: lw::CircuitBoard::default().with_size(3, 2).custom_data(), + }; + + *next_address += 2; + + next_parent = next_board.address; + components.push(mount); + components.push(next_board); + + for i_bit in 0..height { + let mut next_position_within = [SQUARE / 2, SQUARE / 2, SQUARE / 2]; + let mount = lw::Component { + address: *next_address, + parent: next_parent, + numeric_id: COMPONENT_MAP["MHG.Mount"], + position: next_position_within, + rotation: quaternion::id(), + inputs: vec![], + outputs: vec![], + custom_data: lw::Mount::new(8).custom_data(), + }; + let next_board = lw::Component { + address: *next_address + 1, + parent: mount.address, + numeric_id: COMPONENT_MAP["MHG.CircuitBoard"], + position: [-SQUARE / 2, 3 * SQUARE - SQUARE / 3, -SQUARE / 2], + rotation: quaternion::id(), + inputs: vec![], + outputs: vec![], + custom_data: lw::CircuitBoard::default().with_size(3, 2).custom_data(), + }; + *next_address += 2; + next_position_within[0] += SQUARE; + let input_a = lw::Input::new(cell.inputs["A"][i_bit] as i32); let input_b = lw::Input::new(cell.inputs["B"][i_bit] as i32); let output_state_id = cell.outputs["Y"][i_bit] as lw::Int; @@ -384,9 +441,9 @@ fn binary_op( let peg = lw::Input::new(output_state_id); let buffer_a = lw::Component { address: *next_address, - parent: parent_address, + parent: next_parent, numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"], - position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]), + position: next_position_within, rotation: quaternion::id(), inputs: vec![input_a], outputs: vec![output_a], @@ -394,9 +451,9 @@ fn binary_op( }; let buffer_b = lw::Component { address: *next_address + 1, - parent: parent_address, + parent: next_parent, numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"], - position: vec3_add(*next_position, [SQUARE, (i_bit as lw::Int) * 2 * SQUARE, 0]), + position: vec3_add(next_position_within, [SQUARE, 0, 0]), rotation: quaternion::id(), inputs: vec![input_b], outputs: vec![output_b], @@ -404,12 +461,9 @@ fn binary_op( }; let peg = lw::Component { address: *next_address + 2, - parent: parent_address, + parent: next_parent, numeric_id: COMPONENT_MAP["MHG.Peg"], - position: vec3_add( - *next_position, - [0, (i_bit as lw::Int) * 2 * SQUARE, 2 * SQUARE], - ), + position: vec3_add(next_position_within, [0, 0, 2 * SQUARE]), rotation: quaternion::id(), inputs: vec![peg], outputs: vec![], @@ -462,9 +516,9 @@ fn binary_op( } else { let component = lw::Component { address: *next_address, - parent: parent_address, + parent: next_parent, numeric_id: COMPONENT_MAP[text_id], - position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]), + position: next_position_within, rotation: quaternion::id(), inputs: vec![input_a, input_b], outputs: vec![output], @@ -498,6 +552,9 @@ fn binary_op( ); components.push(component); } + next_parent = next_board.address; + components.push(mount); + components.push(next_board); } next_position[2] += 5 * SQUARE;