logicuit 0.2.0 → 0.3.0
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 +4 -4
- data/.rubocop.yml +12 -0
- data/README.md +300 -18
- data/lib/logicuit/array_as_signal_group.rb +13 -0
- data/lib/logicuit/circuits/combinational/full_adder.rb +28 -30
- data/lib/logicuit/circuits/combinational/full_adder_4bit.rb +13 -28
- data/lib/logicuit/circuits/combinational/half_adder.rb +8 -10
- data/lib/logicuit/circuits/combinational/multiplexer_2to1.rb +7 -9
- data/lib/logicuit/circuits/combinational/multiplexer_4to1.rb +11 -15
- data/lib/logicuit/circuits/sequential/d_flip_flop.rb +3 -5
- data/lib/logicuit/circuits/{system_level/one_bit_cpu2.rb → sequential/one_bit_cpu.rb} +13 -15
- data/lib/logicuit/circuits/sequential/program_counter.rb +6 -8
- data/lib/logicuit/circuits/sequential/register_4bit.rb +12 -14
- data/lib/logicuit/circuits/{system_level/cpu_td4.rb → td4/cpu.rb} +34 -59
- data/lib/logicuit/circuits/{combinational → td4}/decoder.rb +9 -11
- data/lib/logicuit/circuits/{rom/timer.rb → td4/rom.rb} +7 -5
- data/lib/logicuit/{base.rb → dsl.rb} +40 -107
- data/lib/logicuit/gates/and.rb +5 -7
- data/lib/logicuit/gates/nand.rb +5 -7
- data/lib/logicuit/gates/not.rb +3 -5
- data/lib/logicuit/gates/or.rb +5 -7
- data/lib/logicuit/gates/xor.rb +5 -7
- data/lib/logicuit/runner.rb +45 -0
- data/lib/logicuit/signals/clock.rb +18 -15
- data/lib/logicuit/signals/signal.rb +29 -24
- data/lib/logicuit/signals/signal_group.rb +26 -0
- data/lib/logicuit/version.rb +1 -1
- data/lib/logicuit.rb +8 -6
- metadata +10 -8
- data/lib/logicuit/circuits/system_level/one_bit_cpu.rb +0 -41
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Logicuit module
|
|
4
|
+
module Logicuit
|
|
5
|
+
def self.run(circuit, hz: 1, noclear: false)
|
|
6
|
+
render = lambda {
|
|
7
|
+
system("clear") unless noclear
|
|
8
|
+
puts circuit
|
|
9
|
+
puts
|
|
10
|
+
puts "tick: #{Signals::Clock.tick_count}" if circuit.clock
|
|
11
|
+
puts "input: #{circuit.input_targets.join ","}?" if circuit.input_targets.any?
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if circuit.clock && hz.nonzero?
|
|
15
|
+
Thread.new do
|
|
16
|
+
loop do
|
|
17
|
+
render.call
|
|
18
|
+
sleep 1.0 / hz
|
|
19
|
+
Signals::Clock.tick
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
render.call
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
while (input = gets.chomp)
|
|
27
|
+
key = input.to_sym
|
|
28
|
+
unless circuit.respond_to? key
|
|
29
|
+
if circuit.clock && hz.zero?
|
|
30
|
+
Signals::Clock.tick
|
|
31
|
+
render.call
|
|
32
|
+
end
|
|
33
|
+
next
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
signal = circuit.send(key)
|
|
37
|
+
if signal.current
|
|
38
|
+
signal.off
|
|
39
|
+
else
|
|
40
|
+
signal.on
|
|
41
|
+
end
|
|
42
|
+
render.call
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -5,36 +5,39 @@ module Logicuit
|
|
|
5
5
|
# Clock
|
|
6
6
|
class Clock
|
|
7
7
|
def initialize
|
|
8
|
-
@
|
|
8
|
+
@downstreams = []
|
|
9
9
|
@tick_count = 0
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
attr_reader :
|
|
12
|
+
attr_reader :downstreams, :tick_count
|
|
13
13
|
|
|
14
14
|
def tick
|
|
15
15
|
@tick_count += 1
|
|
16
16
|
# Call the `evaluate` method for all components.
|
|
17
|
-
# However, the input argument values should be bound to the values at the time `
|
|
18
|
-
@
|
|
17
|
+
# However, the input argument values should be bound to the values at the time `tick` is called.
|
|
18
|
+
@downstreams.map do |component|
|
|
19
19
|
args = component.input_targets.map { |input| component.instance_variable_get("@#{input}").current }
|
|
20
20
|
-> { component.evaluate(*args) }
|
|
21
21
|
end.each(&:call)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
class << self
|
|
25
|
+
def instance
|
|
26
|
+
@instance ||= new
|
|
27
|
+
end
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
def connects_to(component)
|
|
30
|
+
instance.downstreams << component
|
|
31
|
+
end
|
|
32
|
+
alias >> connects_to
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
def tick
|
|
35
|
+
instance.tick
|
|
36
|
+
end
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
def tick_count
|
|
39
|
+
instance.tick_count
|
|
40
|
+
end
|
|
38
41
|
end
|
|
39
42
|
end
|
|
40
43
|
end
|
|
@@ -4,49 +4,54 @@ module Logicuit
|
|
|
4
4
|
module Signals
|
|
5
5
|
# Signal
|
|
6
6
|
class Signal
|
|
7
|
-
def initialize(current = false)
|
|
7
|
+
def initialize(current = false)
|
|
8
8
|
@current = current
|
|
9
|
-
@
|
|
10
|
-
@on_change = []
|
|
9
|
+
@downstreams = []
|
|
11
10
|
end
|
|
12
11
|
|
|
13
|
-
attr_reader :current
|
|
14
|
-
attr_accessor :connected_by
|
|
12
|
+
attr_reader :current
|
|
15
13
|
|
|
16
14
|
def on
|
|
17
|
-
|
|
15
|
+
return if @current
|
|
16
|
+
|
|
18
17
|
@current = true
|
|
19
|
-
|
|
20
|
-
self
|
|
18
|
+
propagate_current
|
|
21
19
|
end
|
|
22
20
|
|
|
23
21
|
def off
|
|
24
|
-
|
|
25
|
-
@current = false
|
|
26
|
-
@on_change.each(&:evaluate) if changed
|
|
27
|
-
self
|
|
28
|
-
end
|
|
22
|
+
return unless @current
|
|
29
23
|
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
@current = false
|
|
25
|
+
propagate_current
|
|
32
26
|
end
|
|
33
27
|
|
|
34
28
|
def connects_to(other)
|
|
35
|
-
other.
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
if other.is_a? Array
|
|
30
|
+
@downstreams.concat(other)
|
|
31
|
+
elsif other.is_a? Signals::SignalGroup
|
|
32
|
+
@downstreams.concat(other.signals)
|
|
33
|
+
else
|
|
34
|
+
@downstreams << other
|
|
35
|
+
end
|
|
36
|
+
propagate_current
|
|
38
37
|
end
|
|
39
38
|
alias >> connects_to
|
|
40
39
|
|
|
41
|
-
def evaluate
|
|
42
|
-
return if @connected_by.nil?
|
|
43
|
-
|
|
44
|
-
@connected_by.current ? on : off
|
|
45
|
-
end
|
|
46
|
-
|
|
47
40
|
def to_s
|
|
48
41
|
current ? "1" : "0"
|
|
49
42
|
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def propagate_current
|
|
47
|
+
@downstreams.each do |downstream|
|
|
48
|
+
if downstream.is_a?(Signal)
|
|
49
|
+
current ? downstream.on : downstream.off
|
|
50
|
+
elsif downstream.respond_to?(:evaluate)
|
|
51
|
+
downstream.evaluate
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
50
55
|
end
|
|
51
56
|
end
|
|
52
57
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Logicuit
|
|
4
|
+
module Signals
|
|
5
|
+
# Signal Group
|
|
6
|
+
class SignalGroup
|
|
7
|
+
def initialize(*signals)
|
|
8
|
+
@signals = signals
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def signals
|
|
12
|
+
@signals.dup
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def connects_to(others)
|
|
16
|
+
others = others.signals if others.is_a?(SignalGroup)
|
|
17
|
+
@signals.zip(others).each { _1 >> _2 unless _1.nil? || _2.nil? }
|
|
18
|
+
end
|
|
19
|
+
alias >> connects_to
|
|
20
|
+
|
|
21
|
+
def to_s
|
|
22
|
+
signals.map { it.current ? "1" : "0" }.join
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/logicuit/version.rb
CHANGED
data/lib/logicuit.rb
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "logicuit/version"
|
|
4
|
-
require_relative "logicuit/
|
|
4
|
+
require_relative "logicuit/dsl"
|
|
5
|
+
require_relative "logicuit/array_as_signal_group"
|
|
6
|
+
require_relative "logicuit/runner"
|
|
5
7
|
require_relative "logicuit/gates/and"
|
|
6
8
|
require_relative "logicuit/gates/or"
|
|
7
9
|
require_relative "logicuit/gates/not"
|
|
8
10
|
require_relative "logicuit/gates/nand"
|
|
9
11
|
require_relative "logicuit/gates/xor"
|
|
10
12
|
require_relative "logicuit/signals/signal"
|
|
13
|
+
require_relative "logicuit/signals/signal_group"
|
|
11
14
|
require_relative "logicuit/signals/clock"
|
|
12
15
|
require_relative "logicuit/circuits/combinational/multiplexer_2to1"
|
|
13
16
|
require_relative "logicuit/circuits/combinational/multiplexer_4to1"
|
|
14
17
|
require_relative "logicuit/circuits/combinational/half_adder"
|
|
15
18
|
require_relative "logicuit/circuits/combinational/full_adder"
|
|
16
19
|
require_relative "logicuit/circuits/combinational/full_adder_4bit"
|
|
17
|
-
require_relative "logicuit/circuits/combinational/decoder"
|
|
18
|
-
require_relative "logicuit/circuits/rom/timer"
|
|
19
20
|
require_relative "logicuit/circuits/sequential/d_flip_flop"
|
|
20
21
|
require_relative "logicuit/circuits/sequential/register_4bit"
|
|
21
22
|
require_relative "logicuit/circuits/sequential/program_counter"
|
|
22
|
-
require_relative "logicuit/circuits/
|
|
23
|
-
require_relative "logicuit/circuits/
|
|
24
|
-
require_relative "logicuit/circuits/
|
|
23
|
+
require_relative "logicuit/circuits/sequential/one_bit_cpu"
|
|
24
|
+
require_relative "logicuit/circuits/td4/cpu"
|
|
25
|
+
require_relative "logicuit/circuits/td4/decoder"
|
|
26
|
+
require_relative "logicuit/circuits/td4/rom"
|
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.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Koji NAKAMURA
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-04-
|
|
10
|
+
date: 2025-04-19 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
12
|
description: logi(c cir)cuit -> logicuit
|
|
13
13
|
email:
|
|
@@ -21,27 +21,29 @@ files:
|
|
|
21
21
|
- README.md
|
|
22
22
|
- Rakefile
|
|
23
23
|
- lib/logicuit.rb
|
|
24
|
-
- lib/logicuit/
|
|
25
|
-
- lib/logicuit/circuits/combinational/decoder.rb
|
|
24
|
+
- lib/logicuit/array_as_signal_group.rb
|
|
26
25
|
- lib/logicuit/circuits/combinational/full_adder.rb
|
|
27
26
|
- lib/logicuit/circuits/combinational/full_adder_4bit.rb
|
|
28
27
|
- lib/logicuit/circuits/combinational/half_adder.rb
|
|
29
28
|
- lib/logicuit/circuits/combinational/multiplexer_2to1.rb
|
|
30
29
|
- lib/logicuit/circuits/combinational/multiplexer_4to1.rb
|
|
31
|
-
- lib/logicuit/circuits/rom/timer.rb
|
|
32
30
|
- lib/logicuit/circuits/sequential/d_flip_flop.rb
|
|
31
|
+
- lib/logicuit/circuits/sequential/one_bit_cpu.rb
|
|
33
32
|
- lib/logicuit/circuits/sequential/program_counter.rb
|
|
34
33
|
- lib/logicuit/circuits/sequential/register_4bit.rb
|
|
35
|
-
- lib/logicuit/circuits/
|
|
36
|
-
- lib/logicuit/circuits/
|
|
37
|
-
- lib/logicuit/circuits/
|
|
34
|
+
- lib/logicuit/circuits/td4/cpu.rb
|
|
35
|
+
- lib/logicuit/circuits/td4/decoder.rb
|
|
36
|
+
- lib/logicuit/circuits/td4/rom.rb
|
|
37
|
+
- lib/logicuit/dsl.rb
|
|
38
38
|
- lib/logicuit/gates/and.rb
|
|
39
39
|
- lib/logicuit/gates/nand.rb
|
|
40
40
|
- lib/logicuit/gates/not.rb
|
|
41
41
|
- lib/logicuit/gates/or.rb
|
|
42
42
|
- lib/logicuit/gates/xor.rb
|
|
43
|
+
- lib/logicuit/runner.rb
|
|
43
44
|
- lib/logicuit/signals/clock.rb
|
|
44
45
|
- lib/logicuit/signals/signal.rb
|
|
46
|
+
- lib/logicuit/signals/signal_group.rb
|
|
45
47
|
- lib/logicuit/version.rb
|
|
46
48
|
- sig/logicuit.rbs
|
|
47
49
|
homepage: https://github.com/kozy4324/logicuit
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Logicuit
|
|
4
|
-
module Circuits
|
|
5
|
-
module SystemLevel
|
|
6
|
-
# 1 bit CPU
|
|
7
|
-
class OneBitCpu < Base
|
|
8
|
-
tag :ONE_BIT_CPU
|
|
9
|
-
|
|
10
|
-
diagram <<~DIAGRAM
|
|
11
|
-
+-------------+
|
|
12
|
-
| |
|
|
13
|
-
+-|NOT|-| |-+-(Y)
|
|
14
|
-
|DFF|
|
|
15
|
-
(CK)-|> |
|
|
16
|
-
DIAGRAM
|
|
17
|
-
|
|
18
|
-
define_inputs clock: :ck
|
|
19
|
-
|
|
20
|
-
define_outputs :y
|
|
21
|
-
|
|
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
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
truth_table <<~TRUTH_TABLE
|
|
33
|
-
| CK | prev Y | Y |
|
|
34
|
-
| -- | ------ | - |
|
|
35
|
-
| ^ | 0 | 1 |
|
|
36
|
-
| ^ | 1 | 0 |
|
|
37
|
-
TRUTH_TABLE
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|