|
|
@ -5,13 +5,15 @@ use vecmath::{vec3_add, Vector3};
|
|
|
|
|
|
|
|
|
|
|
|
use crate::verilog::{Cell, Error, Module};
|
|
|
|
use crate::verilog::{Cell, Error, Module};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const SQUARE: lw::Int = 300;
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Default, Debug)]
|
|
|
|
#[derive(Default, Debug)]
|
|
|
|
struct Net {
|
|
|
|
struct Net<'a> {
|
|
|
|
/// Index of cell that is outputting into this net (or None, if it's the module input)
|
|
|
|
/// Index of cell that is outputting into this net (or None, if it's the module input)
|
|
|
|
connected_output: Option<(usize, String)>,
|
|
|
|
connected_output: Option<(usize, &'a str)>,
|
|
|
|
|
|
|
|
|
|
|
|
/// Indicies and names of ports of cells whose inputs are connected to this net
|
|
|
|
/// Indicies and names of ports of cells whose inputs are connected to this net
|
|
|
|
connected_inputs: Vec<(usize, String)>,
|
|
|
|
connected_inputs: Vec<(usize, &'a str)>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Error> {
|
|
|
|
pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Error> {
|
|
|
@ -36,17 +38,13 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i, cell) in module.cells.iter().enumerate() {
|
|
|
|
for (i, cell) in module.cells.iter().enumerate() {
|
|
|
|
// println!(
|
|
|
|
|
|
|
|
// "Cell {} - {}: in={:?} out={:?}",
|
|
|
|
|
|
|
|
// i, cell.cell_type, cell.inputs, cell.outputs
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
for (key, bits) in &cell.inputs {
|
|
|
|
for (key, bits) in &cell.inputs {
|
|
|
|
for bit in bits {
|
|
|
|
for bit in bits {
|
|
|
|
net_list
|
|
|
|
net_list
|
|
|
|
.entry(*bit)
|
|
|
|
.entry(*bit)
|
|
|
|
.or_insert(Net::default())
|
|
|
|
.or_insert(Net::default())
|
|
|
|
.connected_inputs
|
|
|
|
.connected_inputs
|
|
|
|
.push((i, key.to_owned()));
|
|
|
|
.push((i, key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (key, bits) in &cell.outputs {
|
|
|
|
for (key, bits) in &cell.outputs {
|
|
|
@ -54,7 +52,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
|
|
|
|
net_list
|
|
|
|
net_list
|
|
|
|
.entry(*bit)
|
|
|
|
.entry(*bit)
|
|
|
|
.or_insert(Net::default())
|
|
|
|
.or_insert(Net::default())
|
|
|
|
.connected_output = Some((i, key.to_owned()));
|
|
|
|
.connected_output = Some((i, key));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -63,77 +61,229 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
|
|
|
|
println!("Net {}: {:?}", key, value);
|
|
|
|
println!("Net {}: {:?}", key, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let board = lw::Component {
|
|
|
|
let board_address = 1;
|
|
|
|
address: 1,
|
|
|
|
let mut next_address = board_address + 1;
|
|
|
|
parent: 0,
|
|
|
|
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.CircuitBoard"],
|
|
|
|
|
|
|
|
position: [0, 0, 0],
|
|
|
|
|
|
|
|
rotation: quaternion::euler_angles(0.0, -PI / 2.0, 0.0),
|
|
|
|
|
|
|
|
inputs: vec![],
|
|
|
|
|
|
|
|
outputs: vec![],
|
|
|
|
|
|
|
|
custom_data: lw::CircuitBoard::default()
|
|
|
|
|
|
|
|
.with_size(5, 10)
|
|
|
|
|
|
|
|
.with_color(100, 25, 25)
|
|
|
|
|
|
|
|
.custom_data(),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let board_address = board.address;
|
|
|
|
let mut wires: Vec<lw::Wire> = vec![];
|
|
|
|
|
|
|
|
let mut cells: Vec<lw::Component> = vec![];
|
|
|
|
|
|
|
|
let mut input_ports: Vec<lw::Component> = vec![];
|
|
|
|
|
|
|
|
let mut output_ports: Vec<lw::Component> = vec![];
|
|
|
|
|
|
|
|
|
|
|
|
let mut next_address = board_address + 1;
|
|
|
|
let mut connection_map: HashMap<(usize, &str), lw::PegAddress> = HashMap::new();
|
|
|
|
|
|
|
|
|
|
|
|
let mut next_position = [150 + 1 * 300, 150, 150 + 1 * 300];
|
|
|
|
// the size of squares is 300 units
|
|
|
|
|
|
|
|
// 150, 150, 150 is the middle of the first square
|
|
|
|
|
|
|
|
// first coordinate is down, second up, third to the right
|
|
|
|
|
|
|
|
let origin = [SQUARE / 2, SQUARE / 2, SQUARE / 2];
|
|
|
|
|
|
|
|
|
|
|
|
let mut wires: Vec<lw::Wire> = vec![];
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let mut components = vec![board];
|
|
|
|
let mut next_position = vec3_add(origin, [1 * SQUARE, 0, 3 * SQUARE]);
|
|
|
|
components.extend(
|
|
|
|
|
|
|
|
module
|
|
|
|
for (i, cell) in module.cells.iter().enumerate() {
|
|
|
|
.cells
|
|
|
|
println!("{}: {:?}", i, cell);
|
|
|
|
.iter()
|
|
|
|
let components = match cell.cell_type.as_str() {
|
|
|
|
.map(|cell| {
|
|
|
|
"$and" => basic_gate(
|
|
|
|
println!("{:?}", cell);
|
|
|
|
|
|
|
|
let component = match cell.cell_type.as_str() {
|
|
|
|
|
|
|
|
"$and" => Ok(basic_gate(
|
|
|
|
|
|
|
|
cell,
|
|
|
|
cell,
|
|
|
|
"MHG.AndGate",
|
|
|
|
"MHG.AndGate",
|
|
|
|
board_address,
|
|
|
|
board_address,
|
|
|
|
&mut next_address,
|
|
|
|
&mut next_address,
|
|
|
|
&mut next_position,
|
|
|
|
&mut next_position,
|
|
|
|
)),
|
|
|
|
&mut connection_map,
|
|
|
|
"$xor" => Ok(basic_gate(
|
|
|
|
),
|
|
|
|
|
|
|
|
"$xor" => basic_gate(
|
|
|
|
cell,
|
|
|
|
cell,
|
|
|
|
"MHG.XorGate",
|
|
|
|
"MHG.XorGate",
|
|
|
|
board_address,
|
|
|
|
board_address,
|
|
|
|
&mut next_address,
|
|
|
|
&mut next_address,
|
|
|
|
&mut next_position,
|
|
|
|
&mut next_position,
|
|
|
|
)),
|
|
|
|
&mut connection_map,
|
|
|
|
"$or" => Ok(or_gate(
|
|
|
|
),
|
|
|
|
|
|
|
|
"$or" => or_gate(
|
|
|
|
cell,
|
|
|
|
cell,
|
|
|
|
board_address,
|
|
|
|
board_address,
|
|
|
|
&mut next_address,
|
|
|
|
&mut next_address,
|
|
|
|
&mut next_position,
|
|
|
|
&mut next_position,
|
|
|
|
&mut wires,
|
|
|
|
&mut wires,
|
|
|
|
)),
|
|
|
|
&mut connection_map,
|
|
|
|
_ => Err(Error::UnsupportedCell),
|
|
|
|
),
|
|
|
|
|
|
|
|
_ => return Err(Error::UnsupportedCell),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
cells.extend(components);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return component;
|
|
|
|
let mut next_output_position = next_position.clone();
|
|
|
|
})
|
|
|
|
for output in &module.outputs {
|
|
|
|
.collect::<Result<Vec<Vec<lw::Component>>, Error>>()?
|
|
|
|
for bit in &output.bits {
|
|
|
|
.into_iter()
|
|
|
|
output_ports.extend(output_port(
|
|
|
|
.flatten()
|
|
|
|
*bit,
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
&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;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let board = lw::Component {
|
|
|
|
|
|
|
|
address: board_address,
|
|
|
|
|
|
|
|
parent: 0,
|
|
|
|
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.CircuitBoard"],
|
|
|
|
|
|
|
|
position: [0, 0, 0],
|
|
|
|
|
|
|
|
rotation: quaternion::euler_angles(0.0, -PI / 2.0, 0.0),
|
|
|
|
|
|
|
|
inputs: vec![],
|
|
|
|
|
|
|
|
outputs: vec![],
|
|
|
|
|
|
|
|
custom_data: lw::CircuitBoard::default()
|
|
|
|
|
|
|
|
.with_size(
|
|
|
|
|
|
|
|
next_output_position[0] / SQUARE + 2,
|
|
|
|
|
|
|
|
next_output_position[2] / SQUARE + 2,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.with_color(100, 25, 25)
|
|
|
|
|
|
|
|
.custom_data(),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut components = vec![board];
|
|
|
|
|
|
|
|
components.extend(input_ports);
|
|
|
|
|
|
|
|
components.extend(cells);
|
|
|
|
|
|
|
|
components.extend(output_ports);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (id, net) in &net_list {
|
|
|
|
|
|
|
|
println!();
|
|
|
|
|
|
|
|
println!("{}: {:?}", id, net);
|
|
|
|
|
|
|
|
println!("map; {:?}", connection_map.keys());
|
|
|
|
|
|
|
|
let output_address = &connection_map[&net.connected_output.unwrap_or((*id, "input"))];
|
|
|
|
|
|
|
|
for input in &net.connected_inputs {
|
|
|
|
|
|
|
|
let input_address = &connection_map[input];
|
|
|
|
|
|
|
|
wires.push(lw::Wire {
|
|
|
|
|
|
|
|
first_point: output_address.clone(),
|
|
|
|
|
|
|
|
second_point: input_address.clone(),
|
|
|
|
|
|
|
|
circuit_state_id: *id as lw::Int,
|
|
|
|
|
|
|
|
wire_rotation: 0.0,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if net.connected_inputs.is_empty() {
|
|
|
|
|
|
|
|
let input_address = &connection_map[&(*id, "output")];
|
|
|
|
|
|
|
|
wires.push(lw::Wire {
|
|
|
|
|
|
|
|
first_point: output_address.clone(),
|
|
|
|
|
|
|
|
second_point: input_address.clone(),
|
|
|
|
|
|
|
|
circuit_state_id: *id as lw::Int,
|
|
|
|
|
|
|
|
wire_rotation: 0.0,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Ok((components, wires));
|
|
|
|
return Ok((components, wires));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn input_port(
|
|
|
|
|
|
|
|
bit_id: usize,
|
|
|
|
|
|
|
|
port_name: &str,
|
|
|
|
|
|
|
|
parent_address: u32,
|
|
|
|
|
|
|
|
next_address: &mut u32,
|
|
|
|
|
|
|
|
next_position: &mut Vector3<lw::Int>,
|
|
|
|
|
|
|
|
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>,
|
|
|
|
|
|
|
|
) -> Vec<lw::Component> {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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((bit_id, "input"), 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<lw::Int>,
|
|
|
|
|
|
|
|
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>,
|
|
|
|
|
|
|
|
) -> Vec<lw::Component> {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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((bit_id, "output"), lw::PegAddress::input(peg.address, 0));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*next_address += 1;
|
|
|
|
|
|
|
|
next_position[0] += SQUARE / 3; // third of a square
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return vec![peg, label];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn basic_gate(
|
|
|
|
fn basic_gate(
|
|
|
|
cell: &Cell,
|
|
|
|
cell: &Cell,
|
|
|
|
text_id: &str,
|
|
|
|
text_id: &str,
|
|
|
|
parent_address: u32,
|
|
|
|
parent_address: u32,
|
|
|
|
next_address: &mut u32,
|
|
|
|
next_address: &mut u32,
|
|
|
|
next_position: &mut Vector3<i32>,
|
|
|
|
next_position: &mut Vector3<i32>,
|
|
|
|
|
|
|
|
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>,
|
|
|
|
) -> Vec<lw::Component> {
|
|
|
|
) -> Vec<lw::Component> {
|
|
|
|
let input_a = lw::Input::new(cell.inputs["A"][0] as i32);
|
|
|
|
let input_a = lw::Input::new(cell.inputs["A"][0] as i32);
|
|
|
|
let input_b = lw::Input::new(cell.inputs["B"][0] as i32);
|
|
|
|
let input_b = lw::Input::new(cell.inputs["B"][0] as i32);
|
|
|
@ -149,8 +299,21 @@ fn basic_gate(
|
|
|
|
custom_data: vec![],
|
|
|
|
custom_data: vec![],
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection_map.insert(
|
|
|
|
|
|
|
|
(cell.index, "A"),
|
|
|
|
|
|
|
|
lw::PegAddress::input(component.address, 0),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
connection_map.insert(
|
|
|
|
|
|
|
|
(cell.index, "B"),
|
|
|
|
|
|
|
|
lw::PegAddress::input(component.address, 1),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
connection_map.insert(
|
|
|
|
|
|
|
|
(cell.index, "Y"),
|
|
|
|
|
|
|
|
lw::PegAddress::output(component.address, 0),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
*next_address += 1;
|
|
|
|
*next_address += 1;
|
|
|
|
next_position[2] += 3 * 300;
|
|
|
|
next_position[2] += 3 * SQUARE;
|
|
|
|
|
|
|
|
|
|
|
|
return vec![component];
|
|
|
|
return vec![component];
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -159,12 +322,13 @@ fn or_gate(
|
|
|
|
cell: &Cell,
|
|
|
|
cell: &Cell,
|
|
|
|
parent_address: u32,
|
|
|
|
parent_address: u32,
|
|
|
|
next_address: &mut u32,
|
|
|
|
next_address: &mut u32,
|
|
|
|
next_position: &mut Vector3<i32>,
|
|
|
|
next_position: &mut Vector3<lw::Int>,
|
|
|
|
wires: &mut Vec<lw::Wire>,
|
|
|
|
wires: &mut Vec<lw::Wire>,
|
|
|
|
|
|
|
|
connection_map: &mut HashMap<(usize, &str), lw::PegAddress>,
|
|
|
|
) -> Vec<lw::Component> {
|
|
|
|
) -> Vec<lw::Component> {
|
|
|
|
let input_a = lw::Input::new(cell.inputs["A"][0] as i32);
|
|
|
|
let input_a = lw::Input::new(cell.inputs["A"][0] as lw::Int);
|
|
|
|
let input_b = lw::Input::new(cell.inputs["B"][0] as i32);
|
|
|
|
let input_b = lw::Input::new(cell.inputs["B"][0] as lw::Int);
|
|
|
|
let output_state_id = cell.outputs["Y"][0] as i32;
|
|
|
|
let output_state_id = cell.outputs["Y"][0] as lw::Int;
|
|
|
|
let output_a = lw::Output::new(output_state_id);
|
|
|
|
let output_a = lw::Output::new(output_state_id);
|
|
|
|
let output_b = lw::Output::new(output_state_id);
|
|
|
|
let output_b = lw::Output::new(output_state_id);
|
|
|
|
let peg = lw::Input::new(output_state_id);
|
|
|
|
let peg = lw::Input::new(output_state_id);
|
|
|
@ -183,7 +347,7 @@ fn or_gate(
|
|
|
|
address: *next_address + 1,
|
|
|
|
address: *next_address + 1,
|
|
|
|
parent: parent_address,
|
|
|
|
parent: parent_address,
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
|
|
position: vec3_add(*next_position, [300, 0, 0]),
|
|
|
|
position: vec3_add(*next_position, [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],
|
|
|
@ -193,13 +357,23 @@ fn or_gate(
|
|
|
|
address: *next_address + 2,
|
|
|
|
address: *next_address + 2,
|
|
|
|
parent: parent_address,
|
|
|
|
parent: parent_address,
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Peg"],
|
|
|
|
numeric_id: COMPONENT_MAP["MHG.Peg"],
|
|
|
|
position: vec3_add(*next_position, [0, 0, 2 * 300]),
|
|
|
|
position: vec3_add(*next_position, [0, 0, 2 * SQUARE]),
|
|
|
|
rotation: quaternion::id(),
|
|
|
|
rotation: quaternion::id(),
|
|
|
|
inputs: vec![peg],
|
|
|
|
inputs: vec![peg],
|
|
|
|
outputs: vec![],
|
|
|
|
outputs: vec![],
|
|
|
|
custom_data: vec![],
|
|
|
|
custom_data: vec![],
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection_map.insert(
|
|
|
|
|
|
|
|
(cell.index, "A"),
|
|
|
|
|
|
|
|
lw::PegAddress::input(buffer_a.address, 0),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
connection_map.insert(
|
|
|
|
|
|
|
|
(cell.index, "B"),
|
|
|
|
|
|
|
|
lw::PegAddress::input(buffer_b.address, 0),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
connection_map.insert((cell.index, "Y"), lw::PegAddress::input(peg.address, 0));
|
|
|
|
|
|
|
|
|
|
|
|
wires.push(lw::Wire {
|
|
|
|
wires.push(lw::Wire {
|
|
|
|
first_point: lw::PegAddress::output(buffer_a.address, 0),
|
|
|
|
first_point: lw::PegAddress::output(buffer_a.address, 0),
|
|
|
|
second_point: lw::PegAddress::input(peg.address, 0),
|
|
|
|
second_point: lw::PegAddress::input(peg.address, 0),
|
|
|
@ -214,7 +388,7 @@ fn or_gate(
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
*next_address += 3;
|
|
|
|
*next_address += 3;
|
|
|
|
next_position[2] += 5 * 300;
|
|
|
|
next_position[2] += 5 * SQUARE;
|
|
|
|
|
|
|
|
|
|
|
|
return vec![buffer_a, buffer_b, peg];
|
|
|
|
return vec![buffer_a, buffer_b, peg];
|
|
|
|
}
|
|
|
|
}
|
|
|
|