Permalink
Browse files

Port the TTL examples from poetalk to POE::Stage emitters and

observers.  The new versions fail for the same reasons as before:
There is no clock to drive "electrical" signal propagation, so
non-trivial recursive circuits fire out of order.  The results are
unstable and incorrect.
  • Loading branch information...
1 parent e8bce16 commit e56160cc776959792edb6239f4d2ed887555e35a @rcaputo committed Aug 25, 2009
View
@@ -0,0 +1,147 @@
+# $Id$
+
+# Full adder integrated circuit. Not clocked.
+#
+# A --------+---a\
+# | (XOR ab)--+-a\
+# B -----+------b/ | (XOR cin)----- Sum
+# | | +-----b/
+# | | | |
+# Cin ------------------+ |
+# | | | +-a\
+# | | | (AND cin)-a\
+# | +a\ +-----b/ (OR)-- Cout
+# | (AND ab)-------------------b/
+# +---b/
+#
+# A + B + Cin = Sum + Cout
+# 0 0 0 0 0
+# 1 0 0 1 0
+# 0 1 0 1 0
+# 1 1 0 0 1
+# 0 0 1 1 0
+# 1 0 1 0 1
+# 0 1 1 0 1
+# 1 1 1 1 1
+
+package Ttl::Adder;
+use Moose;
+extends 'Stage';
+use Ttl::Xor;
+use Ttl::And;
+use Ttl::Or;
+
+has a => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has b => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has cin => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has xor_ab => (
+ isa => 'Ttl::Xor',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has xor_cin => (
+ isa => 'Ttl::Xor',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has and_ab => (
+ isa => 'Ttl::And',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has and_cin => (
+ isa => 'Ttl::And',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has or_cout => (
+ isa => 'Ttl::Or',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has sum => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has cout => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+sub on_my_a {
+ my ($self, $args) = @_;
+ $self->xor_ab()->a($args->{value});
+ $self->and_ab()->a($args->{value});
+}
+
+sub on_my_b {
+ my ($self, $args) = @_;
+ $self->xor_ab()->b($args->{value});
+ $self->and_ab()->b($args->{value});
+}
+
+sub on_my_cin {
+ my ($self, $args) = @_;
+ $self->xor_cin()->b($args->{value});
+ $self->and_cin()->b($args->{value});
+}
+
+sub on_xor_ab_out {
+ my ($self, $args) = @_;
+ $self->xor_cin()->a($args->{value});
+ $self->and_cin()->a($args->{value});
+}
+
+sub on_xor_cin_out {
+ my ($self, $args) = @_;
+ $self->sum($args->{value});
+}
+
+sub on_and_ab_out {
+ my ($self, $args) = @_;
+ $self->or_cout->b($args->{value});
+}
+
+sub on_and_cin_out {
+ my ($self, $args) = @_;
+ $self->or_cout->a($args->{value});
+}
+
+sub on_or_cout_out {
+ my ($self, $args) = @_;
+ $self->cout($args->{value});
+}
+
+sub BUILD {
+ my $self = shift;
+ $self->xor_ab( Ttl::Xor->new() );
+ $self->xor_cin( Ttl::Xor->new() );
+ $self->and_ab( Ttl::And->new() );
+ $self->and_cin( Ttl::And->new() );
+ $self->or_cout( Ttl::Or->new() );
+}
+
+1;
View
@@ -0,0 +1,19 @@
+# $Id$
+
+# Logical AND gate.
+# a b out
+# 0 0 0
+# 1 0 0
+# 0 1 0
+# 1 1 1
+
+package Ttl::And;
+use Moose;
+extends 'Ttl::Bin';
+
+sub on_my_change {
+ my $self = shift;
+ $self->out( ($self->a() && $self->b()) || 0 );
+}
+
+1;
View
@@ -0,0 +1,30 @@
+# $Id$
+
+# Base class for binary TTL gates.
+
+package Ttl::Bin;
+use Moose;
+extends 'Stage';
+use EmitterTrait;
+
+has a => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+ event => 'change',
+);
+
+has b => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+ event => 'change',
+);
+
+has out => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+1;
View
@@ -0,0 +1,168 @@
+# $Id$
+
+# D flip-flop.
+#
+# Six tri-input NAND gates don't translate to ASCII art very well.
+# The working version comes from Don Lancaster's _TTL Cookbook_.
+
+package Ttl::FlipFlop::D;
+use Moose;
+extends 'Stage';
+use Ttl::TriNand;
+use ObserverTrait;
+use EmitterTrait;
+
+has clear => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has clock => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has d => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has preset => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has q => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+has not_q => (
+ isa => 'Bool',
+ is => 'rw',
+ traits => ['Emitter'],
+);
+
+sub BUILD {
+ my $self = shift;
+
+ $self->tri1( Ttl::TriNand->new() );
+ $self->tri2( Ttl::TriNand->new() );
+ $self->tri3( Ttl::TriNand->new() );
+ $self->tri4( Ttl::TriNand->new() );
+ $self->tri5( Ttl::TriNand->new() );
+ $self->tri6( Ttl::TriNand->new() );
+
+ # Toggle clear low/high to clear output.
+ $self->preset(1);
+ $self->clear(1);
+ $self->clock(1);
+ $self->d(0);
+}
+
+sub on_my_clear {
+ my ($self, $args) = @_;
+ my $value = $args->{value};
+ $self->tri2->b($value);
+ $self->tri4->b($value);
+ $self->tri6->b($value);
+}
+
+sub on_my_clock {
+ my ($self, $args) = @_;
+ my $value = $args->{value};
+ $self->tri2->c($value);
+ $self->tri3->b($value);
+}
+
+sub on_my_d {
+ my ($self, $args) = @_;
+ $self->tri4->c($args->{value});
+}
+
+sub on_my_preset {
+ my ($self, $args) = @_;
+ my $value = $args->{value};
+ $self->tri1->a($value);
+ $self->tri5->a($value);
+}
+
+sub on_tri1_out {
+ my ($self, $args) = @_;
+ $self->tri2->a($args->{value});
+}
+
+sub on_tri2_out {
+ my ($self, $args) = @_;
+ $self->tri1->c($args->{value});
+ $self->tri3->a($args->{value});
+ $self->tri5->b($args->{value});
+}
+
+sub on_tri3_out {
+ my ($self, $args) = @_;
+ $self->tri4->a($args->{value});
+ $self->tri6->c($args->{value});
+}
+
+sub on_tri4_out {
+ my ($self, $args) = @_;
+ $self->tri1->b($args->{value});
+ $self->tri3->c($args->{value});
+}
+
+sub on_tri5_out {
+ my ($self, $args) = @_;
+ $self->q($args->{value});
+ $self->tri6->a($args->{value});
+}
+
+sub on_tri6_out {
+ my ($self, $args) = @_;
+ $self->not_q($args->{value});
+ $self->tri5->c($args->{value});
+}
+
+
+has tri1 => (
+ isa => 'Ttl::TriNand',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has tri2 => (
+ isa => 'Ttl::TriNand',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has tri3 => (
+ isa => 'Ttl::TriNand',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has tri4 => (
+ isa => 'Ttl::TriNand',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has tri5 => (
+ isa => 'Ttl::TriNand',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+has tri6 => (
+ isa => 'Ttl::TriNand',
+ is => 'rw',
+ traits => ['Observer'],
+);
+
+1;
Oops, something went wrong.

0 comments on commit e56160c

Please sign in to comment.