logicuit 0.1.0 → 0.1.1

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: 0dad7e6a6e7b924c46183e5ef4bfc6e4647fee1d8bc64b10792569664a6c4b80
4
- data.tar.gz: a5c316448fc8b3019488131b53ad8115e11da5151fddc6f1d40d821f2b9862b8
3
+ metadata.gz: 26c6eb8e9b1845c097a5e64604ca2c71632c8d0f98f19e0df1d642e57ad6ee7a
4
+ data.tar.gz: 9e470fdd05e968fd46829a2df9a57015f40cd9460a2cef769e210d1e720c9144
5
5
  SHA512:
6
- metadata.gz: e5b4c0ea5bf5922c99a6ed7ee0d1a0eafe388c481bd1c54995645f01498adb9979c8967e1f70bcbbc7327b9c6ed2b43bd06fef326b25b73bd24beca3705a0fcc
7
- data.tar.gz: f37bec9789e8292558fd8cf58d4aa29a1765ba6d82826315afe1f4d11a24d2bb99d92ba88bdd52f52ff0e74c160ca552ebc99067f7c20151c127f7f756eee593
6
+ metadata.gz: beb747fa8ea167b01d3a765564f1ffcf546072afe315e8c8a9bb37601409204b002011d68a737302090e5f2808c54e75fa80de87ea4d02e66037d2c2a8792b74
7
+ data.tar.gz: dc144486811fc58d4ba1cda48f6fce95ed7776e7b3b059950388d3e41d8459c90e3d4500c4e0b97e9d9158654952fc1041e801c24a9b13c690f8d7c238bb5647
data/.rubocop.yml CHANGED
@@ -1,8 +1,13 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 3.1
3
+ NewCops: disable
3
4
 
4
5
  Style/StringLiterals:
5
6
  EnforcedStyle: double_quotes
6
7
 
7
8
  Style/StringLiteralsInInterpolation:
8
9
  EnforcedStyle: double_quotes
10
+
11
+ require:
12
+ - rubocop-minitest
13
+ - rubocop-rake
data/README.md CHANGED
@@ -19,14 +19,44 @@ gem install logicuit
19
19
  ## Usage
20
20
 
21
21
  ```
22
- Logicuit::And.new(1, 1).signal # [1]
23
- Logicuit::And.new(1, 0).signal # [0]
24
- Logicuit::And.new(0, 1).signal # [0]
25
- Logicuit::And.new(0, 0).signal # [0]
22
+ require "logicuit"
23
+
24
+ # 1 bit CPU
25
+ #
26
+ # +-(Y)-|NOT|-(A)-+
27
+ # | |
28
+ # +-(D)-| |-(Q)-+
29
+ # |DFF|
30
+ # (CK)-|> |
31
+ #
32
+ class OneBitCpu
33
+ def initialize
34
+ @dff = Logicuit::Circuits::Sequential::DFlipFlop.new
35
+ @not = Logicuit::Gates::Not.new
36
+ @dff.q >> @not.a
37
+ @not.y >> @dff.d
38
+ end
39
+
40
+ def to_s
41
+ <<~CIRCUIT
42
+ +-(#{@not.y})-|NOT|-(#{@not.a})-+
43
+ | |
44
+ +-(#{@dff.d})-| |-(#{@dff.q})-+
45
+ |DFF|
46
+ (CK)-|> |
47
+ CIRCUIT
48
+ end
49
+ end
50
+
51
+ obc = OneBitCpu.new
52
+ loop do
53
+ system("clear")
54
+ puts obc
55
+ sleep 1
56
+ Logicuit::Signals::Clock.tick
57
+ end
26
58
  ```
27
59
 
28
- This is all for now :)
29
-
30
60
  ## Development
31
61
 
