Use layer builder for unary op

master
D4VID 3 weeks ago
parent 3d983f0b5d
commit 858f752842

@ -3,5 +3,5 @@ module gates(
output wire [3:0] 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);
endmodule endmodule

@ -3,6 +3,7 @@ use std::cmp::max;
use logicworld_subassembly::{lw, COMPONENT_MAP}; use logicworld_subassembly::{lw, COMPONENT_MAP};
use vecmath::{vec3_add, Vector3}; use vecmath::{vec3_add, Vector3};
use crate::cells::builder;
use crate::router::{Connection, ConnectionMap, SQUARE}; use crate::router::{Connection, ConnectionMap, SQUARE};
use crate::verilog::Cell; use crate::verilog::Cell;
@ -182,89 +183,3 @@ pub fn binary_op(
return components; return components;
} }
pub fn builder(
height: usize,
parent_address: u32,
next_address: &mut u32,
position: &Vector3<i32>,
components: &mut Vec<lw::Component>,
wires: &mut Vec<lw::Wire>,
connection_map: &mut ConnectionMap,
layer_builder: impl Fn(
usize,
&mut u32,
u32,
&mut Vector3<i32>,
&mut Vec<lw::Component>,
&mut Vec<lw::Wire>,
&mut ConnectionMap,
),
) {
let mount = lw::Component {
address: *next_address,
parent: parent_address,
numeric_id: COMPONENT_MAP["MHG.Mount"],
position: *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;
let mut 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;
layer_builder(
i_bit,
next_address,
next_parent,
&mut next_position_within,
components,
wires,
connection_map,
);
next_parent = next_board.address;
components.push(mount);
components.push(next_board);
}
}

@ -0,0 +1,90 @@
use logicworld_subassembly::{lw, COMPONENT_MAP};
use vecmath::Vector3;
use crate::router::{ConnectionMap, SQUARE};
pub fn builder(
height: usize,
parent_address: u32,
next_address: &mut u32,
position: &Vector3<i32>,
components: &mut Vec<lw::Component>,
wires: &mut Vec<lw::Wire>,
connection_map: &mut ConnectionMap,
layer_builder: impl Fn(
usize,
&mut u32,
u32,
&mut Vector3<i32>,
&mut Vec<lw::Component>,
&mut Vec<lw::Wire>,
&mut ConnectionMap,
),
) {
let mount = lw::Component {
address: *next_address,
parent: parent_address,
numeric_id: COMPONENT_MAP["MHG.Mount"],
position: *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;
let mut 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;
layer_builder(
i_bit,
next_address,
next_parent,
&mut next_position_within,
components,
wires,
connection_map,
);
next_parent = next_board.address;
components.push(mount);
components.push(next_board);
}
}

@ -1,3 +1,6 @@
mod builder;
use builder::builder;
pub mod unary_op; pub mod unary_op;
pub use unary_op::unary_op; pub use unary_op::unary_op;

@ -1,8 +1,11 @@
use std::cmp::max;
use logicworld_subassembly::{lw, COMPONENT_MAP}; use logicworld_subassembly::{lw, COMPONENT_MAP};
use vecmath::Vector3; use vecmath::Vector3;
use crate::verilog::Cell; use crate::cells::builder;
use crate::router::{Connection, ConnectionMap, SQUARE}; use crate::router::{Connection, ConnectionMap, SQUARE};
use crate::verilog::Cell;
pub fn unary_op( pub fn unary_op(
cell: &Cell, cell: &Cell,
@ -10,41 +13,74 @@ pub fn unary_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>,
_wires: &mut Vec<lw::Wire>, wires: &mut Vec<lw::Wire>,
connection_map: &mut ConnectionMap, connection_map: &mut ConnectionMap,
) -> Vec<lw::Component> { ) -> Vec<lw::Component> {
let input = lw::Input::new(cell.inputs["A"][0] as i32); // All unary RTL cells have one input port \A and one output port \Y. They also have the following parameters:
let output = lw::Output::new(cell.outputs["Y"][0] as i32);
let component = lw::Component { // Set to a non-zero value if the input \A is signed and therefore should be sign-extended when needed.
address: *next_address, let a_signed = cell.parameters["A_SIGNED"] > 0;
parent: parent_address,
numeric_id: COMPONENT_MAP[text_id], // The width of the input port \A.
position: *next_position, let a_width = cell.parameters["A_WIDTH"];
rotation: quaternion::id(),
inputs: vec![input], // The width of the output port \Y.
outputs: vec![output], let y_width = cell.parameters["Y_WIDTH"];
custom_data: vec![],
}; assert!(!a_signed, "Signed not yet supported");
assert!(
connection_map.insert( a_width == y_width,
Connection { "Different widths of input and output not yet supported"
cell_index: cell.index,
port_name: "A",
bit_index: 0,
},
lw::PegAddress::input(component.address, 0),
); );
connection_map.insert(
Connection { let mut components = vec![];
cell_index: cell.index,
port_name: "Y", let height = max(a_width, y_width);
bit_index: 0,
builder(
height,
parent_address,
next_address,
next_position,
&mut components,
wires,
connection_map,
|i_bit, next_address, parent, next_position_within, components, _wires, connection_map| {
let input = lw::Input::new(cell.inputs["A"][i_bit] as i32);
let output = lw::Output::new(cell.outputs["Y"][i_bit] as i32);
let component = lw::Component {
address: *next_address,
parent,
numeric_id: COMPONENT_MAP[text_id],
position: *next_position_within,
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: i_bit,
},
lw::PegAddress::input(component.address, 0),
);
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_address += 1;
}, },
lw::PegAddress::output(component.address, 0),
); );
*next_address += 1;
next_position[2] += 3 * SQUARE; next_position[2] += 3 * SQUARE;
return vec![component]; return components;
} }

Loading…
Cancel
Save