rtl_circuit 0.7

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ee25e08cf291db2381c60746dd1d654d4931bd0742cdd12f1f85b55b4065f694
4
+ data.tar.gz: 6a39ac68ccf30ff37ab674dad83ff74686fe81d6e3cf6e1c8b1cca5d0d88c384
5
+ SHA512:
6
+ metadata.gz: c5af6786663be64b4ff0dff83e240732a48ba17e0980ae7585f7a8d8967f107a81cf106608049829330f6aa094fd777bf9c26543595501ee469b4015ed6eecd2
7
+ data.tar.gz: 6b633468fc83534bd1164ded8ed001154d378a37c4f37aecde60ec04b14c1ea5cdc762f21565f7291b09dd88eb070a89a7ed811a749a2463c10d905c0a815142
@@ -0,0 +1,136 @@
1
+ module RTL
2
+
3
+ class Circuit
4
+ attr_accessor :name
5
+ attr_accessor :iname
6
+ attr_accessor :ports
7
+ attr_accessor :components
8
+ attr_accessor :father
9
+ attr_accessor :signals
10
+ attr_accessor :properties
11
+
12
+ @@id=-1
13
+
14
+ def initialize name=nil
15
+ @name=name
16
+ @iname="#{name}_#{@@id+=1}"
17
+ @ports={in:[],out:[]}
18
+ @signals=[]
19
+ @components=[]
20
+ @properties={}
21
+ @color="cadetblue"
22
+ end
23
+
24
+ def add element
25
+ port=circuit=sig=element
26
+ case element
27
+ when Sig
28
+ @signals<< sig
29
+ sig.circuit=self
30
+ when Port
31
+ @ports[port.dir] << port
32
+ port.circuit=self
33
+ when Circuit
34
+ @components << circuit
35
+ circuit.father=self
36
+ else
37
+ raise "ERROR : when adding '#{element}'"
38
+ end
39
+ end
40
+
41
+ def port_named dir,name
42
+ @ports[dir].find{|p| p.name==name}
43
+ end
44
+
45
+ def port name
46
+ all=@ports[:in]+@ports[:out]
47
+ all.flatten.find{|p| p.name==name}
48
+ end
49
+
50
+ def component_named name
51
+ @components.find{|comp| comp.iname==name}
52
+ end
53
+
54
+ def inputs
55
+ @ports[:in]
56
+ end
57
+
58
+ def outputs
59
+ @ports[:out]
60
+ end
61
+
62
+ def wires
63
+ wires=[]
64
+ wires << inputs.map{|p| p.fanout}
65
+ wires << signals.map{|p| p.fanout}
66
+ wires << components.map{|comp| comp.outputs.map{|o| o.fanout}}
67
+ wires.flatten
68
+ end
69
+
70
+ def new_instance
71
+ @@clone_id||={}
72
+ @@clone_id[name]||=-1
73
+ @@clone_id[name]+=1
74
+ clone=Marshal.load(Marshal.dump(self))
75
+ clone.iname=self.name+"_#{@@clone_id[name]}"
76
+ clone
77
+ end
78
+
79
+ def make_lib
80
+ filename="#{name}.lib"
81
+ File.open(filename,'w') do |f|
82
+ f.puts Marshal.dump(self)
83
+ end
84
+ end
85
+
86
+ def to_dot
87
+ Printer.new.print self
88
+ end
89
+ end
90
+
91
+ class Port
92
+ attr_accessor :dir
93
+ attr_accessor :name
94
+ attr_accessor :circuit
95
+ attr_accessor :fanout
96
+ attr_accessor :properties
97
+ def initialize dir,name
98
+ @dir=dir
99
+ @name=name
100
+ @fanout=[]
101
+ @properties={}
102
+ end
103
+
104
+ def connect port
105
+ puts "connecting #{self.name}-> #{port.name}" if $verbose
106
+ @fanout << Wire.new(self,port)
107
+ end
108
+
109
+ def type=(t)
110
+ @properties[:type]=t
111
+ end
112
+
113
+ def type
114
+ @properties[:type]
115
+ end
116
+ end
117
+
118
+ class Sig < Port
119
+ def initialize name
120
+ super(:out,name)
121
+ end
122
+ end
123
+
124
+ class Wire
125
+ @@id=-1
126
+ attr_accessor :name
127
+ attr_accessor :source,:sink
128
+ attr_accessor :properties
129
+ def initialize source,sink
130
+ @name="w_#{@@id+=1}"
131
+ @source=source
132
+ @sink=sink
133
+ @properties={}
134
+ end
135
+ end
136
+ end
data/lib/rtl/code.rb ADDED
@@ -0,0 +1,47 @@
1
+ class Code
2
+
3
+ attr_accessor :indent,:lines
4
+
5
+ def initialize str=nil
6
+ @lines=[]
7
+ (@lines << str) if str
8
+ @indent=0
9
+ end
10
+
11
+ def <<(thing)
12
+ if (code=thing).is_a? Code
13
+ code.lines.each do |line|
14
+ @lines << " "*@indent+line.to_s
15
+ end
16
+ elsif thing.is_a? Array
17
+ thing.each do |kode|
18
+ @lines << kode
19
+ end
20
+ elsif thing.nil?
21
+ else
22
+ @lines << " "*@indent+thing.to_s
23
+ end
24
+ end
25
+
26
+ def finalize
27
+ return @lines.join("\n") if @lines.any?
28
+ ""
29
+ end
30
+
31
+ def newline
32
+ @lines << " "
33
+ end
34
+
35
+ def save_as filename,verbose=true
36
+ str=self.finalize
37
+ File.open(filename,'w'){|f| f.puts(str)}
38
+ puts "code saved as : #{filename}" if verbose
39
+ return filename
40
+ end
41
+
42
+ def size
43
+ @lines.size
44
+ end
45
+
46
+
47
+ end
@@ -0,0 +1,85 @@
1
+ require_relative "circuit"
2
+
3
+ module RTL
4
+
5
+ class UnaryGate < Circuit
6
+ def initialize
7
+ name=self.class.to_s.split("::").last
8
+ super(name)
9
+ add Port.new(:in,"i")
10
+ add Port.new(:out,"f")
11
+ end
12
+ end
13
+
14
+ class BinaryGate < Circuit
15
+ def initialize
16
+ name=self.class.to_s.split("::").last
17
+ super(name)
18
+ add Port.new(:in,"i1")
19
+ add Port.new(:in,"i2")
20
+ add Port.new(:out,"f")
21
+ end
22
+ end
23
+
24
+ class Not < UnaryGate
25
+ end
26
+
27
+ class Or < BinaryGate
28
+ end
29
+
30
+ class And < BinaryGate
31
+ end
32
+
33
+ class Nand < BinaryGate
34
+ end
35
+
36
+ class Nor < BinaryGate
37
+ end
38
+
39
+ class Xor < BinaryGate
40
+ end
41
+
42
+ class Reg < Circuit
43
+ def initialize
44
+ name="Reg"
45
+ super(name)
46
+ add Port.new(:in ,"d")
47
+ add Port.new(:out,"q")
48
+ @color="darkorange"
49
+ end
50
+ end
51
+
52
+ class Mux < Circuit
53
+ attr_accessor :arity
54
+ def initialize
55
+ name="Mux"
56
+ super(name)
57
+ @arity=0
58
+ add Port.new("i0",:in)
59
+ add Port.new("i1",:in)
60
+ add Port.new("sel",:in)
61
+ add Port.new("f",:out)
62
+ end
63
+
64
+ def add port
65
+ @arity+=1
66
+ super port
67
+ end
68
+ end
69
+
70
+ class Add < BinaryGate
71
+ end
72
+
73
+ class Sub < BinaryGate
74
+ end
75
+
76
+ class Mul < BinaryGate
77
+ end
78
+
79
+ class Div < BinaryGate
80
+ end
81
+
82
+ class Rem < BinaryGate
83
+ end
84
+
85
+ end
@@ -0,0 +1,82 @@
1
+ require_relative 'code'
2
+
3
+ module RTL
4
+
5
+ class Printer
6
+
7
+ def print circuit
8
+ dot=Code.new
9
+ dot << "digraph G {"
10
+ dot.indent=2
11
+ dot << "graph [rankdir = LR];"
12
+ circuit.components.each do |comp|
13
+ inputs_dot ="{"+comp.ports[:in].collect{|e| "<#{e.name}>#{e.name}"}.join("|")+"}"
14
+ outputs_dot="{"+comp.ports[:out].collect{|e| "<#{e.name}>#{e.name}"}.join("|")+"}"
15
+ p color=circuit.color
16
+ dot << "#{comp.iname}[ shape=record; style=filled ; color=#{color} ; label=\"{ #{inputs_dot}| #{comp.name} | #{outputs_dot} }\"];"
17
+ end
18
+ circuit.ports[:in].each do |p|
19
+ dot << "#{p.name}[shape=cds label=\"#{p.name}\"];"
20
+ end
21
+ circuit.ports[:out].each do |p|
22
+ dot << "#{p.name}[shape=cds label=\"#{p.name}\"];"
23
+ end
24
+ circuit.signals.each do |sig|
25
+ dot << "#{sig.name}[shape=point ; xlabel=\"#{sig.name}\"]; /* sig */"
26
+ end
27
+ circuit.ports[:in].each do |source|
28
+ source.fanout.each do |wire|
29
+ source_name=source.name
30
+ sink=wire.sink
31
+ sink_name=sink.name
32
+ if sink.circuit!=circuit
33
+ sink_name="#{sink.circuit.iname}:#{sink_name}"
34
+ end
35
+ wire_name=wire.name if $verbose
36
+ dot << "#{source_name} -> #{sink_name} [label=\"#{wire_name}\"]/* pin */"
37
+ end
38
+ end
39
+ circuit.signals.each do |sig|
40
+ sig.fanout.each do |wire|
41
+ source_name=sig.name
42
+ sink =wire.sink
43
+ sink_name=sink.name
44
+ if sink.circuit!=circuit
45
+ sink_name="#{sink.circuit.iname}:#{sink_name}"
46
+ end
47
+ wire_name=wire.name if $verbose
48
+ dot << "#{source_name} -> #{sink_name} [label=\"#{wire_name}\"] /* sig */"
49
+ end
50
+ end
51
+
52
+ circuit.components.each do |c|
53
+ c.ports[:out].each do |p|
54
+ p.fanout.each do |wire| #pin
55
+ pout=wire.sink
56
+ c=pout.circuit==circuit ? "#{pout.name}" : "#{pout.circuit.iname}:#{pout.name}"
57
+ if c!=p.circuit.iname+":"+p.name
58
+ wire_name=wire.name if $verbose
59
+ dot << "#{p.circuit.iname}:#{p.name} -> #{c}[label=\"#{wire_name}\"]; /* tag3 */"
60
+ end
61
+ end
62
+ end
63
+ end
64
+ dot.indent=0
65
+ dot << "}"
66
+ dot.save_as "#{circuit.name}.dot",verbose=false
67
+ end
68
+
69
+ def print_svg circuit
70
+ svg=Code.new
71
+ svg << "{"
72
+ svg.indent=2
73
+ svg << "creator: \"RTL::printer version #{version}\","
74
+ svg << "modules: "
75
+ svg.indent=4
76
+ svg.indent=2
77
+ svg.indent=0
78
+ svg << "}"
79
+ svg
80
+ end
81
+ end
82
+ end
data/lib/rtl.rb ADDED
@@ -0,0 +1,8 @@
1
+ require_relative "./rtl/circuit"
2
+ require_relative "./rtl/library"
3
+ require_relative "./rtl/printer"
4
+ require_relative "./rtl/placer"
5
+ require_relative "./rtl/json_parser"
6
+
7
+ module RTL
8
+ end
@@ -0,0 +1,4 @@
1
+ require_relative "../../lib/rtl"
2
+ puts "testing json".center(40,'=')
3
+ g=Parser.new.parse "ex_1.json"
4
+ g.print_info
@@ -0,0 +1,20 @@
1
+ #require "rtl_circuit"
2
+ require_relative "../../../rtl/lib/rtl.rb"
3
+
4
+ include RTL
5
+
6
+ top=Circuit.new("top_0")
7
+ top.add a=Port.new(:in,"a")
8
+ top.add b=Port.new(:in,"b")
9
+ top.add f=Port.new(:out,"f")
10
+ top.add g1=And.new
11
+ top.add g2=Xor.new
12
+
13
+ a.connect g1.port("i1")
14
+ b.connect g1.port("i2")
15
+ b.connect g2.port("i2")
16
+ g1.port("f").connect g2.port("i1")
17
+ g2.port("f").connect f
18
+ top.to_dot
19
+
20
+ Placer.new.place top
@@ -0,0 +1,32 @@
1
+ #require "rtl_circuit"
2
+ require_relative "../../../rtl/lib/rtl.rb"
3
+
4
+ include RTL
5
+
6
+ top=Circuit.new("top_1")
7
+ top.add a=Port.new(:in,"a")
8
+ top.add b=Port.new(:in,"b")
9
+ top.add c=Port.new(:in,"c")
10
+ top.add d=Port.new(:in,"d")
11
+ top.add f=Port.new(:out,"f")
12
+
13
+ top.add a1=And.new
14
+ top.add a2=Or.new
15
+ top.add a3=Nor.new
16
+ top.add a4=Nand.new
17
+ top.add a5=Xor.new
18
+
19
+ a.connect a1.port("i1")
20
+ b.connect a1.port("i2")
21
+ b.connect a2.port("i1")
22
+ c.connect a2.port("i2")
23
+ c.connect a3.port("i1")
24
+ d.connect a3.port("i2")
25
+ a2.port("f").connect a4.port("i1")
26
+ a3.port("f").connect a4.port("i2")
27
+ a1.port("f").connect a5.port("i1")
28
+ a4.port("f").connect a5.port("i2")
29
+ a5.port("f").connect f
30
+ top.to_dot
31
+
32
+ Placer.new.place top
@@ -0,0 +1,18 @@
1
+ require_relative "../../../synchrony/lib/synchrony"
2
+
3
+ puts "synchrony 1"
4
+
5
+ sync= %{
6
+ circuit sync1
7
+ input a,b,c,d,e,f,g,h,i,j
8
+ output o1,o2
9
+ sig s1
10
+ s1=(a and !b) or (c and d)
11
+ o1=((e and f) xor s1) and g
12
+ o2=(e and f) or (s1 and h) and reg(i or j)
13
+ end
14
+ }
15
+ filename="sync_0.syc"
16
+ File.open(filename,'w'){|f| f.puts(sync)}
17
+
18
+ Synchrony::Compiler.new.compile filename
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rtl_circuit
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.7'
5
+ platform: ruby
6
+ authors:
7
+ - Jean-Christophe Le Lann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: simple digital circuit modeling, with hierarchy and graphviz output
14
+ email: jean-christophe.le_lann@ensta-bretagne.fr
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/rtl.rb
20
+ - lib/rtl/circuit.rb
21
+ - lib/rtl/code.rb
22
+ - lib/rtl/library.rb
23
+ - lib/rtl/printer.rb
24
+ - tests/json/testing_json.rb
25
+ - tests/pnr/pnr_0.rb
26
+ - tests/pnr/pnr_1.rb
27
+ - tests/pnr/sync_0.rb
28
+ homepage: http://www.github.com/JC-LL/rtl
29
+ licenses:
30
+ - GPL-2.0-only
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.0.6
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: simple digital circuit modeling
51
+ test_files: []