logicuit 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c670278d5f0547d3b3acdaa0f828731de1351c1d4148c2df2b57bae5a43a199
4
- data.tar.gz: f84a271fd5df3767035f77ba196a84638a5214d52b71cd7151c81b18162709a5
3
+ metadata.gz: 7ef81360704b23fe06ebb5c22d0d4c38ebce1eb8da32e7a505e4f021221c72cd
4
+ data.tar.gz: 2c28373e690be07f5cb610fedda7cdb128298eba6471bf50ff9eae7790bfc06d
5
5
  SHA512:
6
- metadata.gz: 95e3514d3a0327f43becf3066a5a9ad6ecf4dcc51af6af0dfcbf1475fe055faaa715925878422fdc268c261006ea66514b7f6ad90a721c5f0f193cd66104231a
7
- data.tar.gz: 39f1237f88d0bcf06d8aed9b08d9e9fd0c7b6f9659c8b6843c8c320382aff5a249f82c2e180a508fb3e9dac14f7eef04d02f6ed2037d14481d6abf2b8fdd3cc6
6
+ metadata.gz: 1ebd743740d8ed0e04bab8524e46281677adae99bfda0a792118e8a3a225a3574538a24096c3ad32549be00acca91c14f9b283b49764971897345a46a32ab2d8
7
+ data.tar.gz: d68eeceb3aedcf4dd2e23c51da0deb50523d53bd8bee37e4773c43be0a9bbe98dcb8ca80a6282ae805c9df0f35862703e468c4f8997867798e4cbc49be7c4530
data/README.md CHANGED
@@ -21,48 +21,47 @@ gem install logicuit
21
21
  This is the code to create a 1-bit CPU:
22
22
 
23
23
  ```
24
- require "logicuit"
25
-
26
- # 1 bit CPU
27
- #
28
- # +-(Y)-|NOT|-(A)-+
29
- # | |
30
- # +-(D)-| |-(Q)-+
31
- # |DFF|
32
- # (CK)-|> |
33
- #
34
- class OneBitCpu
35
- def initialize
36
- @dff = Logicuit::Circuits::Sequential::DFlipFlop.new
37
- @not = Logicuit::Gates::Not.new
38
- @dff.q >> @not.a
39
- @not.y >> @dff.d
40
- end
41
-
42
- def to_s
43
- <<~CIRCUIT
44
- +-(#{@not.y})-|NOT|-(#{@not.a})-+
45
- | |
46
- +-(#{@dff.d})-| |-(#{@dff.q})-+
47
- |DFF|
48
- (CK)-|> |
49
- CIRCUIT
50
- end
51
- end
24
+ require 'logicuit'
25
+
26
+ class Multiplexer2To1 < Logicuit::Base
27
+ tag :MY_MUX
28
+
29
+ diagram <<~DIAGRAM
30
+ (C0)---------|
31
+ |AND|--+
32
+ +-|NOT|-| +--|
33
+ | |OR|--(Y)
34
+ (C1)---------| +--|
35
+ | |AND|--+
36
+ (A)--+-------|
37
+ DIAGRAM
38
+
39
+ define_inputs :c0, :c1, :a
52
40
 
53
- obc = OneBitCpu.new
54
- loop do
55
- system("clear")
56
- puts obc
57
- sleep 1
58
- Logicuit::Signals::Clock.tick
41
+ define_outputs y: ->(c0, c1, a) { (c0 && !a) || (c1 && a) }
59
42
  end
43
+
44
+ Logicuit.run(:MY_MUX)
60
45
  ```
61
46
 
62
- you can execute the following as a one-liner:
47
+ you can execute a same circuit by the following as a one-liner:
48
+
49
+ ```
50
+ $ ruby -r ./lib/logicuit -e 'Logicuit.run(:mux)'
51
+ ```
52
+
53
+ you can similarly execute other circuits with the following commands:
54
+
55
+ ```
56
+ $ ruby -r ./lib/logicuit -e 'Logicuit.run(:mux)'
57
+ ```
58
+
59
+ ```
60
+ $ ruby -r ./lib/logicuit -e 'Logicuit.run(:dff)'
61
+ ```
63
62
 
