diff --git a/verilog2logicworld/src/router.rs b/verilog2logicworld/src/router.rs index 3dcdd5b..ccca821 100644 --- a/verilog2logicworld/src/router.rs +++ b/verilog2logicworld/src/router.rs @@ -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 vecmath::{vec3_add, Vector3}; @@ -9,12 +9,21 @@ use crate::verilog::{Cell, Error, Module}; const SQUARE: lw::Int = 300; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] struct Connection<'a> { cell_index: usize, port_name: &'a str, 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)] struct Net<'a> { @@ -58,7 +67,7 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro .push(Connection { cell_index: i_cell, port_name: key, - bit_index: 0, + bit_index: i_bit, }); } } @@ -70,7 +79,7 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro .connected_output = Some(Connection { cell_index: i_cell, port_name: key, - bit_index: 0, + bit_index: i_bit, }); } } @@ -124,6 +133,7 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro board_address, &mut next_address, &mut next_position, + &mut wires, &mut connection_map, ), "$xor" => binary_op( @@ -132,10 +142,12 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro board_address, &mut next_address, &mut next_position, + &mut wires, &mut connection_map, ), - "$or" => or_gate( + "$or" => binary_op( cell, + "Custom.OrGate", board_address, &mut next_address, &mut next_position, @@ -148,6 +160,7 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro board_address, &mut next_address, &mut next_position, + &mut wires, &mut connection_map, ), _ => return Err(Error::UnsupportedCell), @@ -196,15 +209,16 @@ pub fn route(module: Module) -> Result<(Vec, Vec), Erro components.extend(output_ports); for (id, net) in &net_list { - // println!(); - // println!("{}: {:?}", id, net); - // println!("map; {:?}", connection_map.keys()); + println!(); + println!("{}: {:#?}", id, net); + println!("map; {:#?}", connection_map.keys()); let output_address = &connection_map[&net.connected_output.unwrap_or(Connection { cell_index: *id, port_name: "input", bit_index: 0, // TODO: figure out })]; for input in &net.connected_inputs { + println!("input: {:?}", input); let input_address = &connection_map[input]; wires.push(lw::Wire { first_point: output_address.clone(), @@ -330,6 +344,7 @@ fn binary_op( parent_address: u32, next_address: &mut u32, next_position: &mut Vector3, + wires: &mut Vec, connection_map: &mut ConnectionMap, ) -> Vec { // All binary RTL cells have two input ports \A and \B and one output port \Y. They also have the following parameters: @@ -356,50 +371,136 @@ fn binary_op( let mut components = vec![]; - for i in 0..a_width { - let input_a = lw::Input::new(cell.inputs["A"][i] as i32); - let input_b = lw::Input::new(cell.inputs["B"][i] as i32); - let output = lw::Output::new(cell.outputs["Y"][i] as i32); - let component = lw::Component { - address: *next_address, - parent: parent_address, - numeric_id: COMPONENT_MAP[text_id], - position: vec3_add(*next_position, [0, (i as lw::Int) * 2 * SQUARE, 0]), - 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: 0, - }, - lw::PegAddress::input(component.address, 0), - ); - connection_map.insert( - Connection { - cell_index: cell.index, - port_name: "B", - bit_index: 0, - }, - lw::PegAddress::input(component.address, 1), - ); - connection_map.insert( - Connection { - cell_index: cell.index, - port_name: "Y", - bit_index: 0, - }, - lw::PegAddress::output(component.address, 0), - ); - components.push(component); + for i_bit in 0..a_width { + 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: parent_address, + numeric_id: COMPONENT_MAP["MHG.Buffer_WithOutput"], + position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]), + 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, [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![], + }; + + 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); + + *next_address += 3; + } else { + let component = lw::Component { + address: *next_address, + parent: parent_address, + numeric_id: COMPONENT_MAP[text_id], + position: vec3_add(*next_position, [0, (i_bit as lw::Int) * 2 * SQUARE, 0]), + 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] += 3 * SQUARE; + next_position[2] += 5 * SQUARE; return components; } @@ -410,6 +511,7 @@ fn unary_op( parent_address: u32, next_address: &mut u32, next_position: &mut Vector3, + wires: &mut Vec, connection_map: &mut ConnectionMap, ) -> Vec { let input = lw::Input::new(cell.inputs["A"][0] as i32); @@ -447,93 +549,3 @@ fn unary_op( return vec![component]; } - -fn or_gate( - cell: &Cell, - parent_address: u32, - next_address: &mut u32, - next_position: &mut Vector3, - wires: &mut Vec, - connection_map: &mut ConnectionMap, -) -> Vec { - 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_state_id = cell.outputs["Y"][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: 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, [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![], - }; - - connection_map.insert( - Connection { - cell_index: cell.index, - port_name: "A", - bit_index: 0, - }, - lw::PegAddress::input(buffer_a.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 { - cell_index: cell.index, - port_name: "Y", - bit_index: 0, - }, - 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, - }); - - *next_address += 3; - next_position[2] += 5 * SQUARE; - - return vec![buffer_a, buffer_b, peg]; -}