32
62
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TODO: implement the HalfAdder class
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Circuits
5
+ module Sequential
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
15
+
16
+ @d = d.is_a?(Signals::Signal) ? d : Signals::Signal.new(d == 1)
17
+
18
+ @q = Signals::Signal.new(false)
19
+ evaluate
20
+ end
21
+
22
+ attr_reader :d, :q
23
+
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
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Circuits
5
+ module SystemLevel
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
21
+
22
+ def to_s
23
+ <<~CIRCUIT
24
+ +-(#{@not.y})-|NOT|-(#{@not.a})-+
25
+ | |
26
+ +-(#{@dff.d})-| |-(#{@dff.q})-+
27
+ |DFF|
28
+ (CK)-|> |
29
+ CIRCUIT
30
+ end
31
+
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
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Gates
5
+ # AND gate
6
+ #
7
+ # (A)-|
8
+ # |AND|-(Y)
9
+ # (B)-|
10
+ #
11
+ class And
12
+ def initialize(a = 0, b = 0) # rubocop:disable Naming/MethodParameterName
13
+ @a = Signals::Signal.new(a == 1)
14
+ @a.on_change << self
15
+
16
+ @b = Signals::Signal.new(b == 1)
17
+ @b.on_change << self
18
+
19
+ @y = Signals::Signal.new(false)
20
+ evaluate
21
+ end
22
+
23
+ attr_reader :a, :b, :y
24
+
25
+ def evaluate
26
+ a.current && b.current ? y.on : y.off
27
+ end
28
+
29
+ def to_s
30
+ <<~CIRCUIT
31
+ (#{a})-|
32
+ |AND|-(#{y})
33
+ (#{b})-|
34
+ CIRCUIT
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Gates
5
+ # NOT gate
6
+ #
7
+ # (A)-|NOT|-(Y)
8
+ #
9
+ class Not
10
+ def initialize(a = 0) # rubocop:disable Naming/MethodParameterName
11
+ @a = Signals::Signal.new(a == 1)
12
+ @a.on_change << self
13
+
14
+ @y = Signals::Signal.new(false)
15
+ evaluate
16
+ end
17
+
18
+ attr_reader :a, :y
19
+
20
+ def evaluate
21
+ a.current ? y.off : y.on
22
+ end
23
+
24
+ def to_s
25
+ <<~CIRCUIT
26
+ (#{a})-|NOT|-(#{y})
27
+ CIRCUIT
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Gates
5
+ # OR gate
6
+ #
7
+ # (A)-|
8
+ # |OR|-(Y)
9
+ # (B)-|
10
+ #
11
+ class Or
12
+ def initialize(a = 0, b = 0) # rubocop:disable Naming/MethodParameterName
13
+ @a = Signals::Signal.new(a == 1)
14
+ @a.on_change << self
15
+
16
+ @b = Signals::Signal.new(b == 1)
17
+ @b.on_change << self
18
+
19
+ @y = Signals::Signal.new(false)
20
+ evaluate
21
+ end
22
+
23
+ attr_reader :a, :b, :y
24
+
25
+ def evaluate
26
+ a.current || b.current ? y.on : y.off
27
+ end
28
+
29
+ def to_s
30
+ <<~CIRCUIT
31
+ (#{a})-|
32
+ |OR|-(#{y})
33
+ (#{b})-|
34
+ CIRCUIT
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Signals
5
+ # Clock
6
+ class Clock
7
+ def initialize
8
+ @on_tick = []
9
+ end
10
+
11
+ attr_reader :on_tick
12
+
13
+ def tick
14
+ @on_tick.each(&:evaluate)
15
+ end
16
+
17
+ def self.instance
18
+ @instance ||= new
19
+ end
20
+
21
+ def self.on_tick
22
+ instance.on_tick
23
+ end
24
+
25
+ def self.tick
26
+ instance.tick
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Logicuit
4
+ module Signals
5
+ # Signal
6
+ class Signal
7
+ def initialize(current = false) # rubocop:disable Style/OptionalBooleanParameter
8
+ @current = current
9
+ @connected_by = nil
10
+ @on_change = []
11
+ end
12
+
13
+ attr_reader :current, :on_change
14
+ attr_accessor :connected_by
15
+
16
+ def on
17
+ changed = @current.!
18
+ @current = true
19
+ @on_change.each(&:evaluate) if changed
20
+ end
21
+
22
+ def off
23
+ changed = @current
24
+ @current = false
25
+ @on_change.each(&:evaluate) if changed
26
+ end
27
+
28
+ def toggle
29
+ @current ? off : on
30
+ end
31
+
32
+ def connects_to(other)
33
+ other.connected_by = self
34
+ other.evaluate
35
+ on_change << other
36
+ end
37
+ alias >> connects_to
38
+
39
+ def evaluate
40
+ return if @connected_by.nil?
41
+
42
+ @connected_by.current ? on : off
43
+ end
44
+
45
+ def to_s
46
+ current ? "1" : "0"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Logicuit
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/logicuit.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "logicuit/version"
4
- require_relative "logicuit/and"
4
+ require_relative "logicuit/gates/and"
5
+ require_relative "logicuit/gates/or"
6
+ require_relative "logicuit/gates/not"
7
+ require_relative "logicuit/signals/signal"
8
+ require_relative "logicuit/signals/clock"
9
+ require_relative "logicuit/circuits/sequential/d_flip_flop"
10
+ 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.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koji NAKAMURA
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-02-05 00:00:00.000000000 Z
10
+ date: 2025-02-26 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: logi(c cir)cuit -> logicuit
13
13
  email:
@@ -21,7 +21,14 @@ files:
21
21
  - README.md
22
22
  - Rakefile
23
23
  - lib/logicuit.rb
24
- - lib/logicuit/and.rb
24
+ - lib/logicuit/circuits/combinational/half_adder.rb
25
+ - lib/logicuit/circuits/sequential/d_flip_flop.rb
26
+ - lib/logicuit/circuits/system_level/one_bit_cpu.rb
27
+ - lib/logicuit/gates/and.rb
28
+ - lib/logicuit/gates/not.rb
29
+ - lib/logicuit/gates/or.rb
30
+ - lib/logicuit/signals/clock.rb
31
+ - lib/logicuit/signals/signal.rb
25
32
  - lib/logicuit/version.rb
26
33
  - sig/logicuit.rbs
27
34
  homepage: https://github.com/kozy4324/logicuit
data/lib/logicuit/and.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Logicuit
4
- # AND circuit
5
- class And
6
- def initialize(a, b) # rubocop:disable Naming/MethodParameterName
7
- @a = a
8
- @b = b
9
- end
10
-
11
- def signal
12
- [@a == 1 && @b == 1 ? 1 : 0]
13
- end
14
- end
15
- end