64
63
  ```
65
- $ ruby -r logicuit -e 'Logicuit::Circuits::SystemLevel::OneBitCpu.run'
64
+ $ ruby -r ./lib/logicuit -e 'Logicuit.run(:one_bit_cpu)'
66
65
  ```
67
66
 
68
67
  ## Development
data/lib/logicuit/base.rb CHANGED
@@ -1,51 +1,68 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Logicuit module
3
4
  module Logicuit
4
5
  # base class for all gates and circuits
5
- class Base
6
+ class Base # rubocop:disable Metrics/ClassLength
7
+ def self.tag(*tags)
8
+ tags.each do |tag|
9
+ registry[tag] = self
10
+ end
11
+ end
12
+
13
+ @@registry = {} # rubocop:disable Style/ClassVars
14
+
15
+ def self.registry
16
+ @@registry
17
+ end
18
+
6
19
  def initialize(*args)
7
20
  @input_targets = []
8
21
  @output_targets = []
9
- define_inputs(*args)
10
- define_outputs
11
- evaluate
22
+ @clock = false
23
+ define_inputs(*args) if respond_to?(:define_inputs)
24
+ define_outputs if respond_to?(:define_outputs)
25
+ assembling if respond_to?(:assembling)
26
+ evaluate if respond_to?(:evaluate)
12
27
  end
13
28
 
14
- attr_reader :input_targets, :output_targets
29
+ attr_reader :input_targets, :output_targets, :clock
15
30
 
16
- def self.define_inputs(*inputs) # rubocop:disable Metrics/MethodLength
17
- inputs.each do |input|
31
+ def self.define_inputs(*args, **kwargs) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
32
+ args.each do |input|
18
33
  define_method(input) do
19
34
  instance_variable_get("@#{input}")
20
35
  end
21
36
  end
22
37
 
23
- define_method(:define_inputs) do |*args|
24
- inputs.each_with_index do |input, index|
25
- signal = Signals::Signal.new(args[index] == 1)
26
- signal.on_change << self
38
+ define_method(:define_inputs) do |*instance_method_args|
39
+ instance_variable_set("@clock", true) if kwargs&.key?(:clock)
40
+ args.each_with_index do |input, index|
41
+ signal = Signals::Signal.new(instance_method_args[index] == 1)
42
+ signal.on_change << self unless clock
27
43
  instance_variable_set("@#{input}", signal)
28
44
  @input_targets << input
29
45
  end
46
+ Signals::Clock.on_tick << self if clock
30
47
  end
31
48
  end
32
49
 
33
- def self.define_outputs(**outputs) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
34
- outputs.each_key do |output|
50
+ def self.define_outputs(*args, **kwargs) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
51
+ (args + kwargs.keys).each do |output|
35
52
  define_method(output) do
36
53
  instance_variable_get("@#{output}")
37
54
  end
38
55
  end
39
56
 
40
57
  define_method(:define_outputs) do
41
- outputs.each_key do |output|
58
+ (args + kwargs.keys).each do |output|
42
59
  instance_variable_set("@#{output}", Signals::Signal.new(false))
43
60
  @output_targets << output
44
61
  end
45
62
  end
46
63
 
47
64
  define_method(:evaluate) do
48
- outputs.each do |output, evaluator|
65
+ kwargs.each do |output, evaluator|
49
66
  signal = instance_variable_get("@#{output}")
