Multi bit without boards

master
D4VID 4 weeks ago
parent 18ef7c2914
commit aca55a7c2c

@ -1,4 +1,4 @@
use std::{collections::HashMap, f32::consts::PI}; use std::{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};
@ -9,12 +9,21 @@ use crate::verilog::{Cell, Error, Module};
const SQUARE: lw::Int = 300; const SQUARE: lw::Int = 300;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Clone, Copy, PartialEq, Eq, Hash)]
struct Connection<'a> { struct Connection<'a> {
cell_index: usize, cell_index: usize,
port_name: &'a str, port_name: &'a str,
bit_index: usize, bit_index: usize,
} }
impl<'a> Debug for Connection<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}-{}-{}",
self.cell_index, self.port_name, self.bit_index
)
}
}
#[derive(Default, Debug)] #[derive(Default, Debug)]
struct Net<'a> { struct Net<'a> {
@ -58,7 +67,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
.push(Connection { .push(Connection {
cell_index: i_cell, cell_index: i_cell,
port_name: key, port_name: key,
bit_index: 0, bit_index: i_bit,
}); });
} }
} }
@ -70,7 +79,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
.connected_output = Some(Connection { .connected_output = Some(Connection {
cell_index: i_cell, cell_index: i_cell,
port_name: key, port_name: key,
bit_index: 0, bit_index: i_bit,
}); });
} }
} }
@ -124,6 +133,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
&mut wires,
&mut connection_map, &mut connection_map,
), ),
"$xor" => binary_op( "$xor" => binary_op(
@ -132,10 +142,12 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
&mut wires,
&mut connection_map, &mut connection_map,
), ),
"$or" => or_gate( "$or" => binary_op(
cell, cell,
"Custom.OrGate",
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
@ -148,6 +160,7 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
board_address, board_address,
&mut next_address, &mut next_address,
&mut next_position, &mut next_position,
&mut wires,
&mut connection_map, &mut connection_map,
), ),
_ => return Err(Error::UnsupportedCell), _ => return Err(Error::UnsupportedCell),
@ -196,15 +209,16 @@ pub fn route(module: Module) -> Result<(Vec<lw::Component>, Vec<lw::Wire>), Erro
components.extend(output_ports); components.extend(output_ports);
for (id, net) in &net_list { for (id, net) in &net_list {
// println!(); println!();
// println!("{}: {:?}", id, net); println!("{}: {:#?}", id, net);
// println!("map; {:?}", connection_map.keys()); println!("map; {:#?}", connection_map.keys());
let output_address = &connection_map[&net.connected_output.unwrap_or(Connection { let output_address = &connection_map[&net.connected_output.unwrap_or(Connection {
cell_index: *id, cell_index: *id,
port_name: "input", port_name: "input",
bit_index: 0, // TODO: figure out bit_index: 0, // TODO: figure out
})]; })];
for input in &net.connected_inputs { for input in &net.connected_inputs {
println!("input: {:?}", input);
let input_address = &connection_map[input]; let input_address = &connection_map[input];
wires.push(lw::Wire { wires.push(lw::Wire {
first_point: output_address.clone(), first_point: output_address.clone(),
@ -330,6 +344,7 @@ fn binary_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>,
connection_map: &mut ConnectionMap, connection_map: &mut ConnectionMap,
) -> Vec<lw::Component> { ) -> 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: // All binary RTL cells have two input ports \A and \B and one output port \Y. They also have the following parameters:
@ -356,141 +371,159 @@ fn binary_op(
let mut components = vec![]; let mut components = vec![];
for i in 0..a_width { for i_bit in 0..a_width {
let input_a = lw::Input::new(cell.inputs["A"][i] 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] as i32); let input_b = lw::Input::new(cell.inputs["B"][i_bit] as i32);
let output = lw::Output::new(cell.outputs["Y"][i] as i32); let output_state_id = cell.outputs["Y"][i_bit] as lw::Int;
let component = lw::Component { 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, address: *next_address,
parent: parent_address, parent: parent_address,
numeric_id: COMPONENT_MAP[text_id], numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"],
position: vec3_add(*next_position, [0, (i as lw::Int) * 2 * SQUARE, 0]), position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]),
rotation: quaternion::id(), rotation: quaternion::id(),
inputs: vec![input_a, input_b], inputs: vec![input_a],
outputs: vec![output], 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, [SQUARE, (i_bit as lw::Int) * 2 * SQUARE, 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, (i_bit as lw::Int) * 2 * SQUARE, 2 * SQUARE],
),
rotation: quaternion::id(),
inputs: vec![peg],
outputs: vec![],
custom_data: vec![], custom_data: vec![],
}; };
*next_address += 1;
connection_map.insert( connection_map.insert(
Connection { Connection {
cell_index: cell.index, cell_index: cell.index,
port_name: "A", port_name: "A",
bit_index: 0, bit_index: i_bit,
}, },
lw::PegAddress::input(component.address, 0), lw::PegAddress::input(buffer_a.address, 0),
); );
connection_map.insert( connection_map.insert(
Connection { Connection {
cell_index: cell.index, cell_index: cell.index,
port_name: "B", port_name: "B",
bit_index: 0, bit_index: i_bit,
}, },
lw::PegAddress::input(component.address, 1), lw::PegAddress::input(buffer_b.address, 0),
); );
connection_map.insert( connection_map.insert(
Connection { Connection {
cell_index: cell.index, cell_index: cell.index,
port_name: "Y", port_name: "Y",
bit_index: 0, bit_index: i_bit,
}, },
lw::PegAddress::output(component.address, 0), lw::PegAddress::input(peg.address, 0),
); );
components.push(component);
}
next_position[2] += 3 * SQUARE; 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,
});
return components; components.push(buffer_a);
} components.push(buffer_b);
components.push(peg);
fn unary_op( *next_address += 3;
cell: &Cell, } else {
text_id: &str,
parent_address: u32,
next_address: &mut u32,
next_position: &mut Vector3<i32>,
connection_map: &mut ConnectionMap,
) -> Vec<lw::Component> {
let input = lw::Input::new(cell.inputs["A"][0] as i32);
let output = lw::Output::new(cell.outputs["Y"][0] as i32);
let component = lw::Component { let component = lw::Component {
address: *next_address, address: *next_address,
parent: parent_address, parent: parent_address,
numeric_id: COMPONENT_MAP[text_id], numeric_id: COMPONENT_MAP[text_id],
position: *next_position, position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]),
rotation: quaternion::id(), rotation: quaternion::id(),
inputs: vec![input], inputs: vec![input_a, input_b],
outputs: vec![output], outputs: vec![output],
custom_data: vec![], custom_data: vec![],
}; };
*next_address += 1;
connection_map.insert( connection_map.insert(
Connection { Connection {
cell_index: cell.index, cell_index: cell.index,
port_name: "A", port_name: "A",
bit_index: 0, bit_index: i_bit,
}, },
lw::PegAddress::input(component.address, 0), 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_map.insert(
Connection { Connection {
cell_index: cell.index, cell_index: cell.index,
port_name: "Y", port_name: "Y",
bit_index: 0, bit_index: i_bit,
}, },
lw::PegAddress::output(component.address, 0), lw::PegAddress::output(component.address, 0),
); );
components.push(component);
}
}
*next_address += 1; next_position[2] += 5 * SQUARE;
next_position[2] += 3 * SQUARE;
return vec![component]; return components;
} }
fn or_gate( fn unary_op(
cell: &Cell, cell: &Cell,
text_id: &str,
parent_address: u32, parent_address: u32,
next_address: &mut u32, next_address: &mut u32,
next_position: &mut Vector3<lw::Int>, 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_a = lw::Input::new(cell.inputs["A"][0] as lw::Int); let input = lw::Input::new(cell.inputs["A"][0] as i32);
let input_b = lw::Input::new(cell.inputs["B"][0] as lw::Int); let output = lw::Output::new(cell.outputs["Y"][0] as i32);
let output_state_id = cell.outputs["Y"][0] as lw::Int; let component = lw::Component {
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, address: *next_address,
parent: parent_address, parent: parent_address,
numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"], numeric_id: COMPONENT_MAP[text_id],
position: *next_position, position: *next_position,
rotation: quaternion::id(), rotation: quaternion::id(),
inputs: vec![input_a], inputs: vec![input],
outputs: vec![output_a], outputs: vec![output],
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, [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: parent_address,
numeric_id: COMPONENT_MAP["MHG.Peg"],
position: vec3_add(*next_position, [0, 0, 2 * SQUARE]),
rotation: quaternion::id(),
inputs: vec![peg],
outputs: vec![],
custom_data: vec![], custom_data: vec![],
}; };
@ -500,15 +533,7 @@ fn or_gate(
port_name: "A", port_name: "A",
bit_index: 0, bit_index: 0,
}, },
lw::PegAddress::input(buffer_a.address, 0), lw::PegAddress::input(component.address, 0),
);
connection_map.insert(
Connection {
cell_index: cell.index,
port_name: "B",
bit_index: 0,
},
lw::PegAddress::input(buffer_b.address, 0),
); );
connection_map.insert( connection_map.insert(
Connection { Connection {
@ -516,24 +541,11 @@ fn or_gate(
port_name: "Y", port_name: "Y",
bit_index: 0, bit_index: 0,
}, },
lw::PegAddress::input(peg.address, 0), lw::PegAddress::output(component.address, 0),
); );
wires.push(lw::Wire { *next_address += 1;
first_point: lw::PegAddress::output(buffer_a.address, 0), next_position[2] += 3 * SQUARE;
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 * SQUARE;
return vec![buffer_a, buffer_b, peg]; return vec![component];
} }

Loading…
Cancel
Save