Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hellow554 committed Nov 15, 2018
0 parents commit a7bff0d
Show file tree
Hide file tree
Showing 28 changed files with 2,374 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/target
**/*.rs.bk
Cargo.lock
.idea/
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "logical"
version = "0.1.0"
authors = ["Marcel Hellwig <[email protected]>"]
edition = "2018"

[dependencies]
anymap = "*"
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

all: clippy test

format:
@cargo fmt

clippy:
@cargo clippy

test:
@cargo test

build:
@cargo build

run:
@cargo run

doc:
@cargo doc --open
131 changes: 131 additions & 0 deletions examples/fulladder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
//! Lets try to build a full adder!
use std::error::Error;
use std::thread::sleep;
use std::time::Duration;

use logical::gates::{AndGate, OrGate, XorGate};
use logical::models::inputs::Switch;
use logical::models::outputs::Led;
use logical::{Ieee1164, Ieee1164Value, Reactor, Signal};

fn main() -> Result<(), Box<Error>> {
//first halfadder
let and1 = AndGate::default();
let xor1 = XorGate::default();

//second halfadder
let and2 = AndGate::default();
let xor2 = XorGate::default();

//cout or
let or = OrGate::default();

//inputs
let mut x = Switch::default();
let mut y = Switch::default();
let mut c = Switch::default();

//outputs
let cout = Led::default();
let s = Led::default();

//connections
//from x to and and xor of ha1
let mut s_x = Signal::<Ieee1164>::new();
s_x.connect_as_input(&x.output);
s_x.connect_as_output(&and1.a);
s_x.connect_as_output(&xor1.a);

//from y to and and xor of ha1
let mut s_y = Signal::new();
s_y.connect_as_input(&y.output);
s_y.connect_as_output(&and1.b);
s_y.connect_as_output(&xor1.b);

//from and of ha1 to or
let mut s_ha1_o = Signal::new();
s_ha1_o.connect_as_input(&and1.z);
s_ha1_o.connect_as_output(&or.a);

//from from xor of ha1 to ha2
let mut s_ha1_ha2 = Signal::new();
s_ha1_ha2.connect_as_input(&xor1.z);
s_ha1_ha2.connect_as_output(&and2.a);
s_ha1_ha2.connect_as_output(&xor2.a);

//from cin to and2 and xor2
let mut s_cin_ha2 = Signal::new();
s_cin_ha2.connect_as_input(&c.output);
s_cin_ha2.connect_as_output(&and2.b);
s_cin_ha2.connect_as_output(&xor2.b);

//from and2 to xor
let mut s_ha2_o = Signal::new();
s_ha2_o.connect_as_input(&and2.z);
s_ha2_o.connect_as_output(&or.b);

//from or to cout
let mut s_or_cout = Signal::new();
s_or_cout.connect_as_input(&or.z);
s_or_cout.connect_as_output(&cout.input);

//from xor2 to s
let mut s_ha_s = Signal::new();
s_ha_s.connect_as_input(&xor2.z);
s_ha_s.connect_as_output(&s.input);

let mut r = Reactor::new();

r.add_updater(&s_x);
r.add_updater(&s_y);
r.add_updater(&s_ha1_o);
r.add_updater(&s_ha1_ha2);
r.add_updater(&s_cin_ha2);
r.add_updater(&s_ha2_o);
r.add_updater(&s_or_cout);
r.add_updater(&s_ha_s);
r.add_updater(&and1);
r.add_updater(&and2);
r.add_updater(&xor1);
r.add_updater(&xor2);
r.add_updater(&or);

const _0: Ieee1164 = Ieee1164::Strong(Ieee1164Value::Zero);
const _1: Ieee1164 = Ieee1164::Strong(Ieee1164Value::One);

const VALUES: [[Ieee1164; 5]; 8] = [
[_0, _0, _0, _0, _0],
[_0, _0, _1, _1, _0],
[_0, _1, _0, _1, _0],
[_0, _1, _1, _0, _1],
[_1, _0, _0, _1, _0],
[_1, _0, _1, _0, _1],
[_1, _1, _0, _0, _1],
[_1, _1, _1, _1, _1],
];

for triple in VALUES.iter() {
x.set_value(triple[0]);
y.set_value(triple[1]);
c.set_value(triple[2]);

for _ in 0..3 {
r.tick();
}

println!(
"{} + {} + {} = {}{}",
triple[0],
triple[1],
triple[2],
cout.value(),
s.value()
);
assert_eq!(triple[3], s.value());
assert_eq!(triple[4], cout.value());
sleep(Duration::from_secs(1));
}

Ok(())
}
1 change: 1 addition & 0 deletions src/dump/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//! TODO
35 changes: 35 additions & 0 deletions src/gates/and.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::logicbit::Ieee1164;
use crate::port::Port;
use crate::port::{Input, Output};
use crate::Updateable;

#[derive(Debug, Clone)]
pub struct AndGate {
pub a: Port<Ieee1164, Input>,
pub b: Port<Ieee1164, Input>,
pub z: Port<Ieee1164, Output>,
_private: (),
}

impl Updateable for AndGate {
fn update(&mut self) {
self.z.set_value(self.a.value() & self.b.value());
}
}

impl Default for AndGate {
fn default() -> Self {
Self::new()
}
}

impl AndGate {
pub fn new() -> Self {
Self {
a: Port::default(),
b: Port::default(),
z: Port::default(),
_private: (),
}
}
}
7 changes: 7 additions & 0 deletions src/gates/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod and;
mod or;
mod xor;

pub use self::and::AndGate;
pub use self::or::OrGate;
pub use self::xor::XorGate;
42 changes: 42 additions & 0 deletions src/gates/or.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::logicbit::Ieee1164;
use crate::port::Port;
use crate::port::{Input, Output};
use crate::Updateable;
use std::fmt;

#[derive(Clone)]
pub struct OrGate {
pub a: Port<Ieee1164, Input>,
pub b: Port<Ieee1164, Input>,
pub z: Port<Ieee1164, Output>,
_private: (),
}

impl fmt::Debug for OrGate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "OrGate {{ a: {:?}, b: {:?}, z: {:?} }}", self.a, self.b, self.z)
}
}

impl Updateable for OrGate {
fn update(&mut self) {
self.z.set_value(self.a.value() | self.b.value());
}
}

impl Default for OrGate {
fn default() -> Self {
Self::new()
}
}

impl OrGate {
pub fn new() -> Self {
Self {
a: Port::default(),
b: Port::default(),
z: Port::default(),
_private: (),
}
}
}
35 changes: 35 additions & 0 deletions src/gates/xor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::logicbit::Ieee1164;
use crate::port::Port;
use crate::port::{Input, Output};
use crate::Updateable;

#[derive(Debug, Clone)]
pub struct XorGate {
pub a: Port<Ieee1164, Input>,
pub b: Port<Ieee1164, Input>,
pub z: Port<Ieee1164, Output>,
_private: (),
}

impl Updateable for XorGate {
fn update(&mut self) {
self.z.set_value(self.a.value() ^ self.b.value());
}
}

impl Default for XorGate {
fn default() -> Self {
Self::new()
}
}

impl XorGate {
pub fn new() -> Self {
Self {
a: Port::default(),
b: Port::default(),
z: Port::default(),
_private: (),
}
}
}
68 changes: 68 additions & 0 deletions src/integer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::Resolve;

#[derive(Debug, Default, Clone, Copy)]
pub struct Integer {
value: u128,
width: u8,
}

impl<'a, 'b> Resolve<&'b Integer> for &'a Integer {
type Output = Integer;
fn resolve(self, other: &'b Integer) -> Self::Output {
if self.width != other.width {
panic!("Width mismatch!") //TODO: do not panic
}
Integer {
value: self.value | other.value,
width: self.width,
}
}
fn initial_value(&self) -> Integer {
Integer::new_with_value(0u8, self.width())
}
}

impl PartialEq for Integer {
fn eq(&self, other: &Integer) -> bool {
self.value == other.value
}
}

impl<T: Into<u128> + Copy> PartialEq<T> for Integer {
fn eq(&self, other: &T) -> bool {
self.value == (*other).into()
}
}

impl Eq for Integer {}

impl Integer {
pub fn new() -> Self {
Self { value: 0, width: 128 }
}

pub fn new_with_value(value: impl Into<u128>, width: impl Into<Option<u8>>) -> Self {
Self {
value: value.into(),
width: width.into().unwrap_or(128),
}
}

pub fn new_with_width(width: u8) -> Option<Self> {
if width != 0 && width <= 128 {
Some(Self { value: 0, width })
} else {
None
}
}

pub fn width(&self) -> u8 {
self.width
}

pub fn set_width(&mut self, width: u8) {
if width != 0 && width <= 128 {
self.value &= (1 << width) - 1
}
}
}
Loading

0 comments on commit a7bff0d

Please sign in to comment.