Skip to content

Instantly share code, notes, and snippets.

@occar421
Created September 30, 2014 15:04
Show Gist options
  • Save occar421/bec5968ff9f0c61d2c07 to your computer and use it in GitHub Desktop.
Save occar421/bec5968ff9f0c61d2c07 to your computer and use it in GitHub Desktop.
Reactive Extensions Logic Circuit 2

Reactive Extension Logic Circuit 2

Summary

This Gist is experimental logic circuit description with C#.
I think, using Reactive Extension(Rx), we can write electrical circuit easily.
Previous Gist Code

Files

LogicLine.cs

This class means logic wire. Logic gates are defined as operator override. "Vcc" and "GND" are defined. Factory method "CreateWithDefault" also defined.

Component/HalfAdder.cs Component/FullAdder.cs

Half Adder and Full Adder are simple combinational logic circuits.
If we define component once, we can use it everywhere.

Circuit.cs

Circuit description sample. port A, B are changed by timer, and circuit results are changed immediately.

using System;
using System.Reactive.Linq;
namespace LogicCircuit
{
public class Circuit
{
public void Run()
{
var portA = LogicLine.CreateWithDefault(false, Observable.Interval(TimeSpan.FromSeconds(2.0)).TakeWhile(i => i < 8).Select(i => i % 2 == 0));
var portB = LogicLine.CreateWithDefault(false, Observable.Interval(TimeSpan.FromSeconds(1.0)).TakeWhile(i => i < 16).Select(i => i % 2 == 0));
bool A, B, A_and_B, A_or_B, not_A, A_xor_B;
A = B = A_and_B = A_or_B = not_A = A_xor_B = false;
bool[] A_plus_B = new[] { false, false };
portA.Subscribe(value => A = value);
portB.Subscribe(value => B = value);
(portA & portB).Subscribe(value => A_and_B = value);
(portA | portB).Subscribe(value => A_or_B = value);
(!portA).Subscribe(value => not_A = value);
(portA ^ portB).Subscribe(value => A_xor_B = value);
var fa = new LogicCircuit.Component.FullAdder(portA, portB, LogicLine.GND);
fa.S.Subscribe(value => A_plus_B[0] = value);
fa.Cout.Subscribe(value => A_plus_B[1] = value);
Observable.Merge(portA, portB)
.Delay(TimeSpan.FromMilliseconds(100.0)).Throttle(TimeSpan.FromMilliseconds(100.0))
.Subscribe(_ =>
{
Console.Clear();
Console.WriteLine("portA: " + A);
Console.WriteLine("portB: " + B);
Console.WriteLine(" A&B : " + A_and_B);
Console.WriteLine(" A|B : " + A_or_B);
Console.WriteLine(" !A : " + not_A);
Console.WriteLine(" A^B : " + A_xor_B);
Console.WriteLine("---------------");
Console.WriteLine(" A,B : {0},{1}", A ? '1' : '0', B ? '1' : '0');
Console.WriteLine(" A+B : {0}{1}", A_plus_B[1] ? '1' : '0', A_plus_B[0] ? '1' : '0');
}, () => Console.WriteLine("End."));
Console.Read();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LogicCircuit.Component
{
class FullAdder
{
/// <summary>
/// Carry out
/// </summary>
public LogicLine Cout { get; private set; }
/// <summary>
/// Sum
/// </summary>
public LogicLine S { get; private set; }
public FullAdder(LogicLine A, LogicLine B, LogicLine Cin)
{
var ha1 = new HalfAdder(A, B);
var ha2 = new HalfAdder(ha1.S, Cin);
Cout = ha1.C | ha2.C;
S = ha2.S;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LogicCircuit.Component
{
class HalfAdder
{
/// <summary>
/// Carry
/// </summary>
public LogicLine C { get; private set; }
/// <summary>
/// Sum
/// </summary>
public LogicLine S { get; private set; }
public HalfAdder(LogicLine A, LogicLine B)
{
C = A & B;
S = A ^ B;
}
}
}
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
namespace LogicCircuit
{
using ISignal = IObservable<bool>;
public class LogicLine : ISignal
{
ISignal signal;
public LogicLine(ISignal signal)
{
this.signal = signal;
}
static public LogicLine CreateWithDefault(bool def, ISignal stream)
{
return new LogicLine(stream.StartWith(def));
}
public IDisposable Subscribe(IObserver<bool> observer)
{
return this.signal.Subscribe(observer);
}
static public readonly LogicLine Vcc = new LogicLine(Observable.Return(true));
static public readonly LogicLine GND = new LogicLine(Observable.Return(false));
/// <summary>
/// AND gate
/// </summary>
static public LogicLine operator &(LogicLine A, LogicLine B)
{
return new LogicLine(Observable.CombineLatest(A, B, (l, r) => l && r));
}
/// <summary>
/// OR gate
/// </summary>
static public LogicLine operator |(LogicLine A, LogicLine B)
{
return new LogicLine(Observable.CombineLatest(A, B, (l, r) => l || r));
}
/// <summary>
/// NOT gate
/// </summary>
static public LogicLine operator !(LogicLine A)
{
return new LogicLine(A.Select(x => !x));
}
/// <summary>
/// XOR gate
/// </summary>
static public LogicLine operator ^(LogicLine A, LogicLine B)
{
return new LogicLine(Observable.CombineLatest(A, B, (l, r) => l != r));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment