rhdl 0.1.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 +7 -0
- data/Gemfile +6 -0
- data/data/README.md +3 -0
- data/exe/rhdl +20 -0
- data/lib/rhdl/assign_statement.rb +33 -0
- data/lib/rhdl/bin_op.rb +38 -0
- data/lib/rhdl/block_dsl.rb +65 -0
- data/lib/rhdl/check_context.rb +111 -0
- data/lib/rhdl/component.rb +89 -0
- data/lib/rhdl/component_dsl.rb +32 -0
- data/lib/rhdl/data_type.rb +30 -0
- data/lib/rhdl/expression.rb +27 -0
- data/lib/rhdl/gen_config.rb +5 -0
- data/lib/rhdl/module_generator.rb +89 -0
- data/lib/rhdl/node_statement.rb +37 -0
- data/lib/rhdl/statement.rb +10 -0
- data/lib/rhdl/top_dsl.rb +17 -0
- data/lib/rhdl/un_op.rb +34 -0
- data/lib/rhdl/variable.rb +30 -0
- data/lib/rhdl/verilog_generator.rb +14 -0
- data/lib/rhdl/version.rb +5 -0
- data/lib/rhdl.rb +24 -0
- data/rhdl.gemspec +31 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 87d1dd60eae916a05415177bf5f3dbd9430d8b54a4922e8c98c4f8cff181524b
|
4
|
+
data.tar.gz: 0e50218f3df5e1fb5f375b6f4219be61e8e66a50b788e8a71f445e7cde35c4cd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 407dcc265f29e30d414f04427f49fef74c6dfbfbaa23e2419cf16a1e09a5394847bfe3b78e77497ee5fc040dc697ceeef16ff05f04bac6fed70a37d302e445be
|
7
|
+
data.tar.gz: 3a5977f6ff6bd7a5c4bfe8c320f0e3d965876f87a77cdc5b1ae15f06407429819599f0ce7da744bfae1db3be23d82017bc65013ddb81f7753f8f5fbfb41d272f
|
data/Gemfile
ADDED
data/data/README.md
ADDED
data/exe/rhdl
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rhdl'
|
4
|
+
|
5
|
+
filename = ARGV[0]
|
6
|
+
|
7
|
+
contents = File.read(filename)
|
8
|
+
|
9
|
+
include Rhdl
|
10
|
+
|
11
|
+
dsl = TopDsl.new
|
12
|
+
dsl.instance_eval(contents, contents)
|
13
|
+
|
14
|
+
config = GenConfig.new
|
15
|
+
config.top_module_name = "And"
|
16
|
+
|
17
|
+
vg = VerilogGenerator.new(dsl, config)
|
18
|
+
puts vg.generate_module("Test1")
|
19
|
+
puts vg.generate_module("Test2")
|
20
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class AssignStatement < Statement
|
3
|
+
def initialize(var_name, expr)
|
4
|
+
@var_name = var_name
|
5
|
+
@expr = expr
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate
|
9
|
+
[
|
10
|
+
#"//#{@expr.varnames};",
|
11
|
+
"#{@var_name} = #{@expr.generate};"
|
12
|
+
]
|
13
|
+
end
|
14
|
+
|
15
|
+
def check!(check_context)
|
16
|
+
out_type = @expr.get_output_type(check_context)
|
17
|
+
var_type = check_context.get_var_type(@var_name)
|
18
|
+
|
19
|
+
# assignment type check
|
20
|
+
if out_type.is_equal_or_child_of(var_type)
|
21
|
+
raise "cannot assign type #{out_type} to var #{var_type}"
|
22
|
+
end
|
23
|
+
|
24
|
+
if out_type.bits != var_type.bits
|
25
|
+
raise "cannot assign type #{out_type} to var #{var_type}, they are not the same size"
|
26
|
+
end
|
27
|
+
|
28
|
+
@expr.fanout(check_context, self)
|
29
|
+
check_context.notify_driver(@var_name, self)
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/rhdl/bin_op.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class BinOp < Expression
|
3
|
+
def initialize(lhs, rhs, op)
|
4
|
+
@lhs = lhs
|
5
|
+
@rhs = rhs
|
6
|
+
@op = op
|
7
|
+
end
|
8
|
+
|
9
|
+
def varnames
|
10
|
+
@lhs.varnames + @rhs.varnames
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate
|
14
|
+
"(#{@lhs.generate} #{@op} #{@rhs.generate})"
|
15
|
+
end
|
16
|
+
|
17
|
+
def fanout(check_context, statement)
|
18
|
+
@lhs.fanout(check_context, statement)
|
19
|
+
@rhs.fanout(check_context, statement)
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_output_type(check_context)
|
23
|
+
ltype = @lhs.get_output_type(check_context)
|
24
|
+
rtype = @rhs.get_output_type(check_context)
|
25
|
+
if @op == "&"
|
26
|
+
|
27
|
+
if ltype.to_s != "uint_1" ||
|
28
|
+
rtype.to_s != "uint_1"
|
29
|
+
raise "& does not support types #{ltype} and #{rtype}"
|
30
|
+
end
|
31
|
+
|
32
|
+
return ltype
|
33
|
+
else
|
34
|
+
raise "unknown operation '#{op}'"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class BlockDsl
|
3
|
+
|
4
|
+
class ::Integer
|
5
|
+
def generate
|
6
|
+
"1'b#{to_s}"
|
7
|
+
end
|
8
|
+
|
9
|
+
def fanout(check_context, statement)
|
10
|
+
# literals can fanout anytime
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_output_type(check_context)
|
14
|
+
if self == 0 || self == 1
|
15
|
+
return DataType.new("uint", 1, nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
raise 'integer literal other than 0 or 1 not supported'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ::Array
|
23
|
+
def generate
|
24
|
+
"{#{self.map{|x| x.generate}.join(', ')}}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def fanout(check_context, statement)
|
28
|
+
self.each do |x|
|
29
|
+
x.fanout(check_context, statement)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_output_type(check_context)
|
34
|
+
totalbits = self.flatten.sum{|x| x.get_output_type(check_context).bits}
|
35
|
+
DataType.new("uint", totalbits, nil)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :statements
|
40
|
+
def initialize
|
41
|
+
@variables = {}
|
42
|
+
@statements = []
|
43
|
+
@trap = false
|
44
|
+
end
|
45
|
+
|
46
|
+
def method_missing(name, *args)
|
47
|
+
super if args.length != 0
|
48
|
+
super if @trap
|
49
|
+
|
50
|
+
@trap = true
|
51
|
+
v = @variables[name]
|
52
|
+
if v.nil?
|
53
|
+
v = Variable.new(name, self)
|
54
|
+
@variables[name] = v
|
55
|
+
end
|
56
|
+
@trap = false
|
57
|
+
v
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_assign_statement(var_name, expr)
|
61
|
+
@statements << AssignStatement.new(var_name, expr)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class CheckContext
|
3
|
+
def initialize
|
4
|
+
@variables = {}
|
5
|
+
@types = {
|
6
|
+
"uint" => DataType.new("uint", 1, nil)
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_input_variable(name, paramstatement)
|
11
|
+
raise "#{name} is already defined" if @variables[name]
|
12
|
+
|
13
|
+
@variables[name] = {
|
14
|
+
name: name,
|
15
|
+
role: :input,
|
16
|
+
kind: :wire,
|
17
|
+
fanout: [],
|
18
|
+
driver: true, # always driven
|
19
|
+
type: @types[paramstatement.type].with_bits(paramstatement.bits)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_output_variable(name, paramstatement)
|
24
|
+
raise "#{name} is already defined" if @variables[name]
|
25
|
+
|
26
|
+
@variables[name] = {
|
27
|
+
name: name,
|
28
|
+
role: :output,
|
29
|
+
kind: :wire,
|
30
|
+
fanout: true,
|
31
|
+
driver: nil,
|
32
|
+
type: @types[paramstatement.type].with_bits(paramstatement.bits)
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_wire_variable(name, paramstatement)
|
37
|
+
raise "#{name} is already defined" if @variables[name]
|
38
|
+
|
39
|
+
@variables[name] = {
|
40
|
+
name: name,
|
41
|
+
role: :output,
|
42
|
+
kind: :wire,
|
43
|
+
fanout: [],
|
44
|
+
driver: nil,
|
45
|
+
type: @types[paramstatement.type].with_bits(paramstatement.bits)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_register_variable(name, paramstatement)
|
50
|
+
raise "#{name} is already defined" if @variables[name]
|
51
|
+
|
52
|
+
@variables[name] = {
|
53
|
+
name: name,
|
54
|
+
role: :internal,
|
55
|
+
kind: :register,
|
56
|
+
fanout: [],
|
57
|
+
driver: nil,
|
58
|
+
type: @types[paramstatement.type].with_bits(paramstatement.bits)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_var_type(name)
|
63
|
+
|
64
|
+
if @variables[name].nil?
|
65
|
+
raise "undefined variable '#{name}'"
|
66
|
+
end
|
67
|
+
|
68
|
+
@variables[name][:type]
|
69
|
+
end
|
70
|
+
|
71
|
+
def notify_fanout(name, statement)
|
72
|
+
if @variables[name].nil?
|
73
|
+
raise "variable #{name} does not exist"
|
74
|
+
end
|
75
|
+
|
76
|
+
@variables[name][:fanout] << statement
|
77
|
+
end
|
78
|
+
|
79
|
+
def notify_driver(name, statement)
|
80
|
+
if @variables[name].nil?
|
81
|
+
raise "variable #{name} does not exist, and cannot be driven"
|
82
|
+
end
|
83
|
+
unless @variables[name][:driver].nil?
|
84
|
+
raise "variable #{name} is already being driven"
|
85
|
+
end
|
86
|
+
|
87
|
+
@variables[name][:driver] = statement
|
88
|
+
end
|
89
|
+
|
90
|
+
def fanout_check!
|
91
|
+
|
92
|
+
@variables.each do |name, var|
|
93
|
+
used = var[:fanout] == true || var[:fanout].length > 0
|
94
|
+
driven = !var[:driver].nil?
|
95
|
+
|
96
|
+
if used && !driven
|
97
|
+
raise "variable #{name} not driven but used"
|
98
|
+
end
|
99
|
+
|
100
|
+
if !used && driven
|
101
|
+
raise "variable #{name} driven but not used"
|
102
|
+
end
|
103
|
+
|
104
|
+
if !used && !driven
|
105
|
+
raise "variable #{name} completely unused"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class Component
|
3
|
+
def initialize(name, topdsl, theproc)
|
4
|
+
@name = name
|
5
|
+
@topdsl = topdsl
|
6
|
+
@proc = theproc
|
7
|
+
@component_dsl = nil
|
8
|
+
@inputs = []
|
9
|
+
@outputs = []
|
10
|
+
@wires = []
|
11
|
+
@comb_block_dsl = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def inputs
|
15
|
+
implement!
|
16
|
+
|
17
|
+
@inputs
|
18
|
+
end
|
19
|
+
|
20
|
+
def outputs
|
21
|
+
implement!
|
22
|
+
|
23
|
+
@outputs
|
24
|
+
end
|
25
|
+
|
26
|
+
def wires
|
27
|
+
implement!
|
28
|
+
|
29
|
+
@wires
|
30
|
+
end
|
31
|
+
|
32
|
+
def comb_block_dsl
|
33
|
+
implement!
|
34
|
+
|
35
|
+
@comb_block_dsl
|
36
|
+
end
|
37
|
+
|
38
|
+
def implement!
|
39
|
+
return unless @component_dsl.nil?
|
40
|
+
|
41
|
+
component_dsl = ComponentDsl.new(@topdsl)
|
42
|
+
component_dsl.instance_eval(&@proc)
|
43
|
+
|
44
|
+
@inputs = []
|
45
|
+
component_dsl.inputs.each do |k,v|
|
46
|
+
@inputs << v
|
47
|
+
end
|
48
|
+
|
49
|
+
@outputs = []
|
50
|
+
component_dsl.outputs.each do |k,v|
|
51
|
+
@outputs << v
|
52
|
+
end
|
53
|
+
|
54
|
+
@wires = []
|
55
|
+
component_dsl.wires.each do |k,v|
|
56
|
+
@wires << v
|
57
|
+
end
|
58
|
+
|
59
|
+
@comb_block_dsl = component_dsl.comb_block_dsl
|
60
|
+
|
61
|
+
check!(component_dsl)
|
62
|
+
|
63
|
+
@component_dsl = component_dsl
|
64
|
+
end
|
65
|
+
|
66
|
+
def check!(component_dsl)
|
67
|
+
cc = CheckContext.new
|
68
|
+
component_dsl.inputs.each do |k,v|
|
69
|
+
cc.add_input_variable(k, v)
|
70
|
+
end
|
71
|
+
|
72
|
+
component_dsl.outputs.each do |k,v|
|
73
|
+
cc.add_output_variable(k, v)
|
74
|
+
end
|
75
|
+
|
76
|
+
component_dsl.wires.each do |k,v|
|
77
|
+
cc.add_wire_variable(k, v)
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
component_dsl.comb_block_dsl.statements.each do |s|
|
82
|
+
s.check!(cc)
|
83
|
+
end
|
84
|
+
|
85
|
+
cc.fanout_check!
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class ComponentDsl
|
3
|
+
attr_reader :inputs, :outputs, :wires, :comb_block_dsl
|
4
|
+
|
5
|
+
def initialize(topdsl)
|
6
|
+
@topdsl = topdsl
|
7
|
+
@inputs = {}
|
8
|
+
@outputs = {}
|
9
|
+
@wires = {}
|
10
|
+
@comb_block_dsl = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def input(name, bits: 1, type: "uint")
|
14
|
+
@inputs[name] = NodeStatement.new('input', name, bits: bits, type: type)
|
15
|
+
end
|
16
|
+
|
17
|
+
def output(name, bits: 1, type: "uint")
|
18
|
+
@outputs[name] = NodeStatement.new('output', name, bits: bits, type: type)
|
19
|
+
end
|
20
|
+
|
21
|
+
def wire(name, bits: 1, type: "uint")
|
22
|
+
@wires[name] = NodeStatement.new('wire', name, bits: bits, type: type)
|
23
|
+
end
|
24
|
+
|
25
|
+
def comb(&block)
|
26
|
+
raise "Combinational block already defined" if !@comb_block_dsl.nil?
|
27
|
+
|
28
|
+
@comb_block_dsl = BlockDsl.new
|
29
|
+
@comb_block_dsl.instance_eval(&block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class DataType
|
3
|
+
attr_reader :name, :bits, :parent
|
4
|
+
|
5
|
+
def initialize(name, bits, parent)
|
6
|
+
@name = name
|
7
|
+
@bits = bits
|
8
|
+
@parent = parent
|
9
|
+
end
|
10
|
+
|
11
|
+
def with_bits(bits)
|
12
|
+
DataType.new(@name, bits, parent)
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
name == other.name && bits == other.bits
|
17
|
+
end
|
18
|
+
|
19
|
+
def is_equal_or_child_of(other)
|
20
|
+
return false if parent.nil?
|
21
|
+
return true if other == self
|
22
|
+
|
23
|
+
parent.is_equal_or_child_of(other)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"#{@name}_#{@bits}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class Expression
|
3
|
+
def varnames
|
4
|
+
[]
|
5
|
+
end
|
6
|
+
|
7
|
+
def &(rhs)
|
8
|
+
BinOp.new(self, rhs, "&")
|
9
|
+
end
|
10
|
+
|
11
|
+
def !()
|
12
|
+
UnOp.new(self, "!")
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate
|
16
|
+
"<notimpl>"
|
17
|
+
end
|
18
|
+
|
19
|
+
def fanout(check_context, statement)
|
20
|
+
raise "fanout(check_context, statement) not implemented"
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_output_type(check_context)
|
24
|
+
raise "get_output_type(check_context) not implemented"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class ModuleGenerator
|
3
|
+
attr_reader :module_name, :component
|
4
|
+
|
5
|
+
def initialize(module_name, component)
|
6
|
+
@module_name = module_name
|
7
|
+
@component = component
|
8
|
+
end
|
9
|
+
|
10
|
+
def maxlens
|
11
|
+
@maxlens ||= begin
|
12
|
+
res = {}
|
13
|
+
params.each do |paraminfo|
|
14
|
+
paraminfo.each do |key, val|
|
15
|
+
res[key] ||= 0
|
16
|
+
len = (val&.length || 0)
|
17
|
+
if res[key] < len
|
18
|
+
res[key] = len
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
res
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def params
|
28
|
+
@params ||= [] +
|
29
|
+
component.inputs.map{|x| x.generate_terms} +
|
30
|
+
component.outputs.map{|x| x.generate_terms}
|
31
|
+
end
|
32
|
+
|
33
|
+
def params_arr
|
34
|
+
@params_arr ||= begin
|
35
|
+
res = []
|
36
|
+
params.each do |paraminfo|
|
37
|
+
arr = []
|
38
|
+
paraminfo.each do |key, val|
|
39
|
+
if val.nil?
|
40
|
+
arr << "".ljust(maxlens[key])
|
41
|
+
next
|
42
|
+
end
|
43
|
+
|
44
|
+
arr << val.ljust(maxlens[key])
|
45
|
+
end
|
46
|
+
res << " #{arr.join(' ')}"
|
47
|
+
end
|
48
|
+
res
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def params_stmt
|
53
|
+
@params_stmt ||= params_arr.join(",\n")
|
54
|
+
end
|
55
|
+
|
56
|
+
def comb_block
|
57
|
+
@comb_block ||= component.
|
58
|
+
comb_block_dsl.
|
59
|
+
statements.
|
60
|
+
map{|x| x.generate}.flatten.map{|x| " #{x}"}.
|
61
|
+
join("\n")
|
62
|
+
end
|
63
|
+
|
64
|
+
def wire_list
|
65
|
+
component.wires.map do |x|
|
66
|
+
terms = x.generate_terms
|
67
|
+
"reg #{terms[:bitterm]} #{terms[:name]}; // wire"
|
68
|
+
end.join("\n")
|
69
|
+
end
|
70
|
+
|
71
|
+
def generate
|
72
|
+
result = <<~CONTENT
|
73
|
+
module #{module_name}
|
74
|
+
(
|
75
|
+
#{params_stmt}
|
76
|
+
);
|
77
|
+
#{wire_list}
|
78
|
+
always @(*) begin
|
79
|
+
#{comb_block}
|
80
|
+
end
|
81
|
+
|
82
|
+
endmodule
|
83
|
+
|
84
|
+
CONTENT
|
85
|
+
|
86
|
+
result
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class NodeStatement
|
3
|
+
attr_reader :ptype, :bits, :name, :type
|
4
|
+
|
5
|
+
def initialize(ptype ,name, bits:, type:)
|
6
|
+
@ptype = ptype
|
7
|
+
@name = name
|
8
|
+
@bits = bits
|
9
|
+
@type = type
|
10
|
+
end
|
11
|
+
|
12
|
+
def theptype
|
13
|
+
if @ptype == 'input'
|
14
|
+
"input wire"
|
15
|
+
else
|
16
|
+
"output reg"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_terms
|
21
|
+
{
|
22
|
+
keyword: theptype,
|
23
|
+
bitterm: bitterm,
|
24
|
+
name: name
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def bitterm
|
30
|
+
if bits == 1
|
31
|
+
nil
|
32
|
+
else
|
33
|
+
"[#{bits-1}:0]"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/rhdl/top_dsl.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class TopDsl
|
3
|
+
attr_reader :contents
|
4
|
+
def initialize
|
5
|
+
@components = {}
|
6
|
+
@contents = {
|
7
|
+
components: @components
|
8
|
+
}
|
9
|
+
end
|
10
|
+
|
11
|
+
def component(name, &block)
|
12
|
+
raise "component '#{name}' already defined" if @components[name]
|
13
|
+
@components[name] = Component.new(name, self, Proc.new(&block))
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/rhdl/un_op.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class UnOp < Expression
|
3
|
+
def initialize(lhs, op)
|
4
|
+
@lhs = lhs
|
5
|
+
@op = op
|
6
|
+
end
|
7
|
+
|
8
|
+
def varnames
|
9
|
+
@lhs.varnames
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate
|
13
|
+
"!(#{@lhs.generate})"
|
14
|
+
end
|
15
|
+
|
16
|
+
def fanout(check_context, statement)
|
17
|
+
@lhs.fanout(check_context, statement)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_output_type(check_context)
|
21
|
+
ltype = @lhs.get_output_type(check_context)
|
22
|
+
if @op == "!"
|
23
|
+
|
24
|
+
if ltype.to_s != "uint_1"
|
25
|
+
raise "& does not support types #{ltype}"
|
26
|
+
end
|
27
|
+
|
28
|
+
return ltype
|
29
|
+
else
|
30
|
+
raise "unknown operation '#{op}'"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class Variable < Expression
|
3
|
+
def initialize(name, owner)
|
4
|
+
@name = name.to_s
|
5
|
+
@owner = owner
|
6
|
+
end
|
7
|
+
|
8
|
+
def <=(rhs)
|
9
|
+
@owner.add_assign_statement(@name, rhs)
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def varnames
|
14
|
+
[@name]
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
"#{@name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_output_type(check_context)
|
22
|
+
check_context.get_var_type(@name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def fanout(check_context, statement)
|
26
|
+
check_context.notify_fanout(@name, statement)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rhdl
|
2
|
+
class VerilogGenerator
|
3
|
+
def initialize(dsl, config)
|
4
|
+
@dsl = dsl
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def generate_module(module_name)
|
9
|
+
thing = @dsl.contents[:components][module_name]
|
10
|
+
|
11
|
+
ModuleGenerator.new(module_name, thing).generate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/rhdl/version.rb
ADDED
data/lib/rhdl.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rhdl/version'
|
4
|
+
require 'rhdl/top_dsl.rb'
|
5
|
+
require 'rhdl/component.rb'
|
6
|
+
require 'rhdl/data_type.rb'
|
7
|
+
require 'rhdl/check_context.rb'
|
8
|
+
require 'rhdl/node_statement.rb'
|
9
|
+
require 'rhdl/expression.rb'
|
10
|
+
require 'rhdl/un_op.rb'
|
11
|
+
require 'rhdl/bin_op.rb'
|
12
|
+
require 'rhdl/variable.rb'
|
13
|
+
require 'rhdl/statement.rb'
|
14
|
+
require 'rhdl/assign_statement.rb'
|
15
|
+
require 'rhdl/block_dsl.rb'
|
16
|
+
require 'rhdl/component_dsl.rb'
|
17
|
+
require 'rhdl/gen_config.rb'
|
18
|
+
require 'rhdl/module_generator.rb'
|
19
|
+
require 'rhdl/verilog_generator.rb'
|
20
|
+
|
21
|
+
module Rhdl
|
22
|
+
class Error < StandardError; end
|
23
|
+
# Your code goes here...
|
24
|
+
end
|
data/rhdl.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/rhdl/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'rhdl'
|
7
|
+
spec.version = Rhdl::VERSION
|
8
|
+
spec.authors = ['David Siaw']
|
9
|
+
spec.email = ['874280+davidsiaw@users.noreply.github.com']
|
10
|
+
|
11
|
+
spec.summary = 'Rhdl summary'
|
12
|
+
spec.description = 'Rhdl description'
|
13
|
+
spec.homepage = 'https://github.com/davidsiaw/rhdl'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
16
|
+
|
17
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
18
|
+
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
20
|
+
spec.metadata['source_code_uri'] = 'https://github.com/davidsiaw/rhdl'
|
21
|
+
spec.metadata['changelog_uri'] = 'https://github.com/davidsiaw/rhdl'
|
22
|
+
|
23
|
+
spec.files = Dir['{exe,data,lib}/**/*'] + %w[Gemfile rhdl.gemspec]
|
24
|
+
spec.bindir = 'exe'
|
25
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ['lib']
|
27
|
+
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.0'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
30
|
+
spec.add_development_dependency 'rubocop'
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rhdl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Siaw
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-02-14 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: rake
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '12.0'
|
19
|
+
type: :development
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '12.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: rubocop
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
description: Rhdl description
|
55
|
+
email:
|
56
|
+
- 874280+davidsiaw@users.noreply.github.com
|
57
|
+
executables:
|
58
|
+
- rhdl
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- Gemfile
|
63
|
+
- data/README.md
|
64
|
+
- exe/rhdl
|
65
|
+
- lib/rhdl.rb
|
66
|
+
- lib/rhdl/assign_statement.rb
|
67
|
+
- lib/rhdl/bin_op.rb
|
68
|
+
- lib/rhdl/block_dsl.rb
|
69
|
+
- lib/rhdl/check_context.rb
|
70
|
+
- lib/rhdl/component.rb
|
71
|
+
- lib/rhdl/component_dsl.rb
|
72
|
+
- lib/rhdl/data_type.rb
|
73
|
+
- lib/rhdl/expression.rb
|
74
|
+
- lib/rhdl/gen_config.rb
|
75
|
+
- lib/rhdl/module_generator.rb
|
76
|
+
- lib/rhdl/node_statement.rb
|
77
|
+
- lib/rhdl/statement.rb
|
78
|
+
- lib/rhdl/top_dsl.rb
|
79
|
+
- lib/rhdl/un_op.rb
|
80
|
+
- lib/rhdl/variable.rb
|
81
|
+
- lib/rhdl/verilog_generator.rb
|
82
|
+
- lib/rhdl/version.rb
|
83
|
+
- rhdl.gemspec
|
84
|
+
homepage: https://github.com/davidsiaw/rhdl
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata:
|
88
|
+
allowed_push_host: https://rubygems.org
|
89
|
+
homepage_uri: https://github.com/davidsiaw/rhdl
|
90
|
+
source_code_uri: https://github.com/davidsiaw/rhdl
|
91
|
+
changelog_uri: https://github.com/davidsiaw/rhdl
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 2.3.0
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubygems_version: 3.6.2
|
107
|
+
specification_version: 4
|
108
|
+
summary: Rhdl summary
|
109
|
+
test_files: []
|