Compare commits
No commits in common. '5faead9fc67f941cf6395839dee3f46f521139a8' and 'eca62daf3094441161da634423acf7a437fe5392' have entirely different histories.
5faead9fc6
...
eca62daf30
@ -1,185 +0,0 @@
|
|||||||
use std::cmp::max;
|
|
||||||
|
|
||||||
use logicworld_subassembly::{lw, COMPONENT_MAP};
|
|
||||||
use vecmath::{vec3_add, Vector3};
|
|
||||||
|
|
||||||
use crate::cells::builder;
|
|
||||||
use crate::router::{Connection, ConnectionMap, SQUARE};
|
|
||||||
use crate::verilog::Cell;
|
|
||||||
|
|
||||||
pub fn binary_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> {
|
|
||||||
// All binary RTL cells have two input ports \A and \B and one output port \Y. They also have the following parameters:
|
|
||||||
|
|
||||||
// Set to a non-zero value if the input \A is signed and therefore should be sign-extended when needed.
|
|
||||||
let a_signed = cell.parameters["A_SIGNED"] > 0;
|
|
||||||
|
|
||||||
// The width of the input port \A.
|
|
||||||
let a_width = cell.parameters["A_WIDTH"];
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// The width of the input port \B.
|
|
||||||
let b_width = cell.parameters["B_WIDTH"];
|
|
||||||
|
|
||||||
// The width of the output port \Y.
|
|
||||||
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 components = vec![];
|
|
||||||
|
|
||||||
let height = max(max(a_width, b_width), y_width);
|
|
||||||
|
|
||||||
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_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;
|
|
||||||
let output = lw::Output::new(output_state_id);
|
|
||||||
if text_id == "Custom.OrGate" {
|
|
||||||
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 output_a = lw::Output::new(output_state_id);
|
|
||||||
let output_b = lw::Output::new(output_state_id);
|
|
||||||
let peg = lw::Input::new(output_state_id);
|
|
||||||
let buffer_a = lw::Component {
|
|
||||||
address: *next_address,
|
|
||||||
parent,
|
|
||||||
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
||||||
position: *next_position_within,
|
|
||||||
rotation: quaternion::id(),
|
|
||||||
inputs: vec![input_a],
|
|
||||||
outputs: vec![output_a],
|
|
||||||
custom_data: vec![],
|
|
||||||
};
|
|
||||||
let buffer_b = lw::Component {
|
|
||||||
address: *next_address + 1,
|
|
||||||
parent,
|
|
||||||
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
||||||
position: vec3_add(*next_position_within, [SQUARE, 0, 0]),
|
|
||||||
rotation: quaternion::id(),
|
|
||||||
inputs: vec![input_b],
|
|
||||||
outputs: vec![output_b],
|
|
||||||
custom_data: vec![],
|
|
||||||
};
|
|
||||||
let peg = lw::Component {
|
|
||||||
address: *next_address + 2,
|
|
||||||
parent,
|
|
||||||
numeric_id: COMPONENT_MAP["MHG.Peg"],
|
|
||||||
position: vec3_add(*next_position_within, [0, 0, 2 * SQUARE]),
|
|
||||||
rotation: quaternion::id(),
|
|
||||||
inputs: vec![peg],
|
|
||||||
outputs: vec![],
|
|
||||||
custom_data: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
*next_address += 3;
|
|
||||||
|
|
||||||
connection_map.insert(
|
|
||||||
Connection {
|
|
||||||
cell_index: cell.index,
|
|
||||||
port_name: "A",
|
|
||||||
bit_index: i_bit,
|
|
||||||
},
|
|
||||||
lw::PegAddress::input(buffer_a.address, 0),
|
|
||||||
);
|
|
||||||
connection_map.insert(
|
|
||||||
Connection {
|
|
||||||
cell_index: cell.index,
|
|
||||||
port_name: "B",
|
|
||||||
bit_index: i_bit,
|
|
||||||
},
|
|
||||||
lw::PegAddress::input(buffer_b.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 {
|
|
||||||
first_point: lw::PegAddress::output(buffer_a.address, 0),
|
|
||||||
second_point: lw::PegAddress::input(peg.address, 0),
|
|
||||||
circuit_state_id: output_state_id,
|
|
||||||
wire_rotation: 0.0,
|
|
||||||
});
|
|
||||||
wires.push(lw::Wire {
|
|
||||||
first_point: lw::PegAddress::output(buffer_b.address, 0),
|
|
||||||
second_point: lw::PegAddress::input(peg.address, 0),
|
|
||||||
circuit_state_id: output_state_id,
|
|
||||||
wire_rotation: 0.0,
|
|
||||||
});
|
|
||||||
|
|
||||||
components.push(buffer_a);
|
|
||||||
components.push(buffer_b);
|
|
||||||
components.push(peg);
|
|
||||||
} else {
|
|
||||||
let component = lw::Component {
|
|
||||||
address: *next_address,
|
|
||||||
parent,
|
|
||||||
numeric_id: COMPONENT_MAP[text_id],
|
|
||||||
position: *next_position_within,
|
|
||||||
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] += 4 * SQUARE;
|
|
||||||
|
|
||||||
return components;
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
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,73 +0,0 @@
|
|||||||
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<usize>,
|
|
||||||
port_name: &str,
|
|
||||||
parent_address: u32,
|
|
||||||
next_address: &mut u32,
|
|
||||||
next_position: &mut Vector3<lw::Int>,
|
|
||||||
connection_map: &mut ConnectionMap,
|
|
||||||
) -> Vec<lw::Component> {
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
mod builder;
|
|
||||||
use builder::builder;
|
|
||||||
|
|
||||||
pub mod 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;
|
|
@ -1,73 +0,0 @@
|
|||||||
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<usize>,
|
|
||||||
port_name: &str,
|
|
||||||
parent_address: u32,
|
|
||||||
next_address: &mut u32,
|
|
||||||
next_position: &mut Vector3<lw::Int>,
|
|
||||||
connection_map: &mut ConnectionMap,
|
|
||||||
) -> Vec<lw::Component> {
|
|
||||||
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;
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
use std::cmp::max;
|
|
||||||
|
|
||||||
use logicworld_subassembly::{lw, COMPONENT_MAP};
|
|
||||||
use vecmath::Vector3;
|
|
||||||
|
|
||||||
use crate::cells::builder;
|
|
||||||
use crate::router::{Connection, ConnectionMap, SQUARE};
|
|
||||||
use crate::verilog::Cell;
|
|
||||||
|
|
||||||
pub 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> {
|
|
||||||
// All unary RTL cells have one input port \A and one output port \Y. They also have the following parameters:
|
|
||||||
|
|
||||||
// Set to a non-zero value if the input \A is signed and therefore should be sign-extended when needed.
|
|
||||||
let a_signed = cell.parameters["A_SIGNED"] > 0;
|
|
||||||
|
|
||||||
// The width of the input port \A.
|
|
||||||
let a_width = cell.parameters["A_WIDTH"];
|
|
||||||
|
|
||||||
// The width of the output port \Y.
|
|
||||||
let y_width = cell.parameters["Y_WIDTH"];
|
|
||||||
|
|
||||||
assert!(!a_signed, "Signed not yet supported");
|
|
||||||
assert!(
|
|
||||||
a_width == y_width,
|
|
||||||
"Different widths of input and output not yet supported"
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut components = vec![];
|
|
||||||
|
|
||||||
let height = max(a_width, y_width);
|
|
||||||
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
next_position[2] += 3 * SQUARE;
|
|
||||||
|
|
||||||
return components;
|
|
||||||
}
|
|
Loading…
Reference in new issue