Compare commits
No commits in common. '6f173533db8f53b821e3634c5d28fa99c3ae8041' and '4649b1aad0ed2e423b2553524588675f2d40fe02' have entirely different histories.
6f173533db
...
4649b1aad0
@ -1 +1 @@
|
|||||||
Subproject commit 5c4ba463240312b81d43ed3e284aabf560d38520
|
Subproject commit 9801e5d6c87db31a616de50195110266ed00c15c
|
@ -1,220 +0,0 @@
|
|||||||
use std::{collections::HashMap, f32::consts::PI};
|
|
||||||
|
|
||||||
use logicworld_subassembly::{lw, COMPONENT_MAP};
|
|
||||||
use vecmath::{vec3_add, Vector3};
|
|
||||||
|
|
||||||
use crate::verilog::{Cell, Error, Module};
|
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
|
||||||
struct Net {
|
|
||||||
/// Index of cell that is outputting into this net (or None, if it's the module input)
|
|
||||||
connected_output: Option<(usize, String)>,
|
|
||||||
|
|
||||||
/// Indicies and names of ports of cells whose inputs are connected to this net
|
|
||||||
connected_inputs: Vec<(usize, String)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Error> {
|
|
||||||
let mut net_list: HashMap<usize, Net> = HashMap::new();
|
|
||||||
|
|
||||||
for input in &module.inputs {
|
|
||||||
println!("Input {}: {:?} ", input.name, input.bits);
|
|
||||||
for bit in &input.bits {
|
|
||||||
net_list.insert(*bit, Net::default());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for output in &module.outputs {
|
|
||||||
println!("Output {}: {:?} ", output.name, output.bits);
|
|
||||||
for bit in &output.bits {
|
|
||||||
net_list.insert(
|
|
||||||
*bit,
|
|
||||||
Net {
|
|
||||||
connected_output: None,
|
|
||||||
connected_inputs: Vec::with_capacity(0),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 bit in bits {
|
|
||||||
net_list
|
|
||||||
.entry(*bit)
|
|
||||||
.or_insert(Net::default())
|
|
||||||
.connected_inputs
|
|
||||||
.push((i, key.to_owned()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (key, bits) in &cell.outputs {
|
|
||||||
for bit in bits {
|
|
||||||
net_list
|
|
||||||
.entry(*bit)
|
|
||||||
.or_insert(Net::default())
|
|
||||||
.connected_output = Some((i, key.to_owned()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (key, value) in &net_list {
|
|
||||||
println!("Net {}: {:?}", key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
let board = lw::Component {
|
|
||||||
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 next_address = board_address + 1;
|
|
||||||
|
|
||||||
let mut next_position = [150 + 1 * 300, 150, 150 + 1 * 300];
|
|
||||||
|
|
||||||
let mut wires: Vec<lw::Wire> = vec![];
|
|
||||||
|
|
||||||
let mut components = vec![board];
|
|
||||||
components.extend(
|
|
||||||
module
|
|
||||||
.cells
|
|
||||||
.iter()
|
|
||||||
.map(|cell| {
|
|
||||||
println!("{:?}", cell);
|
|
||||||
let component = match cell.cell_type.as_str() {
|
|
||||||
"$and" => Ok(basic_gate(
|
|
||||||
cell,
|
|
||||||
"MHG.AndGate",
|
|
||||||
board_address,
|
|
||||||
&mut next_address,
|
|
||||||
&mut next_position,
|
|
||||||
)),
|
|
||||||
"$xor" => Ok(basic_gate(
|
|
||||||
cell,
|
|
||||||
"MHG.XorGate",
|
|
||||||
board_address,
|
|
||||||
&mut next_address,
|
|
||||||
&mut next_position,
|
|
||||||
)),
|
|
||||||
"$or" => Ok(or_gate(
|
|
||||||
cell,
|
|
||||||
board_address,
|
|
||||||
&mut next_address,
|
|
||||||
&mut next_position,
|
|
||||||
&mut wires,
|
|
||||||
)),
|
|
||||||
_ => Err(Error::UnsupportedCell),
|
|
||||||
};
|
|
||||||
|
|
||||||
return component;
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<Vec<lw::Component>>, Error>>()?
|
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
);
|
|
||||||
|
|
||||||
return Ok((components, wires));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn basic_gate(
|
|
||||||
cell: &Cell,
|
|
||||||
text_id: &str,
|
|
||||||
parent_address: u32,
|
|
||||||
next_address: &mut u32,
|
|
||||||
next_position: &mut Vector3<i32>,
|
|
||||||
) -> Vec<lw::Component> {
|
|
||||||
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 output = lw::Output::new(cell.outputs["Y"][0] as i32);
|
|
||||||
let component = lw::Component {
|
|
||||||
address: *next_address,
|
|
||||||
parent: parent_address,
|
|
||||||
numeric_id: COMPONENT_MAP[text_id],
|
|
||||||
position: *next_position,
|
|
||||||
rotation: quaternion::id(),
|
|
||||||
inputs: vec![input_a, input_b],
|
|
||||||
outputs: vec![output],
|
|
||||||
custom_data: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
*next_address += 1;
|
|
||||||
next_position[2] += 3 * 300;
|
|
||||||
|
|
||||||
return vec![component];
|
|
||||||
}
|
|
||||||
|
|
||||||
fn or_gate(
|
|
||||||
cell: &Cell,
|
|
||||||
parent_address: u32,
|
|
||||||
next_address: &mut u32,
|
|
||||||
next_position: &mut Vector3<i32>,
|
|
||||||
wires: &mut Vec<lw::Wire>,
|
|
||||||
) -> Vec<lw::Component> {
|
|
||||||
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 output_state_id = cell.outputs["Y"][0] as i32;
|
|
||||||
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: parent_address,
|
|
||||||
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
||||||
position: *next_position,
|
|
||||||
rotation: quaternion::id(),
|
|
||||||
inputs: vec![input_a],
|
|
||||||
outputs: vec![output_a],
|
|
||||||
custom_data: vec![],
|
|
||||||
};
|
|
||||||
let buffer_b = lw::Component {
|
|
||||||
address: *next_address + 1,
|
|
||||||
parent: parent_address,
|
|
||||||
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
|
|
||||||
position: vec3_add(*next_position, [300, 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: parent_address,
|
|
||||||
numeric_id: COMPONENT_MAP["MHG.Peg"],
|
|
||||||
position: vec3_add(*next_position, [0, 0, 2 * 300]),
|
|
||||||
rotation: quaternion::id(),
|
|
||||||
inputs: vec![peg],
|
|
||||||
outputs: vec![],
|
|
||||||
custom_data: vec![],
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
*next_address += 3;
|
|
||||||
next_position[2] += 5 * 300;
|
|
||||||
|
|
||||||
return vec![buffer_a, buffer_b, peg];
|
|
||||||
}
|
|
Loading…
Reference in new issue