summaryrefslogtreecommitdiff
path: root/src/gate.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/gate.rs')
-rw-r--r--src/gate.rs96
1 files changed, 69 insertions, 27 deletions
diff --git a/src/gate.rs b/src/gate.rs
index 87ae219..d88f729 100644
--- a/src/gate.rs
+++ b/src/gate.rs
@@ -1,6 +1,7 @@
use crate::pin::*;
use crate::types::*;
use std::collections::HashMap;
+use std::collections::HashSet;
#[derive(Debug)]
pub enum GateType {
@@ -140,8 +141,8 @@ pub struct AndGate {
impl AndGate {
fn new(input: Vec<PinValue>, id: usize, kind: PinType) -> Self {
if input.is_empty() {
- let pin_1 = Pin::new(PinType::Undetermined, id, 42);
- let pin_2 = Pin::new(PinType::Undetermined, id, 42);
+ let pin_1 = Pin::new(PinType::GateInput, id, 42);
+ let pin_2 = Pin::new(PinType::GateInput, id, 42);
Self {
id,
input: vec![pin_1, pin_2],
@@ -169,6 +170,7 @@ impl AndGate {
let res = (self.input[0].val.unwrap() & self.input[1].val.unwrap()) == 1;
self.output.val = Some(res as u8);
self.output.kind = PinType::GateOutput;
+ println!("{:?}", self);
res
}
}
@@ -260,7 +262,7 @@ impl BufferGate {
#[derive(Debug, Clone, PartialEq)]
pub struct Chip {
- gates: Gates,
+ pub gates: Gates,
pub connections: Connections,
input: Pins,
output: Pins,
@@ -291,16 +293,11 @@ impl Chip {
}
pub fn connect_gate(&mut self, from: &mut Gate, to: &mut Gate, to_pin_idx: usize) {
+ to.input_mut()[to_pin_idx] = Pin::new(PinType::GateInput, to.id(), 42);
self.connections
.entry(to.input()[to_pin_idx])
.and_modify(|val| val.push(*from.output()))
.or_insert_with(|| vec![*from.output()]);
- // self.connections
- // .entry(to.input()[to_pin_idx].id)
- // .or_insert(vec![from.output().id]);
- from.evaluate();
- to.input_mut()[to_pin_idx] =
- Pin::new(PinType::GateInput, to.id(), from.output().val.unwrap());
if !self.gates.contains(&from) {
// TODO: Remove this clone
self.add_gate(from.clone());
@@ -311,30 +308,75 @@ impl Chip {
}
}
- pub fn pins(&self) -> Vec<&Pin> {
- let mut pins = vec![];
+ pub fn pins(&self) -> HashMap<usize, Vec<&Pin>> {
+ let mut pins = HashMap::new();
for gate in &self.gates {
for pin in gate.input() {
- pins.push(pin);
+ pins.entry(pin.id)
+ .and_modify(|val: &mut Vec<&Pin>| val.push(pin))
+ .or_insert_with(|| vec![pin]);
}
- pins.push(gate.output());
+ pins.entry(gate.output().id)
+ .and_modify(|val: &mut Vec<&Pin>| val.push(gate.output()))
+ .or_insert_with(|| vec![gate.output()]);
}
pins
}
- // fn gate_dag(&self) -> HashMap<&Pin, Vec<&Pin>> {
- // let mut dag = HashMap::new();
- // for connection in &self.connections {
- // for pin in *connection.1 {
- // dag.entry(*connection.0)
- // .and_modify(|val: &mut Vec<&Pin>| val.push(pin))
- // .or_insert_with(|| vec![pin]);
- // }
- // }
- // dag
- // }
-
- fn simulate(&self) -> bool {
- todo!()
+ pub fn gate_dag(&self) -> HashMap<usize, Vec<usize>> {
+ let mut dag = HashMap::new();
+ for connection in &self.connections {
+ for pin in connection.1 {
+ dag.entry(connection.0.gate_id)
+ .and_modify(|val: &mut Vec<usize>| val.push(pin.gate_id))
+ .or_insert_with(|| vec![pin.gate_id]);
+ }
+ }
+ dag
+ }
+
+ pub fn pin_dag(&self) -> HashMap<usize, Vec<usize>> {
+ let mut gate_dag = self.gate_dag();
+ let mut dag = HashMap::new();
+ for (id, children) in gate_dag {
+ // dag.entry()
+ // .and_modify(|val: &mut Vec<usize>| val.push(pin.gate_id))
+ // .or_insert_with(|| vec![pin.gate_id]);
+ }
+ dag
+ }
+
+ fn simulate_helper(
+ &mut self,
+ gate: usize,
+ visited: &mut HashSet<usize>,
+ dag: &HashMap<usize, Vec<usize>>,
+ ) {
+ visited.insert(gate);
+ if dag.contains_key(&gate) {
+ for child in dag.get(&gate).unwrap() {
+ if !visited.contains(child) {
+ self.simulate_helper(*child, visited, dag);
+ }
+ }
+ let pos = self.gates.iter().position(|g| g.id() == gate).unwrap();
+ self.gates[pos].evaluate();
+ println!("{}", gate);
+ } else {
+ println!("{}", gate);
+ let pos = self.gates.iter().position(|g| g.id() == gate).unwrap();
+ self.gates[pos].evaluate();
+ }
+ }
+
+ pub fn simulate(&mut self) -> bool {
+ let dag = self.gate_dag();
+ let mut visited = HashSet::new();
+ for child in dag.get(&8).unwrap() {
+ if !visited.contains(child) {
+ self.simulate_helper(*child, &mut visited, &dag);
+ }
+ }
+ false
}
}