Name
Silicon::Chip - Design a silicon chip by combining logic gates and sub chips.
Synopsis
Create a chip to compare two 4 bit big endian unsigned integers for equality:
my $B = 4; # Number of bits
my $c = Silicon::Chip::newChip(title=>"$B Bit Equals"); # Create chip
$c->input ("a$_") for 1..$B; # First number
$c->input ("b$_") for 1..$B; # Second number
$c->nxor ("e$_", {1=>"a$_", 2=>"b$_"}) for 1..$B; # Test each bit for equality
$c->and ("and", {map{$_=>"e$_"} 1..$B}); # And tests together to get total equality
$c->output("out", "and"); # Output gate
my $s = $c->simulate({a1=>1, a2=>0, a3=>1, a4=>0, # Input gate values
b1=>1, b2=>0, b3=>1, b4=>0},
svg=>"svg/Equals$B"); # Svg drawing of layout
is_deeply($s->steps, 3); # Three steps
is_deeply($s->values->{out}, 1); # Out is 1 for equals
my $t = $c->simulate({a1=>1, a2=>1, a3=>1, a4=>0,
b1=>1, b2=>0, b3=>1, b4=>0});
is_deeply($t->values->{out}, 0); # Out is 0 for not equals
To obtain:
Other circuit diagrams can be seen in folder: lib/Silicon/svg
Description
Design a silicon chip by combining logic gates and sub chips.
Version 20231111.
The following sections describe the methods in each functional area of this module. For an alphabetic listing of all methods by name see Index.
Construct
Construct a Silicon chip using standard logic gates, components and sub chips combined via buses.
newChip (%options)
Create a new chip.
Parameter Description
1 %options Options
Example:
if (1)
{my $c = Silicon::Chip::newChip; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->one ("one");
$c->zero("zero");
$c->or ("or", [qw(one zero)]);
$c->and ("and", [qw(one zero)]);
$c->output("o1", "or");
$c->output("o2", "and");
my $s = $c->simulate({}, svg=>q(svg/oneZero));
is_deeply($s->steps , 3);
is_deeply($s->value("o1"), 1);
is_deeply($s->value("o2"), 0);
}
if (1) # Single AND gate
{my $c = Silicon::Chip::newChip; # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->input ("i1");
$c->input ("i2");
$c->and ("and1", [qw(i1 i2)]);
$c->output("o", "and1");
my $s = $c->simulate({i1=>1, i2=>1});
ok($s->steps == 2);
ok($s->value("and1") == 1);
}
if (1) # 4 bit equal
{my $B = 4; # Number of bits
my $c = Silicon::Chip::newChip(title=><<"END"); # Create chip # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$B Bit Equals
END
$c->input ("a$_") for 1..$B; # First number
$c->input ("b$_") for 1..$B; # Second number
$c->nxor ("e$_", "a$_", "b$_") for 1..$B; # Test each bit for equality
$c->and ("and", {map{$_=>"e$_"} 1..$B}); # And tests together to get total equality
$c->output("out", "and"); # Output gate
my $s = $c->simulate({a1=>1, a2=>0, a3=>1, a4=>0, # Input gate values
b1=>1, b2=>0, b3=>1, b4=>0},
svg=>q(svg/Equals)); # Svg drawing of layout
is_deeply($s->steps, 3); # Three steps
is_deeply($s->value("out"), 1); # Out is 1 for equals
my $t = $c->simulate({a1=>1, a2=>1, a3=>1, a4=>0,
b1=>1, b2=>0, b3=>1, b4=>0});
is_deeply($t->value("out"), 0); # Out is 0 for not equals
}
gate($chip, $type, $output, $input1, $input2)
A logic gate chosen from and|continue|gt|input|lt|nand|nor|not|nxor|one|or|output|xor|zero. The gate type can be used as a method name, so ->gate("and", can be reduced to ->and(.
Parameter Description
1 $chip Chip
2 $type Gate type
3 $output Output name
4 $input1 Input from another gate
5 $input2 Input from another gate
Example:
if (1) # Two AND gates driving an OR gate # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
{my $c = newChip;
$c->input ("i11");
$c->input ("i12");
$c->and ("and1", [qw(i11 i12)]);
$c->input ("i21");
$c->input ("i22");
$c->and ("and2", [qw(i21 i22 )]);
$c->or ("or", [qw(and1 and2)]);
$c->output( "o", "or");
my $s = $c->simulate({i11=>1, i12=>1, i21=>1, i22=>1});
ok($s->steps == 3);
ok($s->value("or") == 1);
$s = $c->simulate({i11=>1, i12=>0, i21=>1, i22=>1});
ok($s->steps == 3);
ok($s->value("or") == 1);
$s = $c->simulate({i11=>1, i12=>0, i21=>1, i22=>0});
ok($s->steps == 3);
ok($s->value("o") == 0);
}
connectInput($chip, $in, $to, %options)
Connect a previously defined input gate to the output of another previously gate on the same chip. This allows us to define a set of gates on the chip without having to know, first, all the names of the gates that will provide input to these gates.
Parameter Description
1 $chip Chip
2 $in Input gate
3 $to Gate to connect input gate to
4 %options Options
Example:
if (1) # Internal input gate
{my $c = newChip();
$c->input ('i'); # Input
$c->input ('j'); # Internal input which we will connect to later
$c->output(qw(o j)); # Output
$c->connectInput(qw(j i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $s = $c->simulate({i=>1});
is_deeply($s->steps, 1);
is_deeply($s->value("j"), undef);
is_deeply($s->value("o"), 1);
}
if (1) # Internal input gate
{my @n = qw(3 2 1 2 3);
my $c = newChip();
$c->words('i', 2, @n); # Input
$c->outputWords(qw(o i)); # Output
my $s = $c->simulate({});
is_deeply($s->steps, 2);
is_deeply([$s->wordsToInteger("i")], [@n]);
}
if (1) # Internal input gate
{my @n = qw(3 2 1 2 3);
my $c = newChip();
$c->words('i', 2, @n); # Input
$c->outputWords(qw(o i)); # Output
my $s = $c->simulate({});
is_deeply($s->steps, 2);
is_deeply([$s->wordsToInteger("i")], [@n]);
}
Buses
A bus is an array of bits or an array of arrays of bits
Bits
An array of bits that can be manipulated via one name.
setSizeBits ($chip, $name, $bits, %options)
Set the size of a bits bus.
Parameter Description
1 $chip Chip
2 $name Bits bus name
3 $bits Options
4 %options
Example:
if (1)
{my $c = newChip();
$c->setSizeBits ('i', 2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->setSizeWords('j', 3, 2);
is_deeply($c->sizeBits, {i => 2, j_1 => 2, j_2 => 2, j_3 => 2});
is_deeply($c->sizeWords, {j => [3, 2]});
}
bits($chip, $name, $bits, $value, %options)
Create a bus set to a specified number.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $bits Width in bits of bus
4 $value Value of bus
5 %options Options
Example:
if (1)
{my $N = 4;
for my $i(0..2**$N-1)
{my $c = Silicon::Chip::newChip;
$c->bits ("c", $N, $i); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits("o", "c");
my $s = $c->simulate({}, $i == 3 ? (svg=>q(svg/bits)) : ()); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply($s->steps, 2);
is_deeply($s->bint("o"), $i);
}
}
inputBits ($chip, $name, $bits, %options)
Create an input bus made of bits.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $bits Width in bits of bus
4 %options Options
Example:
if (1)
{my $W = 8;
my $i = newChip(name=>"not");
$i->inputBits('i', $W); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$i->notBits (qw(n i));
$i->outputBits(qw(o n));
my $o = newChip(name=>"outer");
$o->inputBits ('a', $W); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$o->outputBits(qw(A a));
$o->inputBits ('b', $W); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$o->outputBits(qw(B b));
my %i = connectBits($i, 'i', $o, 'A');
my %o = connectBits($i, 'o', $o, 'b');
$o->install($i, {%i}, {%o});
my %d = setBits($o, 'a', 0b10110);
my $s = $o->simulate({%d}, svg=>q(svg/not));
is_deeply($s->bint('B'), 0b11101001);
}
outputBits ($chip, $name, $input, %options)
Create an output bus made of bits.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my $W = 8;
my $i = newChip(name=>"not");
$i->inputBits('i', $W);
$i->notBits (qw(n i));
$i->outputBits(qw(o n)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $o = newChip(name=>"outer");
$o->inputBits ('a', $W);
$o->outputBits(qw(A a)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$o->inputBits ('b', $W);
$o->outputBits(qw(B b)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my %i = connectBits($i, 'i', $o, 'A');
my %o = connectBits($i, 'o', $o, 'b');
$o->install($i, {%i}, {%o});
my %d = setBits($o, 'a', 0b10110);
my $s = $o->simulate({%d}, svg=>q(svg/not));
is_deeply($s->bint('B'), 0b11101001);
}
if (1)
{my @B = ((my $W = 4), (my $B = 2));
my $c = newChip();
$c->inputWords ('i', @B);
$c->andWords (qw(and i));
$c->andWordsX (qw(andX i));
$c-> orWords (qw( or i));
$c-> orWordsX (qw( orX i));
$c->notWords (qw(n i));
$c->outputBits (qw(And and)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(AndX andX)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(Or or)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(OrX orX)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputWords(qw(N n));
my %d = setWords($c, 'i', 0b00, 0b01, 0b10, 0b11);
my $s = $c->simulate({%d}, svg=>"svg/andOrWords$W");
is_deeply($s->bint('And'), 0b1000);
is_deeply($s->bint('AndX'), 0b0000);
is_deeply($s->bint('Or'), 0b1110);
is_deeply($s->bint('OrX'), 0b11);
is_deeply([$s->wordsToInteger('N')], [3, 2, 1, 0]);
}
notBits ($chip, $name, $input, %options)
Create a not bus made of bits.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my $W = 8;
my $i = newChip(name=>"not");
$i->inputBits('i', $W);
$i->notBits (qw(n i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$i->outputBits(qw(o n));
my $o = newChip(name=>"outer");
$o->inputBits ('a', $W);
$o->outputBits(qw(A a));
$o->inputBits ('b', $W);
$o->outputBits(qw(B b));
my %i = connectBits($i, 'i', $o, 'A');
my %o = connectBits($i, 'o', $o, 'b');
$o->install($i, {%i}, {%o});
my %d = setBits($o, 'a', 0b10110);
my $s = $o->simulate({%d}, svg=>q(svg/not));
is_deeply($s->bint('B'), 0b11101001);
}
andBits ($chip, $name, $input, %options)
and a bus made of bits.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my $W = 8;
my $c = newChip();
$c-> inputBits('i', $W);
$c-> andBits(qw(and i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c-> orBits(qw(or i));
$c-> nandBits(qw(nand i));
$c-> norBits(qw(nor i));
$c->output (qw(And and));
$c->output (qw(Or or));
$c->output (qw(nAnd nand));
$c->output (qw(nOr nor));
my %d = setBits($c, 'i', 0b10110);
my $s = $c->simulate({%d}, svg=>q(svg/andOrBits));
is_deeply($s->value("And"), 0);
is_deeply($s->value("Or"), 1);
is_deeply($s->value("nAnd"), 1);
is_deeply($s->value("nOr"), 0);
}
nandBits($chip, $name, $input, %options)
nand a bus made of bits.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my $W = 8;
my $c = newChip();
$c-> inputBits('i', $W);
$c-> andBits(qw(and i));
$c-> orBits(qw(or i));
$c-> nandBits(qw(nand i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c-> norBits(qw(nor i));
$c->output (qw(And and));
$c->output (qw(Or or));
$c->output (qw(nAnd nand));
$c->output (qw(nOr nor));
my %d = setBits($c, 'i', 0b10110);
my $s = $c->simulate({%d}, svg=>q(svg/andOrBits));
is_deeply($s->value("And"), 0);
is_deeply($s->value("Or"), 1);
is_deeply($s->value("nAnd"), 1);
is_deeply($s->value("nOr"), 0);
}
orBits ($chip, $name, $input, %options)
or a bus made of bits.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Options
4 %options
Example:
if (1)
{my $W = 8;
my $c = newChip();
$c-> inputBits('i', $W);
$c-> andBits(qw(and i));
$c-> orBits(qw(or i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c-> nandBits(qw(nand i));
$c-> norBits(qw(nor i));
$c->output (qw(And and));
$c->output (qw(Or or));
$c->output (qw(nAnd nand));
$c->output (qw(nOr nor));
my %d = setBits($c, 'i', 0b10110);
my $s = $c->simulate({%d}, svg=>q(svg/andOrBits));
is_deeply($s->value("And"), 0);
is_deeply($s->value("Or"), 1);
is_deeply($s->value("nAnd"), 1);
is_deeply($s->value("nOr"), 0);
}
norBits ($chip, $name, $input, %options)
nor a bus made of bits.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Options
4 %options
Example:
if (1)
{my $W = 8;
my $c = newChip();
$c-> inputBits('i', $W);
$c-> andBits(qw(and i));
$c-> orBits(qw(or i));
$c-> nandBits(qw(nand i));
$c-> norBits(qw(nor i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->output (qw(And and));
$c->output (qw(Or or));
$c->output (qw(nAnd nand));
$c->output (qw(nOr nor));
my %d = setBits($c, 'i', 0b10110);
my $s = $c->simulate({%d}, svg=>q(svg/andOrBits));
is_deeply($s->value("And"), 0);
is_deeply($s->value("Or"), 1);
is_deeply($s->value("nAnd"), 1);
is_deeply($s->value("nOr"), 0);
}
Words
An array of arrays of bits that can be manipulated via one name.
setSizeWords($chip, $name, $words, $bits, %options)
Set the size of a bits bus.
Parameter Description
1 $chip Chip
2 $name Bits bus name
3 $words Words
4 $bits Bits per word
5 %options Options
Example:
if (1)
{my $c = newChip();
$c->setSizeBits ('i', 2);
$c->setSizeWords('j', 3, 2); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply($c->sizeBits, {i => 2, j_1 => 2, j_2 => 2, j_3 => 2});
is_deeply($c->sizeWords, {j => [3, 2]});
}
words ($chip, $name, $bits, @values)
Create a word bus set to specified numbers.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $bits Width in bits of each word
4 @values Values of words
Example:
if (1) # Internal input gate
{my @n = qw(3 2 1 2 3);
my $c = newChip();
$c->words('i', 2, @n); # Input # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputWords(qw(o i)); # Output
my $s = $c->simulate({});
is_deeply($s->steps, 2);
is_deeply([$s->wordsToInteger("i")], [@n]);
}
if (1) # Internal input gate
{my @n = qw(3 2 1 2 3);
my $c = newChip();
$c->words('i', 2, @n); # Input # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputWords(qw(o i)); # Output
my $s = $c->simulate({});
is_deeply($s->steps, 2);
is_deeply([$s->wordsToInteger("i")], [@n]);
}
inputWords ($chip, $name, $words, $bits, %options)
Create an input bus made of words.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $words Width in words of bus
4 $bits Width in bits of each word on bus
5 %options Options
Example:
if (1)
{my @b = ((my $W = 4), (my $B = 3));
my $c = newChip();
$c->inputWords ('i', @b); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputWords(qw(o i));
my %d = setWords($c, 'i', 0b000, 0b001, 0b010, 0b011);
my $s = $c->simulate({%d}, svg=>"svg/words$W");
is_deeply([$s->wordsToInteger('o')], [0..3]);
is_deeply([$s->wordXToInteger('o')], [10, 12, 0]);
}
outputWords ($chip, $name, $input, %options)
Create an output bus made of words.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my @b = ((my $W = 4), (my $B = 3));
my $c = newChip();
$c->inputWords ('i', @b);
$c->outputWords(qw(o i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my %d = setWords($c, 'i', 0b000, 0b001, 0b010, 0b011);
my $s = $c->simulate({%d}, svg=>"svg/words$W");
is_deeply([$s->wordsToInteger('o')], [0..3]);
is_deeply([$s->wordXToInteger('o')], [10, 12, 0]);
}
notWords($chip, $name, $input, %options)
Create a not bus made of words.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my @B = ((my $W = 4), (my $B = 2));
my $c = newChip();
$c->inputWords ('i', @B);
$c->andWords (qw(and i));
$c->andWordsX (qw(andX i));
$c-> orWords (qw( or i));
$c-> orWordsX (qw( orX i));
$c->notWords (qw(n i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(And and));
$c->outputBits (qw(AndX andX));
$c->outputBits (qw(Or or));
$c->outputBits (qw(OrX orX));
$c->outputWords(qw(N n));
my %d = setWords($c, 'i', 0b00, 0b01, 0b10, 0b11);
my $s = $c->simulate({%d}, svg=>"svg/andOrWords$W");
is_deeply($s->bint('And'), 0b1000);
is_deeply($s->bint('AndX'), 0b0000);
is_deeply($s->bint('Or'), 0b1110);
is_deeply($s->bint('OrX'), 0b11);
is_deeply([$s->wordsToInteger('N')], [3, 2, 1, 0]);
}
andWords($chip, $name, $input, %options)
and a bus made of words to produce a single word.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my @B = ((my $W = 4), (my $B = 2));
my $c = newChip();
$c->inputWords ('i', @B);
$c->andWords (qw(and i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->andWordsX (qw(andX i));
$c-> orWords (qw( or i));
$c-> orWordsX (qw( orX i));
$c->notWords (qw(n i));
$c->outputBits (qw(And and));
$c->outputBits (qw(AndX andX));
$c->outputBits (qw(Or or));
$c->outputBits (qw(OrX orX));
$c->outputWords(qw(N n));
my %d = setWords($c, 'i', 0b00, 0b01, 0b10, 0b11);
my $s = $c->simulate({%d}, svg=>"svg/andOrWords$W");
is_deeply($s->bint('And'), 0b1000);
is_deeply($s->bint('AndX'), 0b0000);
is_deeply($s->bint('Or'), 0b1110);
is_deeply($s->bint('OrX'), 0b11);
is_deeply([$s->wordsToInteger('N')], [3, 2, 1, 0]);
}
if (1)
{my @b = ((my $W = 4), (my $B = 3));
my $c = newChip();
$c->inputWords ('i', @b);
$c->outputWords(qw(o i));
my %d = setWords($c, 'i', 0b000, 0b001, 0b010, 0b011);
my $s = $c->simulate({%d}, svg=>"svg/words$W");
is_deeply([$s->wordsToInteger('o')], [0..3]);
is_deeply([$s->wordXToInteger('o')], [10, 12, 0]);
}
andWordsX ($chip, $name, $input, %options)
and a bus made of words by and-ing the corresponding bits in each word to make a single word.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my @B = ((my $W = 4), (my $B = 2));
my $c = newChip();
$c->inputWords ('i', @B);
$c->andWords (qw(and i));
$c->andWordsX (qw(andX i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c-> orWords (qw( or i));
$c-> orWordsX (qw( orX i));
$c->notWords (qw(n i));
$c->outputBits (qw(And and));
$c->outputBits (qw(AndX andX));
$c->outputBits (qw(Or or));
$c->outputBits (qw(OrX orX));
$c->outputWords(qw(N n));
my %d = setWords($c, 'i', 0b00, 0b01, 0b10, 0b11);
my $s = $c->simulate({%d}, svg=>"svg/andOrWords$W");
is_deeply($s->bint('And'), 0b1000);
is_deeply($s->bint('AndX'), 0b0000);
is_deeply($s->bint('Or'), 0b1110);
is_deeply($s->bint('OrX'), 0b11);
is_deeply([$s->wordsToInteger('N')], [3, 2, 1, 0]);
}
orWords ($chip, $name, $input, %options)
or a bus made of words to produce a single word.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my @B = ((my $W = 4), (my $B = 2));
my $c = newChip();
$c->inputWords ('i', @B);
$c->andWords (qw(and i));
$c->andWordsX (qw(andX i));
$c-> orWords (qw( or i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c-> orWordsX (qw( orX i));
$c->notWords (qw(n i));
$c->outputBits (qw(And and));
$c->outputBits (qw(AndX andX));
$c->outputBits (qw(Or or));
$c->outputBits (qw(OrX orX));
$c->outputWords(qw(N n));
my %d = setWords($c, 'i', 0b00, 0b01, 0b10, 0b11);
my $s = $c->simulate({%d}, svg=>"svg/andOrWords$W");
is_deeply($s->bint('And'), 0b1000);
is_deeply($s->bint('AndX'), 0b0000);
is_deeply($s->bint('Or'), 0b1110);
is_deeply($s->bint('OrX'), 0b11);
is_deeply([$s->wordsToInteger('N')], [3, 2, 1, 0]);
}
if (1)
{my @b = ((my $W = 4), (my $B = 3));
my $c = newChip();
$c->inputWords ('i', @b);
$c->outputWords(qw(o i));
my %d = setWords($c, 'i', 0b000, 0b001, 0b010, 0b011);
my $s = $c->simulate({%d}, svg=>"svg/words$W");
is_deeply([$s->wordsToInteger('o')], [0..3]);
is_deeply([$s->wordXToInteger('o')], [10, 12, 0]);
}
orWordsX($chip, $name, $input, %options)
or a bus made of words by or-ing the corresponding bits in each word to make a single word.
Parameter Description
1 $chip Chip
2 $name Name of bus
3 $input Name of inputs
4 %options Options
Example:
if (1)
{my @B = ((my $W = 4), (my $B = 2));
my $c = newChip();
$c->inputWords ('i', @B);
$c->andWords (qw(and i));
$c->andWordsX (qw(andX i));
$c-> orWords (qw( or i));
$c-> orWordsX (qw( orX i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->notWords (qw(n i));
$c->outputBits (qw(And and));
$c->outputBits (qw(AndX andX));
$c->outputBits (qw(Or or));
$c->outputBits (qw(OrX orX));
$c->outputWords(qw(N n));
my %d = setWords($c, 'i', 0b00, 0b01, 0b10, 0b11);
my $s = $c->simulate({%d}, svg=>"svg/andOrWords$W");
is_deeply($s->bint('And'), 0b1000);
is_deeply($s->bint('AndX'), 0b0000);
is_deeply($s->bint('Or'), 0b1110);
is_deeply($s->bint('OrX'), 0b11);
is_deeply([$s->wordsToInteger('N')], [3, 2, 1, 0]);
}
Install
Install a chip within a chip as a sub chip.
install ($chip, $subChip, $inputs, $outputs, %options)
Install a chip within another chip specifying the connections between the inner and outer chip. The same chip can be installed multiple times as each chip description is read only.
Parameter Description
1 $chip Outer chip
2 $subChip Inner chip
3 $inputs Inputs of inner chip to to outputs of outer chip
4 $outputs Outputs of inner chip to inputs of outer chip
5 %options Options
Example:
if (1) # Install one chip inside another chip, specifically one chip that performs NOT is installed once to flip a value
{my $i = newChip(name=>"not");
$i-> inputBits('i', 1);
$i-> notBits(qw(n i));
$i->outputBits(qw(o n));
my $o = newChip(name=>"outer");
$o->inputBits('i', 1); $o->outputBits(qw(n i));
$o->inputBits('I', 1); $o->outputBits(qw(N I));
my %i = connectBits($i, 'i', $o, 'n');
my %o = connectBits($i, 'o', $o, 'I');
$o->install($i, {%i}, {%o}); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my %d = $o->setBits('i', 1);
my $s = $o->simulate({%d}, printOff=>"dump/not1", svg=>"svg/not1");
is_deeply($s->steps, 2);
is_deeply($s->values, {"(not 1 n_1)"=>0, "i_1"=>1, "N_1"=>0 });
}
Visualize
Visualize the chip in various ways.
print ($chip, %options)
Dump the logic gates present on a chip.
Parameter Description
1 $chip Chip
2 %options Gates
Example:
if (1)
{my $c = Silicon::Chip::newChip(title=>"And gate");
$c->input ("i1");
$c->input ("i2");
$c->and ("and1", [qw(i1 i2)]);
$c->output("o", "and1");
my $s = $c->simulate({i1=>1, i2=>1});
is_deeply($c->print, <<END); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
i1 : input i1
i2 : input i2
and1 : and i1 i2
o : output and1
END
is_deeply($s->print, <<END); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
i1 : 1 input i1
i2 : 1 input i2
and1 : 1 and i1 i2
o : 1 output and1
END
ok($s->printSvg ne $c->printSvg);
}
Silicon::Chip::Simulation::print($sim, %options)
Print simulation results as text.
Parameter Description
1 $sim Simulation
2 %options Options
Example:
if (1)
{my $c = Silicon::Chip::newChip(title=>"And gate");
$c->input ("i1");
$c->input ("i2");
$c->and ("and1", [qw(i1 i2)]);
$c->output("o", "and1");
my $s = $c->simulate({i1=>1, i2=>1});
is_deeply($c->print, <<END);
i1 : input i1
i2 : input i2
and1 : and i1 i2
o : output and1
END
is_deeply($s->print, <<END);
i1 : 1 input i1
i2 : 1 input i2
and1 : 1 and i1 i2
o : 1 output and1
END
ok($s->printSvg ne $c->printSvg);
}
printSvg($chip, %options)
Dump the logic gates on a chip as an Scalar Vector Graphics drawing to help visualize the structure of the chip.
Parameter Description
1 $chip Chip
2 %options Options
Example:
if (1)
{my $c = Silicon::Chip::newChip(title=>"And gate");
$c->input ("i1");
$c->input ("i2");
$c->and ("and1", [qw(i1 i2)]);
$c->output("o", "and1");
my $s = $c->simulate({i1=>1, i2=>1});
is_deeply($c->print, <<END);
i1 : input i1
i2 : input i2
and1 : and i1 i2
o : output and1
END
is_deeply($s->print, <<END);
i1 : 1 input i1
i2 : 1 input i2
and1 : 1 and i1 i2
o : 1 output and1
END
ok($s->printSvg ne $c->printSvg); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
}
Silicon::Chip::Simulation::printSvg ($sim, %options)
Print simulation results as svg.
Parameter Description
1 $sim Simulation
2 %options Options
Example:
if (1)
{my $c = Silicon::Chip::newChip(title=>"And gate");
$c->input ("i1");
$c->input ("i2");
$c->and ("and1", [qw(i1 i2)]);
$c->output("o", "and1");
my $s = $c->simulate({i1=>1, i2=>1});
is_deeply($c->print, <<END);
i1 : input i1
i2 : input i2
and1 : and i1 i2
o : output and1
END
is_deeply($s->print, <<END);
i1 : 1 input i1
i2 : 1 input i2
and1 : 1 and i1 i2
o : 1 output and1
END
ok($s->printSvg ne $c->printSvg);
}
Basic Circuits
Some well known basic circuits.
n ($c, $i)
Gate name from single index.
Parameter Description
1 $c Gate name
2 $i Bit number
Example:
if (1)
{is_deeply( n(a,1), "a_1"); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply(nn(a,1,2), "a_1_2");
}
nn ($c, $i, $j)
Gate name from double index.
Parameter Description
1 $c Gate name
2 $i Word number
3 $j Bit number
Example:
if (1)
{is_deeply( n(a,1), "a_1");
is_deeply(nn(a,1,2), "a_1_2"); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
}
Comparisons
Compare unsigned binary integers of specified bit widths.
compareEq ($chip, $output, $a, $b, %options)
Compare two unsigned binary integers of a specified width returning 1 if they are equal else 0.
Parameter Description
1 $chip Chip
2 $output Name of component also the output bus
3 $a First integer
4 $b Second integer
5 %options Options
Example:
if (1) # Compare unsigned integers
{my $B = 2;
my $c = Silicon::Chip::newChip(title=><<"END");
$B Bit Compare Equal
END
$c->inputBits($_, $B) for qw(a b); # First and second numbers
$c->compareEq(qw(o a b)); # Compare equals # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->output (qw(out o)); # Comparison result
for my $i(0..2**$B-1) # Each possible number
{for my $j(0..2**$B-1) # Each possible number
{my %a = $c->setBits('a', $i); # Number a
my %b = $c->setBits('b', $j); # Number b
my $s = $c->simulate({%a, %b}, $i==1&&$j==1?(svg=>"svg/CompareEq$B"):()); # Svg drawing of layout
is_deeply($s->value("out"), $i == $j ? 1 : 0); # Equal
is_deeply($s->steps, 3); # Number of steps to stability
}
}
}
compareGt ($chip, $output, $a, $b, %options)
Compare two unsigned binary integers and return 1 if the first integer is more than b else 0.
Parameter Description
1 $chip Chip
2 $output Name of component also the output bus
3 $a First integer
4 $b Second integer
5 %options Options
Example:
if (1) # Compare 8 bit unsigned integers 'a' > 'b' - the pins used to input 'a' must be alphabetically less than those used for 'b'
{my $B = 3;
my $c = Silicon::Chip::newChip(title=><<END);
$B Bit Compare more than
END
$c->inputBits($_, $B) for qw(a b); # First and second numbers
$c->compareGt(qw(o a b)); # Compare more than # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->output (qw(out o)); # Comparison result
for my $i(0..2**$B-1) # Each possible number
{for my $j(0..2**$B-1) # Each possible number
{my %a = $c->setBits('a', $i); # Number a
my %b = $c->setBits('b', $j); # Number b
my $s = $c->simulate({%a, %b}, $i==2&&$j==1?(svg=>"svg/CompareGt$B"):()); # Svg drawing of layout
is_deeply($s->value("out"), $i > $j ? 1 : 0); # More than
is_deeply($s->steps, 4); # Number of steps to stability
}
}
}
compareLt ($chip, $output, $a, $b, %options)
Compare two unsigned binary integers a, b of a specified width. Output out is 1 if a is less than b else 0.
Parameter Description
1 $chip Chip
2 $output Name of component also the output bus
3 $a First integer
4 $b Second integer
5 %options Options
Example:
if (1) # Compare 8 bit unsigned integers 'a' < 'b' - the pins used to input 'a' must be alphabetically less than those used for 'b'
{my $B = 3;
my $c = Silicon::Chip::newChip(title=><<"END");
$B Bit Compare Less Than
END
$c->inputBits($_, $B) for qw(a b); # First and second numbers
$c->compareLt(qw(o a b)); # Compare less than # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->output (qw(out o)); # Comparison result
for my $i(0..2**$B-1) # Each possible number
{for my $j(0..2**$B-1) # Each possible number
{my %a = $c->setBits('a', $i); # Number a
my %b = $c->setBits('b', $j); # Number b
my $s = $c->simulate({%a, %b}, $i==1&&$j==2?(svg=>"svg/CompareLt$B"):()); # Svg drawing of layout
is_deeply($s->value("out"), $i < $j ? 1 : 0); # More than
is_deeply($s->steps, 4); # Number of steps to stability
}
}
}
chooseFromTwoWords ($chip, $output, $a, $b, $choose, %options)
Choose one of two words based on a bit. The first word is chosen if the bit is 0 otherwise the second word is chosen.
Parameter Description
1 $chip Chip
2 $output Name of component also the chosen word
3 $a The first word
4 $b The second word
5 $choose The choosing bit
6 %options Options
Example:
if (1)
{my $B = 4;
my $c = newChip();
$c->inputBits('a', $B); # First word
$c->inputBits('b', $B); # Second word
$c->input ('c'); # Chooser
$c->chooseFromTwoWords(qw(o a b c)); # Generate gates # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits('out', 'o'); # Result
my %a = setBits($c, 'a', 0b0011);
my %b = setBits($c, 'b', 0b1100);
my $s = $c->simulate({%a, %b, c=>1}, svg=>q(svg/chooseFromTwoWords)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply($s->steps, 4);
is_deeply($s->bint('out'), 0b1100);
my $t = $c->simulate({%a, %b, c=>0});
is_deeply($t->steps, 4);
is_deeply($t->bint('out'), 0b0011);
}
enableWord ($chip, $output, $a, $enable, %options)
Output a word or zeros depending on a choice bit. The first word is chosen if the choice bit is 1 otherwise all zeroes are chosen.
Parameter Description
1 $chip Chip
2 $output Name of component also the chosen word
3 $a The first word
4 $enable The second word
5 %options The choosing bit
Example:
if (1)
{my $B = 4;
my $c = newChip();
$c->inputBits ('a', $B); # Word
$c->input ('c'); # Choice bit
$c->enableWord(qw(o a c)); # Generate gates # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits(qw(out o)); # Result
my %a = setBits($c, 'a', 3);
my $s = $c->simulate({%a, c=>1}, svg=>q(svg/enableWord)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply($s->steps, 4);
is_deeply($s->bint('out'), 3);
my $t = $c->simulate({%a, c=>0});
is_deeply($t->steps, 4);
is_deeply($t->bint('out'), 0);
}
Masks
Point masks and monotone masks. A point mask has a single 1 in a sea of 0s as in 00100. A monotone mask has zero or more 0s followed by all 1s as in: 00111.
pointMaskToInteger ($chip, $output, $input, %options)
Convert a mask i known to have at most a single bit on - also known as a point mask - to an output number a representing the location in the mask of the bit set to 1. If no such bit exists in the point mask then output number a is 0.
Parameter Description
1 $chip Chip
2 $output Output name
3 $input Input mask
4 %options Options
Example:
if (1)
{my $B = 4;
my $N = 2**$B-1;
my $c = Silicon::Chip::newChip(title=><<"END");
$B bits point mask to integer
END
$c->inputBits (qw( i), $N); # Mask with no more than one bit on
$c->pointMaskToInteger(qw(o i)); # Convert # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(out o)); # Mask with no more than one bit on
for my $i(0..$N) # Each position of mask
{my %i = setBits($c, 'i', $i ? 1<<($i-1) : 0); # Point in each position with zero representing no position
my $s = $c->simulate(\%i, $i == 5 ? (svg=>"svg/point$B") : ());
is_deeply($s->steps, 2);
my %o = $s->values->%*; # Output bits
my $n = eval join '', '0b', map {$o{n(o,$_)}} reverse 1..$B; # Output bits as number
is_deeply($n, $i);
}
}
integerToPointMask ($chip, $output, $input, %options)
Convert an integer i of specified width to a point mask m. If the input integer is 0 then the mask is all zeroes as well.
Parameter Description
1 $chip Chip
2 $output Output name
3 $input Input mask
4 %options Options
Example:
if (1)
{my $B = 3;
my $N = 2**$B-1;
my $c = Silicon::Chip::newChip(title=><<"END");
$B bit integer to $N bits monotone mask.
END
$c->inputBits (qw( i), $B); # Input bus
$c->integerToPointMask(qw(m i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(o m));
for my $i(0..$N) # Each position of mask
{my %i = setBits($c, 'i', $i);
my $s = $c->simulate(\%i, $i == 5 ? (svg=>"svg/integerToMontoneMask$B"):());
is_deeply($s->steps, 3);
my $r = $s->bint('o'); # Mask values
is_deeply($r, $i ? 1<<($i-1) : 0); # Expected mask
}
}
monotoneMaskToInteger ($chip, $output, $input, %options)
Convert a monotone mask i to an output number r representing the location in the mask of the bit set to 1. If no such bit exists in the point then output in r is 0.
Parameter Description
1 $chip Chip
2 $output Output name
3 $input Input mask
4 %options Options
Example:
if (1)
{my $B = 4;
my $N = 2**$B-1;
my $c = Silicon::Chip::newChip(title=><<"END");
$N bits monotone mask to $B bit integer
END
$c->inputBits ('i', $N);
$c->monotoneMaskToInteger(qw(m i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(o m));
for my $i(0..$N-1) # Each monotone mask
{my %i = setBits($c, 'i', $i > 0 ? 1<<$i-1 : 0);
my $s = $c->simulate(\%i,
$i == 5 ? (svg=>"svg/monotoneMaskToInteger$B") : ()); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply($s->steps, 4);
is_deeply($s->bint('m'), $i);
}
}
monotoneMaskToPointMask ($chip, $output, $input, %options)
Convert a monotone mask i to a point mask o representing the location in the mask of the first bit set to 1. If the monotone mask is all 0s then point mask is too.
Parameter Description
1 $chip Chip
2 $output Output name
3 $input Input mask
4 %options Options
Example:
if (1)
{my $B = 4;
my $c = newChip();
$c->inputBits('m', $B); # Monotone mask
$c->monotoneMaskToPointMask(qw(o m)); # Generate gates # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits('out', 'o'); # Point mask
for my $i(0..$B)
{my %m = $c->setBits('m', eval '0b'.(1 x $i).('0' x ($B-$i)));
my $s = $c->simulate({%m});
is_deeply($s->steps, 2);
is_deeply($s->bint('out'), $i ? (1<<($B-1)) / (1<<($i-1)) : 0);
}
}
integerToMonotoneMask ($chip, $output, $input, %options)
Convert an integer i of specified width to a monotone mask m. If the input integer is 0 then the mask is all zeroes. Otherwise the mask has i-1 leading zeroes followed by all ones thereafter.
Parameter Description
1 $chip Chip
2 $output Output name
3 $input Input mask
4 %options Options
Example:
if (1)
{my $B = 4;
my $N = 2**$B-1;
my $c = Silicon::Chip::newChip(title=><<"END");
Convert $B bit integer to $N bit monotone mask
END
$c->inputBits ('i', $B); # Input gates
$c->integerToMonotoneMask(qw(m i)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(o m)); # Output gates
for my $i(0..$N) # Each position of mask
{my %i = setBits($c, 'i', $i); # The number to convert
my $s = $c->simulate(\%i, $i == 2 ? (svg=>"svg/integerToMontoneMask$B"):());
is_deeply($s->steps, 4);
is_deeply($s->bint('o'), $i > 0 ? ((1<<$N)-1)>>($i-1)<<($i-1) : 0);# Expected mask
}
}
chooseWordUnderMask ($chip, $output, $input, $mask, %options)
Choose one of a specified number of words w, each of a specified width, using a point mask m placing the selected word in o. If no word is selected then o will be zero.
Parameter Description
1 $chip Chip
2 $output Output
3 $input Inputs
4 $mask Mask
5 %options Options
Example:
if (1)
{my $B = 3; my $W = 4;
my $c = Silicon::Chip::newChip(title=><<"END");
Choose one of $W words of $B bits
END
$c->inputWords ('w', $W, $B);
$c->inputBits ('m', $W);
$c->chooseWordUnderMask(qw(W w m)); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits (qw(o W));
my %i = setWords($c, 'w', 0b000, 0b001, 0b010, 0b0100);
my %m = setBits ($c, 'm', 1<<2); # Choose the third word
my $s = $c->simulate({%i, %m}, svg=>"svg/choose_${W}_$B");
is_deeply($s->steps, 3);
is_deeply($s->bint('o'), 0b010);
}
findWord($chip, $output, $key, $words, %options)
Choose one of a specified number of words w, each of a specified width, using a key k. Return a point mask o indicating the locations of the key if found or or a mask equal to all zeroes if the key is not present.
Parameter Description
1 $chip Chip
2 $output Found point mask
3 $key Key
4 $words Words to search
5 %options Options
Example:
if (1)
{my $B = 3; my $W = 2**$B-1;
my $c = Silicon::Chip::newChip(title=><<END);
Search $W words of $B bits
END
$c->inputBits ('k', $B); # Search key
$c->inputWords('w', 2**$B-1, $B); # Words to search
$c->findWord (qw(m k w)); # Find the word # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$c->outputBits(qw(M m)); # Output mask
my %w = setWords($c, 'w', reverse 1..$W);
for my $k(0..$W) # Each possible key
{my %k = setBits($c, 'k', $k);
my $s = $c->simulate({%k, %w}, $k == 3 ? (svg=>q(svg/findWord)) : ()); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply($s->steps, 3);
is_deeply($s->bint('M'),$k ? 2**($W-$k) : 0);
}
}
Simulate
Simulate the behavior of the chip given a set of values on its input gates.
setBits ($chip, $name, $value, %options)
Set an array of input gates to a number prior to running a simulation.
Parameter Description
1 $chip Chip
2 $name Name of input gates
3 $value Number to set to
4 %options Options
Example:
if (1) # Compare two 4 bit unsigned integers 'a' > 'b' - the pins used to input 'a' must be alphabetically less than those used for 'b'
{my $B = 4; # Number of bits
my $c = Silicon::Chip::newChip(title=><<"END");
$B Bit Compare
END
$c->inputBits("a", $B); # First number
$c->inputBits("b", $B); # Second number
$c->nxor (n(e,$_), n(a,$_), n(b,$_)) for 1..$B-1; # Test each bit for equality
$c->gt (n(g,$_), n(a,$_), n(b,$_)) for 1..$B; # Test each bit pair for greater
for my $b(2..$B)
{$c->and(n(c,$b), [(map {n(e, $_)} 1..$b-1), n(g,$b)]); # Greater on one bit and all preceding bits are equal
}
$c->or ("or", [n(g,1), (map {n(c, $_)} 2..$B)]); # Any set bit indicates that 'a' is more than 'b'
$c->output("out", "or"); # Output 1 if a > b else 0
my %a = $c->setBits('a', 0); # Number a # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my %b = $c->setBits('b', 0); # Number b # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $s = $c->simulate({%a, %b, n(a,2)=>1, n(b,2)=>1}); # Two equal numbers
is_deeply($s->value("out"), 0);
my $t = $c->simulate({%a, %b, n(a,2)=>1}, svg=>q(svg/Compare)); # Svg drawing of layout
is_deeply($t->value("out"), 1);
}
if (1)
{my $B = 3; my $W = 4;
my $c = Silicon::Chip::newChip(title=><<"END");
Choose one of $W words of $B bits
END
$c->inputWords ('w', $W, $B);
$c->inputBits ('m', $W);
$c->chooseWordUnderMask(qw(W w m));
$c->outputBits (qw(o W));
my %i = setWords($c, 'w', 0b000, 0b001, 0b010, 0b0100);
my %m = setBits ($c, 'm', 1<<2); # Choose the third word # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my $s = $c->simulate({%i, %m}, svg=>"svg/choose_${W}_$B");
is_deeply($s->steps, 3);
is_deeply($s->bint('o'), 0b010);
}
setWords($chip, $name, @values)
Set an array of arrays of gates to an array of numbers prior to running a simulation.
Parameter Description
1 $chip Chip
2 $name Name of input gates
3 @values Number of bits in each array element
Example:
if (1)
{my $B = 3; my $W = 4;
my $c = Silicon::Chip::newChip(title=><<"END");
Choose one of $W words of $B bits
END
$c->inputWords ('w', $W, $B);
$c->inputBits ('m', $W);
$c->chooseWordUnderMask(qw(W w m));
$c->outputBits (qw(o W));
my %i = setWords($c, 'w', 0b000, 0b001, 0b010, 0b0100); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my %m = setBits ($c, 'm', 1<<2); # Choose the third word
my $s = $c->simulate({%i, %m}, svg=>"svg/choose_${W}_$B");
is_deeply($s->steps, 3);
is_deeply($s->bint('o'), 0b010);
}
connectBits ($oc, $o, $ic, $i, %options)
Create a connection list connecting a set of output bits on the one chip to a set of input bits on another chip.
Parameter Description
1 $oc First chip
2 $o Name of gates on first chip
3 $ic Second chip
4 $i Names of gates on second chip
5 %options Options
Example:
if (1) # Install one chip inside another chip, specifically one chip that performs NOT is installed once to flip a value
{my $i = newChip(name=>"not");
$i-> inputBits('i', 1);
$i-> notBits(qw(n i));
$i->outputBits(qw(o n));
my $o = newChip(name=>"outer");
$o->inputBits('i', 1); $o->outputBits(qw(n i));
$o->inputBits('I', 1); $o->outputBits(qw(N I));
my %i = connectBits($i, 'i', $o, 'n'); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my %o = connectBits($i, 'o', $o, 'I'); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$o->install($i, {%i}, {%o});
my %d = $o->setBits('i', 1);
my $s = $o->simulate({%d}, printOff=>"dump/not1", svg=>"svg/not1");
is_deeply($s->steps, 2);
is_deeply($s->values, {"(not 1 n_1)"=>0, "i_1"=>1, "N_1"=>0 });
}
connectWords($oc, $o, $ic, $i, $words, $bits, %options)
Create a connection list connecting a set of words on the outer chip to a set of words on the inner chip.
Parameter Description
1 $oc First chip
2 $o Name of gates on first chip
3 $ic Second chip
4 $i Names of gates on second chip
5 $words Number of words to connect
6 $bits Options
7 %options
Example:
if (1) # Install one chip inside another chip, specifically one chip that performs NOT is installed three times sequentially to flip a value
{my $i = newChip(name=>"not");
$i-> inputWords('i', 1, 1);
$i-> notWords(qw(n i));
$i->outputWords(qw(o n));
my $o = newChip(name=>"outer");
$o->inputWords('i', 1, 1); $o->output(nn('n', 1, 1), nn('i', 1, 1));
$o->inputWords('I', 1, 1); $o->output(nn('N', 1, 1), nn('I', 1, 1));
my %i = connectWords($i, 'i', $o, 'n', 1, 1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
my %o = connectWords($i, 'o', $o, 'I', 1, 1); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
$o->install($i, {%i}, {%o});
my %d = $o->setWords('i', 1);
my $s = $o->simulate({%d}, printOff=>"dump/not1", svg=>"svg/not1");
is_deeply($s->steps, 2);
is_deeply($s->values, { "(not 1 n_1_1)" => 0, "i_1_1" => 1, "N_1_1" => 0 });
}
Silicon::Chip::Simulation::value($simulation, $name, %options)
Get the value of a gate as seen in a simulation
Parameter Description
1 $simulation Chip
2 $name Gate
3 %options Options
Example:
if (1) # Internal input gate
{my $c = newChip();
$c->input ('i'); # Input
$c->input ('j'); # Internal input which we will connect to later
$c->output(qw(o j)); # Output
$c->connectInput(qw(j i));
my $s = $c->simulate({i=>1});
is_deeply($s->steps, 1);
is_deeply($s->value("j"), undef);
is_deeply($s->value("o"), 1);
}
if (1) # Internal input gate
{my @n = qw(3 2 1 2 3);
my $c = newChip();
$c->words('i', 2, @n); # Input
$c->outputWords(qw(o i)); # Output
my $s = $c->simulate({});
is_deeply($s->steps, 2);
is_deeply([$s->wordsToInteger("i")], [@n]);
}
if (1) # Internal input gate
{my @n = qw(3 2 1 2 3);
my $c = newChip();
$c->words('i', 2, @n); # Input
$c->outputWords(qw(o i)); # Output
my $s = $c->simulate({});
is_deeply($s->steps, 2);
is_deeply([$s->wordsToInteger("i")], [@n]);
}
Silicon::Chip::Simulation::bint ($simulation, $output, %options)
Represent the state of bits in the simulation results as an unsigned binary integer.
Parameter Description
1 $simulation Chip
2 $output Name of gates on bus
3 %options Options
Example:
if (1)
{my $W = 8;
my $i = newChip(name=>"not");
$i->inputBits('i', $W);
$i->notBits (qw(n i));
$i->outputBits(qw(o n));
my $o = newChip(name=>"outer");
$o->inputBits ('a', $W);
$o->outputBits(qw(A a));
$o->inputBits ('b', $W);
$o->outputBits(qw(B b));
my %i = connectBits($i, 'i', $o, 'A');
my %o = connectBits($i, 'o', $o, 'b');
$o->install($i, {%i}, {%o});
my %d = setBits($o, 'a', 0b10110);
my $s = $o->simulate({%d}, svg=>q(svg/not));
is_deeply($s->bint('B'), 0b11101001);
}
Silicon::Chip::Simulation::wordsToInteger ($simulation, $output, %options)
Represent the state of words in the simulation results as an array of unsigned binary integer.
Parameter Description
1 $simulation Chip
2 $output Name of gates on bus
3 %options Options
Example:
if (1)
{my @b = ((my $W = 4), (my $B = 3));
my $c = newChip();
$c->inputWords ('i', @b);
$c->outputWords(qw(o i));
my %d = setWords($c, 'i', 0b000, 0b001, 0b010, 0b011);
my $s = $c->simulate({%d}, svg=>"svg/words$W");
is_deeply([$s->wordsToInteger('o')], [0..3]);
is_deeply([$s->wordXToInteger('o')], [10, 12, 0]);
}
Silicon::Chip::Simulation::wordXToInteger ($simulation, $output, %options)
Represent the state of words in the simulation results as an array of unsigned binary integer.
Parameter Description
1 $simulation Chip
2 $output Name of gates on bus
3 %options Options
Example:
if (1)
{my @b = ((my $W = 4), (my $B = 3));
my $c = newChip();
$c->inputWords ('i', @b);
$c->outputWords(qw(o i));
my %d = setWords($c, 'i', 0b000, 0b001, 0b010, 0b011);
my $s = $c->simulate({%d}, svg=>"svg/words$W");
is_deeply([$s->wordsToInteger('o')], [0..3]);
is_deeply([$s->wordXToInteger('o')], [10, 12, 0]);
}
simulate($chip, $inputs, %options)
Simulate the action of the logic gates on a chip for a given set of inputs until the output value of each logic gate stabilizes.
Parameter Description
1 $chip Chip
2 $inputs Hash of input names to values
3 %options Options
Example:
if (1)
{my $i = newChip(name=>"inner");
$i->input ("Ii");
$i->not ("In", "Ii");
$i->output( "Io", "In");
my $o = newChip(name=>"outer");
$o->input ("Oi1");
$o->output("Oo1", "Oi1");
$o->input ("Oi2");
$o->output("Oo2", "Oi2");
$o->input ("Oi3");
$o->output("Oo3", "Oi3");
$o->input ("Oi4");
$o->output("Oo", "Oi4");
$o->install($i, {Ii=>"Oo1"}, {Io=>"Oi2"});
$o->install($i, {Ii=>"Oo2"}, {Io=>"Oi3"});
$o->install($i, {Ii=>"Oo3"}, {Io=>"Oi4"});
my $s = $o->simulate({Oi1=>1}, printOff=>"dump/not3", svg=>"svg/not3"); # 𝗘𝘅𝗮𝗺𝗽𝗹𝗲
is_deeply($s->value("Oo"), 0);
is_deeply($s->steps, 4);
}
Hash Definitions
Silicon::Chip Definition
Chip description
Output fields
gateSeq
Gate sequence number - this allows us to display the gates in the order they were defined ti simplify the understanding of drawn layouts
gates
Gates in chip
installs
Chips installed within the chip
name
Name of chip
sizeBits
Sizes of buses
sizeWords
Sizes of buses
title
Title if known
Private Methods
AUTOLOAD($chip, @options)
Autoload by logic gate name to provide a more readable way to specify the logic gates on a chip.
Parameter Description
1 $chip Chip
2 @options Options
Index
1 andBits - and a bus made of bits.
2 andWords - and a bus made of words to produce a single word.
3 andWordsX - and a bus made of words by and-ing the corresponding bits in each word to make a single word.
4 AUTOLOAD - Autoload by logic gate name to provide a more readable way to specify the logic gates on a chip.
5 bits - Create a bus set to a specified number.
6 chooseFromTwoWords - Choose one of two words based on a bit.
7 chooseWordUnderMask - Choose one of a specified number of words w, each of a specified width, using a point mask m placing the selected word in o.
8 compareEq - Compare two unsigned binary integers of a specified width returning 1 if they are equal else 0.
9 compareGt - Compare two unsigned binary integers and return 1 if the first integer is more than b else 0.
10 compareLt - Compare two unsigned binary integers a, b of a specified width.
11 connectBits - Create a connection list connecting a set of output bits on the one chip to a set of input bits on another chip.
12 connectInput - Connect a previously defined input gate to the output of another previously gate on the same chip.
13 connectWords - Create a connection list connecting a set of words on the outer chip to a set of words on the inner chip.
14 enableWord - Output a word or zeros depending on a choice bit.
15 findWord - Choose one of a specified number of words w, each of a specified width, using a key k.
16 gate - A logic gate chosen from and|continue|gt|input|lt|nand|nor|not|nxor|one|or|output|xor|zero.
17 inputBits - Create an input bus made of bits.
18 inputWords - Create an input bus made of words.
19 install - Install a chip within another chip specifying the connections between the inner and outer chip.
20 integerToMonotoneMask - Convert an integer i of specified width to a monotone mask m.
21 integerToPointMask - Convert an integer i of specified width to a point mask m.
22 monotoneMaskToInteger - Convert a monotone mask i to an output number r representing the location in the mask of the bit set to 1.
23 monotoneMaskToPointMask - Convert a monotone mask i to a point mask o representing the location in the mask of the first bit set to 1.
24 n - Gate name from single index.
25 nandBits - nand a bus made of bits.
26 newChip - Create a new chip.
27 nn - Gate name from double index.
28 norBits - nor a bus made of bits.
29 notBits - Create a not bus made of bits.
30 notWords - Create a not bus made of words.
31 orBits - or a bus made of bits.
32 orWords - or a bus made of words to produce a single word.
33 orWordsX - or a bus made of words by or-ing the corresponding bits in each word to make a single word.
34 outputBits - Create an output bus made of bits.
35 outputWords - Create an output bus made of words.
36 pointMaskToInteger - Convert a mask i known to have at most a single bit on - also known as a point mask - to an output number a representing the location in the mask of the bit set to 1.
37 print - Dump the logic gates present on a chip.
38 printSvg - Dump the logic gates on a chip as an Scalar Vector Graphics drawing to help visualize the structure of the chip.
39 setBits - Set an array of input gates to a number prior to running a simulation.
40 setSizeBits - Set the size of a bits bus.
41 setSizeWords - Set the size of a bits bus.
42 setWords - Set an array of arrays of gates to an array of numbers prior to running a simulation.
43 Silicon::Chip::Simulation::bint - Represent the state of bits in the simulation results as an unsigned binary integer.
44 Silicon::Chip::Simulation::print - Print simulation results as text.
45 Silicon::Chip::Simulation::printSvg - Print simulation results as svg.
46 Silicon::Chip::Simulation::value - Get the value of a gate as seen in a simulation
47 Silicon::Chip::Simulation::wordsToInteger - Represent the state of words in the simulation results as an array of unsigned binary integer.
48 Silicon::Chip::Simulation::wordXToInteger - Represent the state of words in the simulation results as an array of unsigned binary integer.
49 simulate - Simulate the action of the logic gates on a chip for a given set of inputs until the output value of each logic gate stabilizes.
50 words - Create a word bus set to specified numbers.
Installation
This module is written in 100% Pure Perl and, thus, it is easy to read, comprehend, use, modify and install via cpan:
sudo cpan install Silicon::Chip
Author
Copyright
Copyright (c) 2016-2023 Philip R Brenan.
This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.