|
|
@ -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 logicworld_subassembly::{lw, COMPONENT_MAP};
|
|
|
|
use vecmath::{vec3_add, Vector3};
|
|
|
|
use vecmath::{vec3_add, Vector3};
|
|
|
@ -362,16 +362,73 @@ fn binary_op(
|
|
|
|
let b_width = cell.parameters["B_WIDTH"];
|
|
|
|
let b_width = cell.parameters["B_WIDTH"];
|
|
|
|
|
|
|
|
|
|
|
|
// The width of the output port \Y.
|
|
|
|
// 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_width == b_width, "Different widths not yet supported");
|
|
|
|
assert!(!a_signed && !b_signed, "Signed 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![];
|
|
|
|
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_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 input_b = lw::Input::new(cell.inputs["B"][i_bit] as i32);
|
|
|
|
let output_state_id = cell.outputs["Y"][i_bit] as lw::Int;
|
|
|
|
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 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: next_parent,
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
|
|
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(),
|
|
|
|
rotation: quaternion::id(),
|
|
|
|
inputs: vec![input_a],
|
|
|
|
inputs: vec![input_a],
|
|
|
|
outputs: vec![output_a],
|
|
|
|
outputs: vec![output_a],
|
|
|
@ -394,9 +451,9 @@ fn binary_op(
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let buffer_b = lw::Component {
|
|
|
|
let buffer_b = lw::Component {
|
|
|
|
address: *next_address + 1,
|
|
|
|
address: *next_address + 1,
|
|
|
|
parent: parent_address,
|
|
|
|
parent: next_parent,
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
|
|
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(),
|
|
|
|
rotation: quaternion::id(),
|
|
|
|
inputs: vec![input_b],
|
|
|
|
inputs: vec![input_b],
|
|
|
|
outputs: vec![output_b],
|
|
|
|
outputs: vec![output_b],
|
|
|
@ -404,12 +461,9 @@ fn binary_op(
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let peg = lw::Component {
|
|
|
|
let peg = lw::Component {
|
|
|
|
address: *next_address + 2,
|
|
|
|
address: *next_address + 2,
|
|
|
|
parent: parent_address,
|
|
|
|
parent: next_parent,
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Peg"],
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Peg"],
|
|
|
|
position: vec3_add(
|
|
|
|
position: vec3_add(next_position_within, [0, 0, 2 * SQUARE]),
|
|
|
|
*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![],
|
|
|
@ -462,9 +516,9 @@ fn binary_op(
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
let component = lw::Component {
|
|
|
|
let component = lw::Component {
|
|
|
|
address: *next_address,
|
|
|
|
address: *next_address,
|
|
|
|
parent: parent_address,
|
|
|
|
parent: next_parent,
|
|
|
|
numeric_id: COMPONENT_MAP[text_id],
|
|
|
|
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(),
|
|
|
|
rotation: quaternion::id(),
|
|
|
|
inputs: vec![input_a, input_b],
|
|
|
|
inputs: vec![input_a, input_b],
|
|
|
|
outputs: vec![output],
|
|
|
|
outputs: vec![output],
|
|
|
@ -498,6 +552,9 @@ fn binary_op(
|
|
|
|
);
|
|
|
|
);
|
|
|
|
components.push(component);
|
|
|
|
components.push(component);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
next_parent = next_board.address;
|
|
|
|
|
|
|
|
components.push(mount);
|
|
|
|
|
|
|
|
components.push(next_board);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
next_position[2] += 5 * SQUARE;
|
|
|
|
next_position[2] += 5 * SQUARE;
|
|
|
|