Skip to content

Commit

Permalink
add so much more comments on types!
Browse files Browse the repository at this point in the history
  • Loading branch information
hellow554 committed Dec 3, 2018
1 parent 90bb3c8 commit a46c556
Show file tree
Hide file tree
Showing 7 changed files with 421 additions and 89 deletions.
12 changes: 12 additions & 0 deletions src/dump/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,24 @@ use std::path::Path;
use crate::logicbit::LogicVector;
use chrono::Local;

/// A trait for iterating over the containing [`Port`]s of a `Model`.
///
/// Instead of using (non-exiting) reflection, you have to pass all Ports you want to export to the
/// argument `FnMut`.
///
/// This is mainly used for dumping purposes, because this operations can be quiet expensive.
//TODO: Is this really needed? Let's rethink dumping values.
pub trait IterPorts {
/// See [`IterPorts] for a good description.
///
/// The implementor should pass a short, descripting `&str` as long with the `Port`.
/// Currently only [`Ieee1164`] is supported, in the future other values will be supported too.
fn iter_ports<F>(&self, f: F)
where
F: FnMut(&str, &Port<Ieee1164, Output>);
}

//TODO: Is this really needed? Let's rethink dumping values.
pub trait IterValues {
fn iter_values<F>(&self, f: F)
where
Expand Down
11 changes: 11 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(nll, try_from, vec_remove_item)]
#![warn(missing_docs)]

//! Logical is a digital network simulator. It is named after the german word "Logical" which
//! describes a puzzle that follows the rules of logic.
Expand Down Expand Up @@ -90,10 +91,20 @@ pub use self::logicbit::{Ieee1164, Ieee1164Value, LogicVector, Resolve};
pub use self::port::Port;
pub use self::signal::Signal;

#[allow(unused)]
use self::direction::{InOut, Input, Output, PortDirection};

/// Declares typical structs and trait that are used for indicating directions, e.g. [`Output`],
/// [`Input`], [`InOut`] or [`PortDirection`].
pub mod direction {
pub use super::port::{Dir, InOut, Input, MaybeRead, MaybeWrite, Off, Output, PortDirection, Read, Write};
}

/// Simple update trait for signalling passing values from input to an output. Of course the actual
/// behavior depends on the actual struct that implement this.
pub trait Updateable {
/// When this trait function is called you should perform any action necessary to update the
/// struct, e.g. reading input values and updating output values. These changes should be
/// instant.
fn update(&mut self);
}
87 changes: 62 additions & 25 deletions src/logicbit/ieee1164.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,53 @@ macro_rules! expand_op_ieee1164 {
};
}

/// Represents an [Ieee1164](https://en.wikipedia.org/wiki/IEEE_1164) value. For a better usage,
/// there are associated constants, which all start with an underscore, e.g. [`Ieee1164::_U`].
///
/// The three binary logical operators are defined on this struct so you can use them.
///
/// # Examples
///
/// ```rust
/// # use logical::Ieee1164;
/// let a = Ieee1164::_1;
/// let b = Ieee1164::_0;
/// assert_eq!(Ieee1164::_0, a & b);
/// assert_eq!(Ieee1164::_1, a | b);
/// assert_eq!(Ieee1164::_1, a ^ b);
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Ieee1164 {
/// Uninitialized is the default value. It represents an unknown or invalid value
Uninitialized,
/// Represents a strong [`Ieee1164Value`]
Strong(Ieee1164Value),
/// Represents a weak [`Ieee1164Value`]
Weak(Ieee1164Value),
/// Represents high-impedance
HighImpedance,
/// Represents a don't-care
DontCare,
}