50
67
  if evaluator.call(*@input_targets.map do |input|
51
68
  instance_variable_get("@#{input}").current
@@ -58,6 +75,12 @@ module Logicuit
58
75
  end
59
76
  end
60
77
 
78
+ def self.assembling
79
+ define_method(:assembling) do
80
+ yield(*(@input_targets + @output_targets).map { |target| instance_variable_get("@#{target}") })
81
+ end
82
+ end
83
+
61
84
  def self.diagram(source)
62
85
  define_method(:to_s) do
63
86
  (@input_targets + @output_targets).reduce(source) do |result, input|
@@ -74,6 +97,8 @@ module Logicuit
74
97
  table = rows.map do |row|
75
98
  row.split("|").map(&:strip).reject(&:empty?).map(&:downcase).map do |v|
76
99
  case v
100
+ when "^"
101
+ :clock
77
102
  when "x"
78
103
  :any
79
104
  when "1"
@@ -107,4 +132,41 @@ module Logicuit
107
132
  end
108
133
  end
109
134
  end
135
+
136
+ def self.run(sym) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength,Metrics/PerceivedComplexity
137
+ circuit = Base.registry[sym.upcase.to_sym].new
138
+
139
+ render = lambda {
140
+ system("clear")
141
+ puts circuit
142
+ puts
143
+ puts "tick: #{Signals::Clock.tick_count}" if circuit.clock
144
+ puts "input: #{circuit.input_targets.join ","}?" if circuit.input_targets.any?
145
+ }
146
+
147
+ if circuit.clock
148
+ Thread.new do
149
+ loop do
150
+ render.call
151
+ sleep 1
152
+ Signals::Clock.tick
153
+ end
154
+ end
155
+ else
156
+ render.call
157
+ end
158
+
159
+ while (input = gets)
160
+ key = input.chomp.to_sym
161
+ next unless circuit.respond_to? key
162
+
163
+ signal = circuit.send(key)
164
+ if signal.current
165
+ signal.off
166
+ else
167
+ signal.on
168
+ end
169
+ render.call
170
+ end
171
+ end
110
172
  end
@@ -1,3 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # TODO: implement the HalfAdder class
3
+ module Logicuit
4
+ module Circuits
5
+ module Combinational
6
+ # HalfAdder class
7
+ class HalfAdder < Base
8
+ tag :HADD
9
+
10
+ diagram <<~DIAGRAM
11
+ (A)---+-|
12
+ | |XOR|-(S)
13
+ (B)-+---+
14
+ | |
15
+ | +-|
16
+ | |AND|-(C)
17
+ +---|
18
+ DIAGRAM
19
+
20
+ define_inputs :a, :b
21
+
22
+ define_outputs :c, :s
23
+
24
+ assembling do |a, b, c, s|
25
+ xor_gate = Gates::Xor.new
26
+ and_gate = Gates::And.new
27
+
28
+ a >> xor_gate.a
29
+ b >> xor_gate.b
30
+ xor_gate.y >> s
31
+
32
+ a >> and_gate.a
33
+ b >> and_gate.b
34
+ and_gate.y >> c
35
+ end
36
+
37
+ truth_table <<~TRUTH_TABLE
38
+ | A | B | C | S |
39
+ | - | - | - | - |
40
+ | 0 | 0 | 0 | 0 |
41
+ | 0 | 1 | 0 | 1 |
42
+ | 1 | 0 | 0 | 1 |
43
+ | 1 | 1 | 1 | 0 |
44
+ TRUTH_TABLE
45
+ end
46
+ end
47
+ end
48
+ end
@@ -5,11 +5,7 @@ module Logicuit
5
5
  module Combinational
6
6
  # A Multiplexer with 2 inputs and 1 output
7
7
  class Multiplexer2To1 < Base
8
- define_inputs :c0, :c1, :a
9
-
10
- define_outputs y: lambda { |c0, c1, a|
11
- (c0 && !a) || (c1 && a)
12
- }
8
+ tag :MUX, :MUX2, :MUX2to1
13
9
 
14
10
  diagram <<~DIAGRAM
15
11
  (C0)---------|
@@ -21,6 +17,10 @@ module Logicuit
21
17
  (A)--+-------|
22
18
  DIAGRAM
23
19
 
20
+ define_inputs :c0, :c1, :a
21
+
22
+ define_outputs y: ->(c0, c1, a) { (c0 && !a) || (c1 && a) }
23
+
24
24
  truth_table <<~TRUTH_TABLE
25
25
  | C0 | C1 | A | Y |
26
26
  | -- | -- | - | - |
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Circuits
5
+ module Combinational
6
+ # A Multiplexer with 4 inputs and 1 output
7
+ class Multiplexer4To1 < Base
8
+ tag :MUX4, :MUX4TO1
9
+
10
+ diagram <<~DIAGRAM
11
+ (C0)---------------|
12
+ +---|AND|---+
13
+ | +-| |
14
+ | | |
15
+ (C1)---------------| +-|
16
+ +---|AND|-+ |
17
+ +-----------| +---|
18
+ | | | |OR|--(Y)
19
+ (C2)---------------| +---|
20
+ +-------------|AND|-+ |
21
+ | | | +-| +-|
22
+ | | | | |
23
+ (C3)---------------| |
24
+ +-------------|AND|---+
25
+ | +-----------|
26
+ | | | |
27
+ (B)--+---|NOT|-+ |
28
+ | |
29
+ (A)----+-|NOT|---+
30
+ DIAGRAM
31
+
32
+ define_inputs :c0, :c1, :c2, :c3, :b, :a
33
+
34
+ define_outputs y: lambda { |c0, c1, c2, c3, b, a|
35
+ (c0 && !b && !a) || (c1 && !b && a) || (c2 && b && !a) || (c3 && b && a)
36
+ }
37
+
38
+ truth_table <<~TRUTH_TABLE
39
+ | B | A | C0 | C1 | C2 | C3 | Y |
40
+ | - | - | -- | -- | -- | -- | - |
41
+ | 0 | 0 | 0 | x | x | x | 0 |
42
+ | 0 | 0 | 1 | x | x | x | 1 |
43
+ | 0 | 1 | x | 0 | x | x | 0 |
44
+ | 0 | 1 | x | 1 | x | x | 1 |
45
+ | 1 | 0 | x | x | 0 | x | 0 |
46
+ | 1 | 0 | x | x | 1 | x | 1 |
47
+ | 1 | 1 | x | x | x | 0 | 0 |
48
+ | 1 | 1 | x | x | x | 1 | 1 |
49
+ TRUTH_TABLE
50
+ end
51
+ end
52
+ end
53
+ end
@@ -4,38 +4,25 @@ module Logicuit
4
4
  module Circuits
5
5
  module Sequential
6
6
  # D Flip-Flop
7
- #
8
- # (D)--| |--(Q)
9
- # |DFF|
10
- # (CK)-|> |
11
- #
12
- class DFlipFlop
13
- def initialize(d = 0) # rubocop:disable Naming/MethodParameterName
14
- Signals::Clock.on_tick << self
7
+ class DFlipFlop < Base
8
+ tag :DFF
15
9
 
16
- @d = d.is_a?(Signals::Signal) ? d : Signals::Signal.new(d == 1)
10
+ diagram <<~DIAGRAM
11
+ (D)--| |--(Q)
12
+ |DFF|
13
+ (CK)-|> |
14
+ DIAGRAM
17
15
 
18
- @q = Signals::Signal.new(false)
19
- evaluate
20
- end
16
+ define_inputs :d, clock: :ck
21
17
 
22
- attr_reader :d, :q
18
+ define_outputs q: ->(d) { d }
23
19
 
24
- def evaluate
25
- if d.current
26
- q.on
27
- else
28
- q.off
29
- end
30
- end
31
-
32
- def to_s
33
- <<~CIRCUIT
34
- (#{d})--| |--(#{q})
35
- |DFF|
36
- (CK)-|> |
37
- CIRCUIT
38
- end
20
+ truth_table <<~TRUTH_TABLE
21
+ | CK | D | Q |
22
+ | -- | - | - |
23
+ | ^ | 0 | 0 |
24
+ | ^ | 1 | 1 |
25
+ TRUTH_TABLE
39
26
  end
40
27
  end
41
28
  end
@@ -4,40 +4,37 @@ module Logicuit
4
4
  module Circuits
5
5
  module SystemLevel
6
6
  # 1 bit CPU
7
- #
8
- # +-(Y)-|NOT|-(A)-+
9
- # | |
10
- # +-(D)-| |-(Q)-+
11
- # |DFF|
12
- # (CK)-|> |
13
- #
14
- class OneBitCpu
15
- def initialize
16
- @dff = Sequential::DFlipFlop.new
17
- @not = Gates::Not.new
18
- @dff.q >> @not.a
19
- @not.y >> @dff.d
20
- end
7
+ class OneBitCpu < Base
8
+ tag :ONE_BIT_CPU
21
9
 
22
- def to_s
23
- <<~CIRCUIT
24
- +-(#{@not.y})-|NOT|-(#{@not.a})-+
25
- | |
26
- +-(#{@dff.d})-| |-(#{@dff.q})-+
10
+ diagram <<~DIAGRAM
11
+ +-------------+
12
+ | |
13
+ +-|NOT|-| |-+-(Y)
27
14
  |DFF|
28
15
  (CK)-|> |
29
- CIRCUIT
30
- end
16
+ DIAGRAM
17
+
18
+ define_inputs clock: :ck
19
+
20
+ define_outputs :y
31
21
 
32
- def self.run
33
- obc = new
34
- loop do
35
- system("clear")
36
- puts obc
37
- sleep 1
38
- Signals::Clock.tick
39
- end
22
+ assembling do |y|
23
+ dff = Sequential::DFlipFlop.new
24
+ not_gate = Gates::Not.new
25
+
26
+ dff.q >> not_gate.a
27
+ not_gate.y >> dff.d
28
+
29
+ dff.q >> y
40
30
  end
31
+
32
+ truth_table <<~TRUTH_TABLE
33
+ | CK | prev Y | Y |
34
+ | -- | ------ | - |
35
+ | ^ | 0 | 1 |
36
+ | ^ | 1 | 0 |
37
+ TRUTH_TABLE
41
38
  end
42
39
  end
43
40
  end
@@ -4,9 +4,7 @@ module Logicuit
4
4
  module Gates
5
5
  # AND gate
6
6
  class And < Base
7
- define_inputs :a, :b
8
-
9
- define_outputs y: ->(a, b) { a && b }
7
+ tag :AND
10
8
 
11
9
  diagram <<~DIAGRAM
12
10
  (A)-|
@@ -14,6 +12,10 @@ module Logicuit
14
12
  (B)-|
15
13
  DIAGRAM
16
14
 
15
+ define_inputs :a, :b
16
+
17
+ define_outputs y: ->(a, b) { a && b }
18
+
17
19
  truth_table <<~TRUTH_TABLE
18
20
  | A | B | Y |
19
21
  | - | - | - |
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Gates
5
+ # NAND gate
6
+ class Nand < Base
7
+ tag :NAND
8
+
9
+ diagram <<~DIAGRAM
10
+ (A)-|
11
+ |NAND|-(Y)
12
+ (B)-|
13
+ DIAGRAM
14
+
15
+ define_inputs :a, :b
16
+
17
+ define_outputs y: ->(a, b) { !(a && b) }
18
+
19
+ truth_table <<~TRUTH_TABLE
20
+ | A | B | Y |
21
+ | - | - | - |
22
+ | 0 | 0 | 1 |
23
+ | 1 | 0 | 1 |
24
+ | 0 | 1 | 1 |
25
+ | 1 | 1 | 0 |
26
+ TRUTH_TABLE
27
+ end
28
+ end
29
+ end
@@ -4,14 +4,16 @@ module Logicuit
4
4
  module Gates
5
5
  # NOT gate
6
6
  class Not < Base
7
- define_inputs :a
8
-
9
- define_outputs y: ->(a) { !a } # rubocop:disable Style/SymbolProc
7
+ tag :NOT
10
8
 
11
9
  diagram <<~DIAGRAM
12
10
  (A)-|NOT|-(Y)
13
11
  DIAGRAM
14
12
 
13
+ define_inputs :a
14
+
15
+ define_outputs y: ->(a) { !a } # rubocop:disable Style/SymbolProc
16
+
15
17
  truth_table <<~TRUTH_TABLE
16
18
  | A | Y |
17
19
  | - | - |
@@ -4,9 +4,7 @@ module Logicuit
4
4
  module Gates
5
5
  # OR gate
6
6
  class Or < Base
7
- define_inputs :a, :b
8
-
9
- define_outputs y: ->(a, b) { a || b }
7
+ tag :OR
10
8
 
11
9
  diagram <<~DIAGRAM
12
10
  (A)-|
@@ -14,6 +12,10 @@ module Logicuit
14
12
  (B)-|
15
13
  DIAGRAM
16
14
 
15
+ define_inputs :a, :b
16
+
17
+ define_outputs y: ->(a, b) { a || b }
18
+
17
19
  truth_table <<~TRUTH_TABLE
18
20
  | A | B | Y |
19
21
  | - | - | - |
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Gates
5
+ # XOR gate
6
+ class Xor < Base
7
+ tag :XOR
8
+
9
+ diagram <<~DIAGRAM
10
+ (A)-|
11
+ |XOR|-(Y)
12
+ (B)-|
13
+ DIAGRAM
14
+
15
+ define_inputs :a, :b
16
+
17
+ define_outputs y: ->(a, b) { (a && !b) || (!a && b) }
18
+
19
+ truth_table <<~TRUTH_TABLE
20
+ | A | B | Y |
21
+ | - | - | - |
22
+ | 0 | 0 | 0 |
23
+ | 1 | 0 | 1 |
24
+ | 0 | 1 | 1 |
25
+ | 1 | 1 | 0 |
26
+ TRUTH_TABLE
27
+ end
28
+ end
29
+ end
@@ -6,11 +6,13 @@ module Logicuit
6
6
  class Clock
7
7
  def initialize
8
8
  @on_tick = []
9
+ @tick_count = 0
9
10
  end
10
11
 
11
- attr_reader :on_tick
12
+ attr_reader :on_tick, :tick_count
12
13
 
13
14
  def tick
15
+ @tick_count += 1
14
16
  @on_tick.each(&:evaluate)
15
17
  end
16
18
 
@@ -25,6 +27,10 @@ module Logicuit
25
27
  def self.tick
26
28
  instance.tick
27
29
  end
30
+
31
+ def self.tick_count
32
+ instance.tick_count
33
+ end
28
34
  end
29
35
  end
30
36
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Logicuit
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
data/lib/logicuit.rb CHANGED
@@ -5,8 +5,12 @@ require_relative "logicuit/base"
5
5
  require_relative "logicuit/gates/and"
6
6
  require_relative "logicuit/gates/or"
7
7
  require_relative "logicuit/gates/not"
8
+ require_relative "logicuit/gates/nand"
9
+ require_relative "logicuit/gates/xor"
8
10
  require_relative "logicuit/signals/signal"
9
11
  require_relative "logicuit/signals/clock"
10
12
  require_relative "logicuit/circuits/sequential/d_flip_flop"
11
13
  require_relative "logicuit/circuits/combinational/multiplexer2to1"
14
+ require_relative "logicuit/circuits/combinational/multiplexer4to1"
15
+ require_relative "logicuit/circuits/combinational/half_adder"
12
16
  require_relative "logicuit/circuits/system_level/one_bit_cpu"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logicuit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koji NAKAMURA
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-09 00:00:00.000000000 Z
10
+ date: 2025-03-15 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: logi(c cir)cuit -> logicuit
13
13
  email:
@@ -24,11 +24,14 @@ files:
24
24
  - lib/logicuit/base.rb
25
25
  - lib/logicuit/circuits/combinational/half_adder.rb
26
26
  - lib/logicuit/circuits/combinational/multiplexer2to1.rb
27
+ - lib/logicuit/circuits/combinational/multiplexer4to1.rb
27
28
  - lib/logicuit/circuits/sequential/d_flip_flop.rb
28
29
  - lib/logicuit/circuits/system_level/one_bit_cpu.rb
29
30
  - lib/logicuit/gates/and.rb
31
+ - lib/logicuit/gates/nand.rb
30
32
  - lib/logicuit/gates/not.rb
31
33
  - lib/logicuit/gates/or.rb
34
+ - lib/logicuit/gates/xor.rb
32
35
  - lib/logicuit/signals/clock.rb
33
36
  - lib/logicuit/signals/signal.rb
34
37
  - lib/logicuit/version.rb