impl Ieee1164 {
/// Uninitialized is the default for an `Ieee1164`. It represents an unknown or invalid value
pub const _U: Ieee1164 = Ieee1164::Uninitialized;
/// Represents a conflicted value between two strong values
pub const _X: Ieee1164 = Ieee1164::Strong(Ieee1164Value::Unknown);
/// Represents a strong 1
pub const _1: Ieee1164 = Ieee1164::Strong(Ieee1164Value::One);
/// Represents a strong 0
pub const _0: Ieee1164 = Ieee1164::Strong(Ieee1164Value::Zero);
/// Represents a conflicted value between two weak values
pub const _W: Ieee1164 = Ieee1164::Weak(Ieee1164Value::Unknown);
/// Represents a weak 1
pub const _H: Ieee1164 = Ieee1164::Weak(Ieee1164Value::One);
/// Represents a weak 1
pub const _L: Ieee1164 = Ieee1164::Weak(Ieee1164Value::Zero);
/// Represents high-impedance
pub const _Z: Ieee1164 = Ieee1164::HighImpedance;
/// Represents a don't-care
pub const _D: Ieee1164 = Ieee1164::DontCare;
}

Expand Down Expand Up @@ -73,6 +102,7 @@ impl From<Ieee1164> for char {
}
}

// this will make the tables shorter
const _U: Ieee1164 = Ieee1164::_U;
const _X: Ieee1164 = Ieee1164::_X;
const _0: Ieee1164 = Ieee1164::_0;
Expand All @@ -86,7 +116,7 @@ const _D: Ieee1164 = Ieee1164::_D;
#[allow(clippy::trivially_copy_pass_by_ref)]
fn and(a: &Ieee1164, b: &Ieee1164) -> Ieee1164 {
const TTABLE: [[Ieee1164; 9]; 9] = [
// U X 0 1 Z W L H -
//U X 0 1 Z W L H -
[_U, _U, _0, _U, _U, _U, _0, _U, _U], // U
[_U, _X, _0, _X, _X, _X, _0, _X, _X], // X
[_0, _0, _0, _0, _0, _0, _0, _0, _0], // 0
Expand All @@ -105,7 +135,7 @@ expand_op_ieee1164!(and, BitAnd, bitand);
#[allow(clippy::trivially_copy_pass_by_ref)]
fn or(a: &Ieee1164, b: &Ieee1164) -> Ieee1164 {
const TTABLE: [[Ieee1164; 9]; 9] = [
// U X 0 1 Z W L H -
//U X 0 1 Z W L H -
[_U, _U, _U, _1, _U, _U, _U, _1, _U], // U
[_U, _X, _X, _1, _X, _X, _X, _1, _X], // X
[_U, _X, _0, _1, _X, _X, _0, _1, _X], // 0
Expand All @@ -124,7 +154,7 @@ expand_op_ieee1164!(or, BitOr, bitor);
#[allow(clippy::trivially_copy_pass_by_ref)]
fn xor(a: &Ieee1164, b: &Ieee1164) -> Ieee1164 {
const TTABLE: [[Ieee1164; 9]; 9] = [
// U X 0 1 Z W L H -
//U X 0 1 Z W L H -
[_U, _U, _U, _U, _U, _U, _U, _U, _U], // U
[_U, _X, _X, _X, _X, _X, _X, _X, _X], // X
[_U, _X, _0, _1, _X, _X, _0, _1, _X], // 0
Expand All @@ -142,17 +172,10 @@ expand_op_ieee1164!(xor, BitXor, bitxor);

fn not(i: Ieee1164) -> Ieee1164 {
match i {
Ieee1164::Uninitialized => Ieee1164::Uninitialized,
Ieee1164::Weak(Ieee1164Value::Zero) | Ieee1164::Strong(Ieee1164Value::Zero) => {
Ieee1164::Strong(Ieee1164Value::One)
}
Ieee1164::Weak(Ieee1164Value::One) | Ieee1164::Strong(Ieee1164Value::One) => {
Ieee1164::Strong(Ieee1164Value::Zero)
}
Ieee1164::Strong(Ieee1164Value::Unknown)
| Ieee1164::HighImpedance
| Ieee1164::Weak(Ieee1164Value::Unknown)
| Ieee1164::DontCare => Ieee1164::Strong(Ieee1164Value::Unknown),
_U => _U,
_L | _0 => _1,
_H | _1 => _0,
_ => Ieee1164::_X,
}
}
impl Not for Ieee1164 {
Expand All @@ -171,7 +194,7 @@ impl<'a> Not for &'a Ieee1164 {
#[allow(clippy::trivially_copy_pass_by_ref)]
fn resolve(a: &Ieee1164, b: &Ieee1164) -> Ieee1164 {
const TTABLE: [[Ieee1164; 9]; 9] = [
// U X 0 1 Z W L H -
//U X 0 1 Z W L H -
[_U, _U, _U, _U, _U, _U, _U, _U, _U], // U
[_U, _X, _X, _X, _X, _X, _X, _X, _X], // X
[_U, _X, _0, _X, _0, _0, _0, _0, _X], // 0
Expand All @@ -195,69 +218,83 @@ impl fmt::Display for Ieee1164 {
impl Ieee1164 {
fn to_index(self) -> usize {
match self {
Ieee1164::Uninitialized => 0,
Ieee1164::Strong(Ieee1164Value::Unknown) => 1,
Ieee1164::Strong(Ieee1164Value::Zero) => 2,
Ieee1164::Strong(Ieee1164Value::One) => 3,
Ieee1164::HighImpedance => 4,
Ieee1164::Weak(Ieee1164Value::Unknown) => 5,
Ieee1164::Weak(Ieee1164Value::Zero) => 6,
Ieee1164::Weak(Ieee1164Value::One) => 7,
Ieee1164::DontCare => 8,
Ieee1164::_U => 0,
Ieee1164::_X => 1,
Ieee1164::_0 => 2,
Ieee1164::_1 => 3,
Ieee1164::_Z => 4,
Ieee1164::_W => 5,
Ieee1164::_L => 6,
Ieee1164::_H => 7,
Ieee1164::_D => 8,
}
}
}

#[allow(non_snake_case)]
impl Ieee1164 {
/// Checks whether this is either [`Ieee1164::_U`], [`Ieee1164::_X`], [`Ieee1164::_W`],
/// [`Ieee1164::_Z`] or [`Ieee1164::_D`].
pub fn is_UXZ(self) -> bool {
!(self.is_1H() || self.is_0L())
}

/// Checks whether this is either [`Ieee1164::_0`], [`Ieee1164::_1`]
pub fn is_01(self) -> bool {
self.is_0() || self.is_1()
}

/// Checks whether this is either [`Ieee1164::_1`], [`Ieee1164::_H`]
pub fn is_1H(self) -> bool {
self.is_1() || self.is_H()
}

/// Checks whether this is either [`Ieee1164::_0`], [`Ieee1164::_L`]
pub fn is_0L(self) -> bool {
self.is_0() || self.is_L()
}

/// Checks whether this is either [`Ieee1164::_U`]
pub fn is_U(self) -> bool {
self == _U
}

/// Checks whether this is either [`Ieee1164::_X`]
pub fn is_X(self) -> bool {
self == _X
}

/// Checks whether this is either [`Ieee1164::_0`]
pub fn is_0(self) -> bool {
self == _0
}

/// Checks whether this is either [`Ieee1164::_1`]
pub fn is_1(self) -> bool {
self == _1
}

/// Checks whether this is either [`Ieee1164::_Z`]
pub fn is_Z(self) -> bool {
self == _Z
}

/// Checks whether this is either [`Ieee1164::_W`]
pub fn is_W(self) -> bool {
self == _W
}

/// Checks whether this is either [`Ieee1164::_L`]
pub fn is_L(self) -> bool {
self == _L
}

/// Checks whether this is either [`Ieee1164::_H`]
pub fn is_H(self) -> bool {
self == _H
}

/// Checks whether this is either [`Ieee1164::_D`]
pub fn is_D(self) -> bool {
self == _D
}
Expand All @@ -268,7 +305,7 @@ mod tests {
use super::*;

#[test]
fn add() {
fn and() {
assert_eq!(Ieee1164::_0, Ieee1164::_X & Ieee1164::_0);
}

Expand Down
Loading

0 comments on commit a46c556

Please sign in to comment.