HDLRuby 2.4.29 → 2.6.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 +4 -4
- data/lib/HDLRuby/drivers/xcd.rb +79 -0
- data/lib/HDLRuby/drivers/xcd/dummy.xcd +4 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +1 -1
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +1 -1
- data/lib/HDLRuby/hdr_samples/constant_in_function.rb +27 -0
- data/lib/HDLRuby/hdr_samples/dff_properties.rb +19 -0
- data/lib/HDLRuby/hdr_samples/dff_unit.rb +54 -0
- data/lib/HDLRuby/hdr_samples/huge_rom.rb +25 -0
- data/lib/HDLRuby/hdr_samples/logic_bench.rb +21 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +1 -1
- data/lib/HDLRuby/hdr_samples/multi_timed_bench.rb +54 -0
- data/lib/HDLRuby/hdr_samples/music.rb +79 -0
- data/lib/HDLRuby/hdr_samples/named_sub.rb +42 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_function_generator.rb +25 -0
- data/lib/HDLRuby/hdrcc.rb +162 -26
- data/lib/HDLRuby/hruby_decorator.rb +250 -0
- data/lib/HDLRuby/hruby_high.rb +468 -91
- data/lib/HDLRuby/hruby_low.rb +913 -45
- data/lib/HDLRuby/hruby_low2c.rb +122 -168
- data/lib/HDLRuby/hruby_low2hdr.rb +738 -0
- data/lib/HDLRuby/hruby_low2high.rb +331 -549
- data/lib/HDLRuby/hruby_low2vhd.rb +39 -2
- data/lib/HDLRuby/hruby_low_bool2select.rb +29 -0
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +27 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +25 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +70 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +28 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +6 -3
- data/lib/HDLRuby/hruby_low_without_namespace.rb +7 -4
- data/lib/HDLRuby/hruby_low_without_select.rb +13 -0
- data/lib/HDLRuby/hruby_tools.rb +11 -1
- data/lib/HDLRuby/hruby_verilog.rb +1577 -1709
- data/lib/HDLRuby/sim/hruby_sim.h +29 -3
- data/lib/HDLRuby/sim/hruby_sim_calc.c +63 -6
- data/lib/HDLRuby/sim/hruby_sim_core.c +24 -9
- data/lib/HDLRuby/sim/hruby_sim_vcd.c +5 -1
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +22 -6
- data/lib/HDLRuby/std/fixpoint.rb +9 -0
- data/lib/HDLRuby/std/function_generator.rb +139 -0
- data/lib/HDLRuby/std/hruby_unit.rb +75 -0
- data/lib/HDLRuby/template_expander.rb +61 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +21 -5
@@ -50,6 +50,15 @@ module HDLRuby::Low
|
|
50
50
|
@@alliance = mode ? true : false
|
51
51
|
end
|
52
52
|
|
53
|
+
|
54
|
+
## Converts string +str+ to a VHDL-compatible string.
|
55
|
+
def self.vhdl_string(str)
|
56
|
+
str = str.gsub(/\n/,"\\n")
|
57
|
+
str.gsub!(/\t/,"\\t")
|
58
|
+
return str
|
59
|
+
end
|
60
|
+
|
61
|
+
|
53
62
|
## Generates the pakage requirement for an entity.
|
54
63
|
# +spaces+ are the spaces to put before each line.
|
55
64
|
def self.packages(spaces)
|
@@ -523,7 +532,8 @@ module HDLRuby::Low
|
|
523
532
|
if inner.value.is_a?(Concat) then
|
524
533
|
# Concat are to be given the expected type of the
|
525
534
|
# elements for casting them equally.
|
526
|
-
res << " := " << inner.value.to_vhdl(inner.type.base,level)
|
535
|
+
# res << " := " << inner.value.to_vhdl(inner.type.base,level)
|
536
|
+
res << " := " << inner.value.to_vhdl(level,inner.type.base)
|
527
537
|
else
|
528
538
|
res << " := " << inner.value.to_vhdl(level)
|
529
539
|
end
|
@@ -901,6 +911,20 @@ module HDLRuby::Low
|
|
901
911
|
Low2VHDL.to_type(self.left.type,self.right) + ";\n"
|
902
912
|
end
|
903
913
|
end
|
914
|
+
|
915
|
+
## Extends the Print class with generation of HDLRuby::High text.
|
916
|
+
class Print
|
917
|
+
|
918
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
919
|
+
# +vars+ is the list of the variables and
|
920
|
+
# +level+ is the hierachical level of the object.
|
921
|
+
def to_vhdl(vars,level = 0)
|
922
|
+
# Generate a report statement.
|
923
|
+
return " " * (level*3) + "report " + self.each_arg.map do |arg|
|
924
|
+
arg.to_vhdl
|
925
|
+
end.join(" & ") + ";\n"
|
926
|
+
end
|
927
|
+
end
|
904
928
|
|
905
929
|
## Extends the If class with generation of HDLRuby::High text.
|
906
930
|
class If
|
@@ -1347,7 +1371,8 @@ module HDLRuby::Low
|
|
1347
1371
|
# Generates the text of the equivalent HDLRuby::High code.
|
1348
1372
|
# +type+ is the expected type of the content.
|
1349
1373
|
# +level+ is the hierachical level of the object.
|
1350
|
-
def to_vhdl(type,level = 0)
|
1374
|
+
# def to_vhdl(type,level = 0)
|
1375
|
+
def to_vhdl(level = 0, type = self.type)
|
1351
1376
|
raise "Invalid class for a type: #{type.class}" unless type.is_a?(Type)
|
1352
1377
|
# The resulting string.
|
1353
1378
|
res = ""
|
@@ -1487,6 +1512,18 @@ module HDLRuby::Low
|
|
1487
1512
|
# Nothing to generate.
|
1488
1513
|
end
|
1489
1514
|
|
1515
|
+
## Extends the StringE class with generation of HDLRuby::High text.
|
1516
|
+
class StringE
|
1517
|
+
|
1518
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
1519
|
+
# +level+ is the hierachical level of the object.
|
1520
|
+
def to_vhdl(level = 0, std_logic = false)
|
1521
|
+
# Generate a report statement.
|
1522
|
+
return "\"#{Low2VHDL.vhdl_string(self.content)}\"" +
|
1523
|
+
self.each_arg.map { |arg| arg.to_vhdl }.join(" & ")
|
1524
|
+
end
|
1525
|
+
end
|
1526
|
+
|
1490
1527
|
## Extends the Numeric class with generation of HDLRuby::High text.
|
1491
1528
|
class ::Numeric
|
1492
1529
|
|
@@ -61,6 +61,20 @@ module HDLRuby::Low
|
|
61
61
|
return self
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
|
66
|
+
## Extends the Print class with functionality for converting booleans
|
67
|
+
# in assignments to select operators.
|
68
|
+
class Print
|
69
|
+
|
70
|
+
# Converts booleans in assignments to select operators.
|
71
|
+
def boolean_in_assign2select!
|
72
|
+
# Apply on the arguments.
|
73
|
+
self.map_args! { |arg| arg.boolean_in_assign2select }
|
74
|
+
return self
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
64
78
|
|
65
79
|
## Extends the If class with functionality for converting booleans
|
66
80
|
# in assignments to select operators.
|
@@ -315,4 +329,19 @@ module HDLRuby::Low
|
|
315
329
|
return self.clone
|
316
330
|
end
|
317
331
|
end
|
332
|
+
|
333
|
+
|
334
|
+
## Extends the StringE class with functionality for converting booleans
|
335
|
+
# in assignments to select operators.
|
336
|
+
class StringE
|
337
|
+
|
338
|
+
# Converts booleans in assignments to select operators.
|
339
|
+
def boolean_in_assign2select
|
340
|
+
# Apply on the content.
|
341
|
+
# Apply on the arguments.
|
342
|
+
return StringE.new(self.content.clone,*self.each_arg.map do |arg|
|
343
|
+
arg.boolean_in_assign2select
|
344
|
+
end)
|
345
|
+
end
|
346
|
+
end
|
318
347
|
end
|
@@ -62,6 +62,20 @@ module HDLRuby::Low
|
|
62
62
|
return self
|
63
63
|
end
|
64
64
|
end
|
65
|
+
|
66
|
+
|
67
|
+
## Extends the Print class with functionality for extracting
|
68
|
+
# expressions from cast.
|
69
|
+
class Print
|
70
|
+
|
71
|
+
# Extracts the expressions from the casts.
|
72
|
+
def casts_without_expression!
|
73
|
+
# Apply on the arguments.
|
74
|
+
self.map_args!(&:casts_without_expression)
|
75
|
+
return self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
65
79
|
|
66
80
|
## Extends the If class with functionality for extracting
|
67
81
|
# expressions from cast.
|
@@ -323,4 +337,17 @@ module HDLRuby::Low
|
|
323
337
|
return self.clone
|
324
338
|
end
|
325
339
|
end
|
340
|
+
|
341
|
+
|
342
|
+
## Extends the StringE class with functionality for extracting
|
343
|
+
# expressions from cast.
|
344
|
+
class StringE
|
345
|
+
|
346
|
+
# Extracts the expressions from the casts.
|
347
|
+
def casts_without_expression
|
348
|
+
return StringE.new(self.content,
|
349
|
+
*self.each_arg.map(&:cast_without_expression))
|
350
|
+
return self
|
351
|
+
end
|
352
|
+
end
|
326
353
|
end
|
@@ -89,6 +89,20 @@ module HDLRuby::Low
|
|
89
89
|
|
90
90
|
end
|
91
91
|
|
92
|
+
|
93
|
+
## Extends the Print class with fixing of types and constants.
|
94
|
+
class Print
|
95
|
+
# Explicit the types conversions in the statement.
|
96
|
+
def explicit_types!
|
97
|
+
# Recurse on the arguments.
|
98
|
+
self.map_args!(&:explicit_types)
|
99
|
+
return self
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
|
92
106
|
|
93
107
|
## Extends the If class with fixing of types and constants.
|
94
108
|
class If
|
@@ -438,4 +452,15 @@ module HDLRuby::Low
|
|
438
452
|
end
|
439
453
|
|
440
454
|
|
455
|
+
## Extends the stringE class with fixing of types and constants.
|
456
|
+
class StringE
|
457
|
+
# Explicit the types conversions in the concat where
|
458
|
+
# +type+ is the expected type of the condition if any.
|
459
|
+
def explicit_types(type = nil)
|
460
|
+
return StringE.new(self.content,
|
461
|
+
*self.each_arg.map(&:explicit_types))
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
|
441
466
|
end
|
@@ -626,6 +626,64 @@ module HDLRuby::Low
|
|
626
626
|
end
|
627
627
|
|
628
628
|
|
629
|
+
##
|
630
|
+
# Decribes a print statement.
|
631
|
+
class Print
|
632
|
+
|
633
|
+
# Maps on the arguments.
|
634
|
+
def map_args!(&ruby_block)
|
635
|
+
@args.map! do |arg|
|
636
|
+
arg = ruby_block.call(arg)
|
637
|
+
arg.parent = self unless arg.parent
|
638
|
+
arg
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
alias_method :map_nodes!, :map_args!
|
643
|
+
|
644
|
+
# Delete an arg.
|
645
|
+
def delete_arg!(arg)
|
646
|
+
if @args.include?(arg) then
|
647
|
+
# The arg is present, delete it.
|
648
|
+
@args.delete(arg)
|
649
|
+
# And remove its parent.
|
650
|
+
arg.parent = nil
|
651
|
+
end
|
652
|
+
arg
|
653
|
+
end
|
654
|
+
|
655
|
+
# Replaces sub arguments using +node2rep+ table indicating the
|
656
|
+
# node to replace and the corresponding replacement.
|
657
|
+
# Returns the actually replaced nodes and their corresponding
|
658
|
+
# replacement.
|
659
|
+
#
|
660
|
+
# NOTE: the replacement is duplicated.
|
661
|
+
def replace_args!(node2rep)
|
662
|
+
# First recurse on the children.
|
663
|
+
res = {}
|
664
|
+
self.each_node do |node|
|
665
|
+
res.merge!(node.replace_args!(node2rep))
|
666
|
+
end
|
667
|
+
# Is there a replacement of on a sub node?
|
668
|
+
self.map_nodes! do |sub|
|
669
|
+
rep = node2rep[sub]
|
670
|
+
if rep then
|
671
|
+
# Yes, do it.
|
672
|
+
rep = rep.clone
|
673
|
+
node = sub
|
674
|
+
# node.set_parent!(nil)
|
675
|
+
# And register the replacement.
|
676
|
+
res[node] = rep
|
677
|
+
rep
|
678
|
+
else
|
679
|
+
sub
|
680
|
+
end
|
681
|
+
end
|
682
|
+
return res
|
683
|
+
end
|
684
|
+
end
|
685
|
+
|
686
|
+
|
629
687
|
##
|
630
688
|
# Describes an if statement.
|
631
689
|
class If
|
@@ -1093,6 +1151,18 @@ module HDLRuby::Low
|
|
1093
1151
|
stmnt.parent = self
|
1094
1152
|
end
|
1095
1153
|
|
1154
|
+
# Replaces statement +org+ by statement +stmnt+.
|
1155
|
+
#
|
1156
|
+
# NOTE: does nothing if +org+ is not present.
|
1157
|
+
def replace_statement!(org,stmnt)
|
1158
|
+
# Checks the statement.
|
1159
|
+
unless stmnt.is_a?(Statement)
|
1160
|
+
raise AnyError, "Invalid type for a statement: #{stmnt.class}"
|
1161
|
+
end
|
1162
|
+
idx = @statements.index(org)
|
1163
|
+
@statements[idx] = stmnt if idx
|
1164
|
+
end
|
1165
|
+
|
1096
1166
|
# Maps on the statements.
|
1097
1167
|
def map_statements!(&ruby_block)
|
1098
1168
|
@statements.map! do |stmnt|
|
@@ -84,6 +84,20 @@ module HDLRuby::Low
|
|
84
84
|
end
|
85
85
|
|
86
86
|
|
87
|
+
##
|
88
|
+
# Extends RefIndex with the capability of finding the object it
|
89
|
+
# refered to.
|
90
|
+
class Ref
|
91
|
+
## Resolves the name of the reference (if any) and return the
|
92
|
+
# corresponding object.
|
93
|
+
# NOTE: return nil if could not resolve.
|
94
|
+
def resolve
|
95
|
+
# By default cannot resolve.
|
96
|
+
return nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
87
101
|
##
|
88
102
|
# Extends RefIndex with the capability of finding the object it
|
89
103
|
# refered to.
|
@@ -93,6 +107,13 @@ module HDLRuby::Low
|
|
93
107
|
def from_systemI?
|
94
108
|
return self.ref.from_systemI?
|
95
109
|
end
|
110
|
+
|
111
|
+
## Resolves the name of the reference (if any) and return the
|
112
|
+
# corresponding object.
|
113
|
+
# NOTE: return nil if could not resolve.
|
114
|
+
def resolve
|
115
|
+
return self.ref.resolve
|
116
|
+
end
|
96
117
|
end
|
97
118
|
|
98
119
|
|
@@ -105,6 +126,13 @@ module HDLRuby::Low
|
|
105
126
|
def from_systemI?
|
106
127
|
return self.ref.from_systemI?
|
107
128
|
end
|
129
|
+
|
130
|
+
## Resolves the name of the reference (if any) and return the
|
131
|
+
# corresponding object.
|
132
|
+
# NOTE: return nil if could not resolve.
|
133
|
+
def resolve
|
134
|
+
return self.ref.resolve
|
135
|
+
end
|
108
136
|
end
|
109
137
|
|
110
138
|
|
@@ -42,7 +42,8 @@ module HDLRuby::Low
|
|
42
42
|
right_r = right.resolve if right.respond_to?(:resolve)
|
43
43
|
# puts "right_r=#{right_r.name}" if right_r
|
44
44
|
# puts "right_r.parent=#{right_r.parent.name}" if right_r && right_r.parent
|
45
|
-
if right.is_a?(Value) then
|
45
|
+
# if right.is_a?(Value) then
|
46
|
+
if right.immutable? then
|
46
47
|
# Right is value, the new transmit is to add
|
47
48
|
# to the timed block.
|
48
49
|
timed_blk.add_statement(
|
@@ -108,13 +109,15 @@ module HDLRuby::Low
|
|
108
109
|
# end
|
109
110
|
# Both or neither input/output, make a behavior
|
110
111
|
# for each.
|
111
|
-
if (left.is_a?(Ref)
|
112
|
+
if (left.is_a?(Ref) &&
|
113
|
+
!(left_r && left_r.immutable?)) then
|
112
114
|
blk = Block.new(:par)
|
113
115
|
blk.add_statement(
|
114
116
|
Transmit.new(left.clone,right.clone))
|
115
117
|
scope.add_behavior(Behavior.new(blk))
|
116
118
|
end
|
117
|
-
if (right.is_a?(Ref)
|
119
|
+
if (right.is_a?(Ref) &&
|
120
|
+
!(right_r && right_r.immutable?)) then
|
118
121
|
blk = Block.new(:par)
|
119
122
|
blk.add_statement(
|
120
123
|
Transmit.new(right.clone,left.clone))
|
@@ -617,10 +617,13 @@ module HDLRuby::Low
|
|
617
617
|
#
|
618
618
|
# NOTE: do not recurse into the sub scopes or behaviors!
|
619
619
|
def extract_declares!
|
620
|
-
# Recurse on the whens.
|
621
|
-
return self.each_when.map(&:extract_declares!)
|
622
|
-
# Recurse on the default if any.
|
623
|
-
self.default.extract_declares! if self.default
|
620
|
+
# # Recurse on the whens.
|
621
|
+
# return self.each_when.map(&:extract_declares!)
|
622
|
+
# # Recurse on the default if any.
|
623
|
+
# self.default.extract_declares! if self.default
|
624
|
+
res = self.each_when.map(&:extract_declares!)
|
625
|
+
res += self.default.extract_declares! if self.default
|
626
|
+
return res
|
624
627
|
end
|
625
628
|
|
626
629
|
# Replaces recursively +former+ name by +nname+ until it is redeclared.
|
@@ -162,6 +162,19 @@ module HDLRuby::Low
|
|
162
162
|
return selects
|
163
163
|
end
|
164
164
|
end
|
165
|
+
|
166
|
+
## Extends the String class with functionality for converting select
|
167
|
+
# expressions to case statements.
|
168
|
+
class Print
|
169
|
+
# Extract the Select expressions.
|
170
|
+
def extract_selects!
|
171
|
+
selects = []
|
172
|
+
self.map_args! do |arg|
|
173
|
+
arg.extract_selects_to!(selects)
|
174
|
+
end
|
175
|
+
return selects
|
176
|
+
end
|
177
|
+
end
|
165
178
|
|
166
179
|
## Extends the If class with functionality for converting select
|
167
180
|
# expressions to case statements.
|
data/lib/HDLRuby/hruby_tools.rb
CHANGED
@@ -17,120 +17,128 @@ module HDLRuby::Low
|
|
17
17
|
# The list of signals that are actually verilog regs.
|
18
18
|
VERILOG_REGS = []
|
19
19
|
|
20
|
+
## Converts string +str+ to a Verilog-compatible string.
|
21
|
+
def self.v_string(str)
|
22
|
+
str = str.gsub(/\n/,"\\n")
|
23
|
+
str.gsub!(/\t/,"\\t")
|
24
|
+
return str
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# Sample of very handy for programming.
|
29
|
+
# puts "class=#{self.yes.class}" # Confirm class of self.yes.
|
30
|
+
# puts "methods=#{self.right.methods}" # Confirm method of self.right.
|
31
|
+
# puts "outputs=#{outputs}" # Confirm outputs
|
32
|
+
|
33
|
+
# each. do |*arg| # I forgot this.
|
34
|
+
# puts args
|
35
|
+
# end
|
36
|
+
|
37
|
+
# Global variable used for indentation and structure (temporary).
|
38
|
+
$vector_reg = "" # For storing signal type at structure declaration. (temporary)
|
39
|
+
$vector_cnt = 0 # For allocating numbers at structure declaration. (temporary)
|
20
40
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
# each. do |*arg| # I forgot this.
|
27
|
-
# puts args
|
28
|
-
# end
|
29
|
-
|
30
|
-
# Global variable used for indentation and structure (temporary).
|
31
|
-
# $space_count = 0 # Count used for increasing indent by if statement. (temporary)
|
32
|
-
$vector_reg = "" # For storing signal type at structure declaration. (temporary)
|
33
|
-
$vector_cnt = 0 # For allocating numbers at structure declaration. (temporary)
|
34
|
-
|
35
|
-
# class Fixnum
|
36
|
-
# def to_verilog
|
37
|
-
# to_s
|
38
|
-
# end
|
39
|
-
# end
|
40
|
-
class ::Integer
|
41
|
-
def to_verilog
|
42
|
-
to_s
|
41
|
+
class ::Integer
|
42
|
+
def to_verilog
|
43
|
+
to_s
|
44
|
+
end
|
43
45
|
end
|
44
|
-
end
|
45
46
|
|
46
|
-
# Class summarizing "hash" used for "par" or "seq" conversion.
|
47
|
-
class Fm
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
47
|
+
# Class summarizing "hash" used for "par" or "seq" conversion.
|
48
|
+
class Fm
|
49
|
+
attr_reader :fm_seq, :fm_par, :rep, :rep_sharp
|
50
|
+
def initialize
|
51
|
+
@fm_seq = {} # Used to seq -> par.
|
52
|
+
@fm_par = {} # Used to par -> seq.
|
53
|
+
@rep = {} # Used to give ' to variables
|
54
|
+
@rep_sharp = {} # Used to give # to variables
|
55
|
+
end
|
54
56
|
end
|
55
|
-
end
|
56
57
|
|
57
|
-
# Declaration of fm to manage each hash.
|
58
|
-
$fm = Fm.new
|
58
|
+
# Declaration of fm to manage each hash.
|
59
|
+
$fm = Fm.new
|
59
60
|
|
60
|
-
# A class that translates the left-hand side, operator, and right-hand side into form of expression.
|
61
|
-
class Binary
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
# A class that translates the left-hand side, operator, and right-hand side into form of expression.
|
62
|
+
class Binary
|
63
|
+
# Converts the system to Verilog code.
|
64
|
+
def to_verilog
|
65
|
+
return "(#{self.left.to_verilog} #{self.operator} #{self.right.to_verilog})"
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
else
|
76
|
-
# If you need to replace the variable, replace it. Otherwise we will get a clone.
|
77
|
-
if $fm.fm_par.has_key?(self.left.to_verilog) && mode == :par then
|
78
|
-
left = $fm.fm_par["#{self.left.to_verilog}"]
|
79
|
-
elsif $fm.fm_seq.has_key?(self.left.to_verilog) && mode == :seq then
|
80
|
-
left = $fm.fm_seq["#{self.left.to_verilog}"]
|
68
|
+
# Method called when two or more expression terms are present.
|
69
|
+
# When translating par into seq mode = seq, when translating seq to par mode = par.
|
70
|
+
# Search recursively and replace if hash matches identifier.
|
71
|
+
def to_change(mode)
|
72
|
+
# Recursively search the left side and the right side, check the identifier and replace it.
|
73
|
+
if self.left.is_a? (Binary) then
|
74
|
+
# If there is an expression on the left side of the right side, to_chang is executed again.
|
75
|
+
left = self.left.to_change(mode)
|
81
76
|
else
|
82
|
-
|
77
|
+
# If you need to replace the variable, replace it. Otherwise we will get a clone.
|
78
|
+
if $fm.fm_par.has_key?(self.left.to_verilog) && mode == :par then
|
79
|
+
left = $fm.fm_par["#{self.left.to_verilog}"]
|
80
|
+
elsif $fm.fm_seq.has_key?(self.left.to_verilog) && mode == :seq then
|
81
|
+
left = $fm.fm_seq["#{self.left.to_verilog}"]
|
82
|
+
else
|
83
|
+
left = self.left.clone
|
84
|
+
end
|
83
85
|
end
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
right = self.right.to_change(mode)
|
88
|
-
else
|
89
|
-
# If you need to replace the variable, replace it. Otherwise we will get a clone.
|
90
|
-
if $fm.fm_par.has_key?(self.right.to_verilog) && mode == :par then
|
91
|
-
right = $fm.fm_par["#{self.right.to_verilog}"]
|
92
|
-
elsif $fm.fm_seq.has_key?(self.right.to_verilog) && mode == :seq then
|
93
|
-
right = $fm.fm_seq["#{self.right.to_verilog}"]
|
86
|
+
if self.right.is_a? (Binary) then
|
87
|
+
# Recursively search the right side and the right side, check the identifier and replace it.
|
88
|
+
right = self.right.to_change(mode)
|
94
89
|
else
|
95
|
-
|
90
|
+
# If you need to replace the variable, replace it. Otherwise we will get a clone.
|
91
|
+
if $fm.fm_par.has_key?(self.right.to_verilog) && mode == :par then
|
92
|
+
right = $fm.fm_par["#{self.right.to_verilog}"]
|
93
|
+
elsif $fm.fm_seq.has_key?(self.right.to_verilog) && mode == :seq then
|
94
|
+
right = $fm.fm_seq["#{self.right.to_verilog}"]
|
95
|
+
else
|
96
|
+
right = self.right.clone
|
97
|
+
end
|
96
98
|
end
|
99
|
+
# After confirmation, we create and return an expression.
|
100
|
+
return Binary.new(self.type,self.operator,left.clone,right.clone)
|
97
101
|
end
|
98
|
-
# After confirmation, we create and return an expression.
|
99
|
-
return Binary.new(self.type,self.operator,left.clone,right.clone)
|
100
102
|
end
|
101
|
-
end
|
102
103
|
|
103
|
-
# class of Represent blocking substitution or nonblocking assignment.
|
104
|
-
# Enhance Transmit with generation of verilog code.
|
105
|
-
class Transmit
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
return code
|
104
|
+
# class of Represent blocking substitution or nonblocking assignment.
|
105
|
+
# Enhance Transmit with generation of verilog code.
|
106
|
+
class Transmit
|
107
|
+
# Converts the system to Verilog code.
|
108
|
+
def to_verilog(spc = 3)
|
109
|
+
# Determine blocking assignment or nonblocking substitution from mode and return it.
|
110
|
+
code = "#{" " * spc}#{self.left.to_verilog} #{self.block.mode == :seq ? "=" : "<="} #{self.right.to_verilog};"
|
111
|
+
return code
|
112
|
+
end
|
113
113
|
end
|
114
|
-
end
|
115
114
|
|
116
|
-
#
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
115
|
+
# Enhance Print with generation of verilog code.
|
116
|
+
class Print
|
117
|
+
# Converts the system to Verilog code.
|
118
|
+
def to_verilog(spc = 3)
|
119
|
+
code = "#{" " * spc}$write(#{self.each_arg.map do |arg|
|
120
|
+
arg.to_verilog
|
121
|
+
end.join(",") });"
|
122
|
+
return code
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# To scheduling to the Block.
|
127
|
+
# Enhance Block with generation of verilog code.
|
128
|
+
class Block
|
124
129
|
|
125
|
-
|
126
|
-
|
127
|
-
|
130
|
+
# Converts the system to Verilog code adding 'spc' spaces at the begining
|
131
|
+
# of each line.
|
132
|
+
def to_verilog(spc = 3)
|
128
133
|
code = "begin"
|
129
|
-
|
134
|
+
if self.name && !self.name.empty? then
|
135
|
+
vname = name_to_verilog(self.name)
|
136
|
+
code << " : #{vname}"
|
137
|
+
self.properties[:verilog_name] = vname
|
138
|
+
end
|
130
139
|
code << "\n" if block.each_inner.any?
|
131
140
|
# Declaration of "inner" part within "always".
|
132
141
|
block.each_inner do |inner|
|
133
|
-
# if regs.include?(inner.name) then
|
134
142
|
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
135
143
|
# code << " reg"
|
136
144
|
code << "#{" " * (spc+3)}reg"
|
@@ -142,14 +150,11 @@ class Block
|
|
142
150
|
# It is determined by an if.
|
143
151
|
if inner.type.base?
|
144
152
|
if inner.type.base.base?
|
145
|
-
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
146
153
|
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
147
154
|
else
|
148
|
-
# code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
149
155
|
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
150
156
|
end
|
151
157
|
else
|
152
|
-
# code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
153
158
|
code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
154
159
|
end
|
155
160
|
if inner.value then
|
@@ -161,8 +166,7 @@ class Block
|
|
161
166
|
|
162
167
|
# Translate the block that finished scheduling.
|
163
168
|
block.each_statement do |statement|
|
164
|
-
#
|
165
|
-
# code << "\n#{" "*spc}#{statement.to_verilog(behavior.block.mode.to_s)}"
|
169
|
+
# puts "#{statement.to_verilog(spc+3)}"
|
166
170
|
if statement.is_a?(Block) then
|
167
171
|
code << "\n#{" " * (spc+3)}#{statement.to_verilog(spc+3)}"
|
168
172
|
else
|
@@ -172,94 +176,177 @@ class Block
|
|
172
176
|
# Close the block."
|
173
177
|
code << "\n#{" "*spc}end"
|
174
178
|
return code
|
175
|
-
|
179
|
+
end
|
176
180
|
|
177
181
|
|
178
182
|
|
179
183
|
|
180
184
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
185
|
+
# Extract and convert to verilog the TimeRepeat statements.
|
186
|
+
# NOTE: work only on the current level of the block (should be called
|
187
|
+
# through each_block_deep).
|
188
|
+
def repeat_to_verilog!
|
189
|
+
code = ""
|
190
|
+
# Gather the TimeRepeat statements.
|
191
|
+
repeats = self.each_statement.find_all { |st| st.is_a?(TimeRepeat) }
|
192
|
+
# Remove them from the block.
|
193
|
+
repeats.each { |st| self.delete_statement!(st) }
|
194
|
+
# Generate them separately in timed always processes.
|
195
|
+
repeats.each do |st|
|
196
|
+
code << " always #{st.delay.to_verilog} begin\n"
|
193
197
|
|
194
|
-
|
195
|
-
|
198
|
+
# Perform "scheduling" using the method "flatten".
|
199
|
+
block = st.statement.flatten(st.statement.mode.to_s)
|
196
200
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
201
|
+
# Declaration of "inner" part within "always".
|
202
|
+
block.each_inner do |inner|
|
203
|
+
# if regs.include?(inner.name) then
|
204
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
205
|
+
code << " reg"
|
206
|
+
else
|
207
|
+
code << " wire"
|
208
|
+
end
|
205
209
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
210
|
+
# Variable has "base", but if there is width etc, it is not in "base".
|
211
|
+
# It is determined by an if.
|
212
|
+
if inner.type.base?
|
213
|
+
if inner.type.base.base?
|
214
|
+
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
215
|
+
else
|
216
|
+
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
217
|
+
end
|
212
218
|
else
|
213
|
-
|
214
|
-
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
219
|
+
code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
215
220
|
end
|
216
|
-
|
217
|
-
|
218
|
-
|
221
|
+
if inner.value then
|
222
|
+
# There is an initial value.
|
223
|
+
code << " = #{inner.value.to_verilog}"
|
224
|
+
end
|
225
|
+
code << ";\n"
|
219
226
|
end
|
220
|
-
|
221
|
-
|
222
|
-
|
227
|
+
|
228
|
+
# Translate the block that finished scheduling.
|
229
|
+
block.each_statement do |statement|
|
230
|
+
code << "\n #{statement.to_verilog(block.mode.to_s)}"
|
223
231
|
end
|
224
|
-
code << ";\n"
|
225
|
-
end
|
226
232
|
|
227
|
-
|
228
|
-
|
229
|
-
code
|
233
|
+
$fm.fm_par.clear()
|
234
|
+
|
235
|
+
code << "\n end\n\n"
|
230
236
|
end
|
237
|
+
return code
|
238
|
+
end
|
231
239
|
|
232
|
-
$fm.fm_par.clear()
|
233
240
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
241
|
+
# Process top layer of Block.
|
242
|
+
# Determine whether there is a block under block and convert it.
|
243
|
+
def flatten(mode = nil)
|
244
|
+
if self.is_a?(TimeBlock) then
|
245
|
+
new_block = TimeBlock.new(self.mode,"")
|
246
|
+
else
|
247
|
+
new_block = Block.new(self.mode,"") # A new block to store the converted statement.
|
248
|
+
end
|
249
|
+
list = [] # A list for confirming that variable declarations do not overlap.
|
250
|
+
|
251
|
+
# Is block in the statement?
|
252
|
+
if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)}) then
|
253
|
+
# Process for each type of statement in block.
|
254
|
+
self.each_statement do |statement|
|
255
|
+
# If statement is case, there is a block for each default and when, so translate each.
|
256
|
+
if statement.is_a?(Case) then
|
257
|
+
if statement.default.is_a?(Block)
|
258
|
+
default = statement.default.flatten
|
259
|
+
new_default = Block.new(default.mode,"")
|
260
|
+
|
261
|
+
default.each_inner do |inner|
|
262
|
+
# I read inner, but when I am par, I delete all '.
|
263
|
+
unless (list.include?(inner.name.to_s)) then
|
264
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
265
|
+
list << inner.name.to_s
|
266
|
+
new_block.add_inner(inner.clone)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
238
270
|
|
271
|
+
default.each_statement do |statement|
|
272
|
+
# If statement is Transmit, it is an expression and should be processed.
|
273
|
+
if statement.is_a?(Transmit) then
|
274
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
275
|
+
unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
|
276
|
+
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
277
|
+
new_signal = att_signal(statement.left, "#")
|
278
|
+
# Check list and add new variables to inner if they do not duplicate.
|
279
|
+
unless (list.include?(new_signal.name.to_s)) then
|
280
|
+
list << new_signal.name.to_s
|
281
|
+
new_block.add_inner(new_signal)
|
282
|
+
end
|
283
|
+
|
284
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
285
|
+
|
286
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
287
|
+
|
288
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
289
|
+
new_default.add_statement(new_statement.clone)
|
290
|
+
else
|
291
|
+
new_default.add_statement(statement.clone)
|
292
|
+
end
|
293
|
+
else
|
294
|
+
new_default.add_statement(statement.clone)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
239
298
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
299
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
300
|
+
|
301
|
+
statement.each_when do |whens|
|
302
|
+
when_smt = whens.statement.flatten
|
303
|
+
new_when_smt = Block.new(when_smt.mode,"")
|
304
|
+
|
305
|
+
when_smt.each_statement do |statement|
|
306
|
+
# If statement is Transmit, it is an expression and should be processed.
|
307
|
+
if statement.is_a?(Transmit) then
|
308
|
+
# # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
309
|
+
unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
|
310
|
+
# # Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
311
|
+
new_signal = att_signal(statement.left, "#")
|
312
|
+
# Check list and add new variables to inner if they do not duplicate.
|
313
|
+
unless (list.include?(new_signal.name.to_s)) then
|
314
|
+
list << new_signal.name.to_s
|
315
|
+
new_block.add_inner(new_signal)
|
316
|
+
end
|
317
|
+
|
318
|
+
new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
319
|
+
|
320
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
321
|
+
|
322
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
|
323
|
+
new_when_smt.add_statement(new_smt.clone)
|
324
|
+
else
|
325
|
+
new_when_smt.add_statement(statement.clone)
|
326
|
+
end
|
327
|
+
else
|
328
|
+
new_when_smt.add_statement(statement.clone)
|
329
|
+
end
|
330
|
+
end
|
249
331
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
self.each_statement do |statement|
|
332
|
+
new_when = When.new(whens.match.clone,new_when_smt.clone)
|
333
|
+
new_statement.add_when(new_when.clone)
|
334
|
+
end
|
254
335
|
|
336
|
+
new_block.add_statement(new_statement)
|
255
337
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
338
|
+
$fm.rep_sharp.each_key do |key|
|
339
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
340
|
+
new_block.add_statement(new_smt.clone)
|
341
|
+
end
|
342
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
261
343
|
|
262
|
-
|
344
|
+
# If the statement is if, there is a block for each of yes, no, noifs, so translate each.
|
345
|
+
elsif statement.is_a?(If) then
|
346
|
+
yes = statement.yes.flatten # Smooth yes of if statement.
|
347
|
+
new_yes = Block.new(yes.mode,"") # New yes storage block
|
348
|
+
|
349
|
+
yes.each_inner do |inner|
|
263
350
|
# I read inner, but when I am par, I delete all '.
|
264
351
|
unless (list.include?(inner.name.to_s)) then
|
265
352
|
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
@@ -269,11 +356,12 @@ class Block
|
|
269
356
|
end
|
270
357
|
end
|
271
358
|
|
272
|
-
|
359
|
+
# Check the statements in "yes" in order.
|
360
|
+
yes.each_statement do |statement|
|
273
361
|
# If statement is Transmit, it is an expression and should be processed.
|
274
362
|
if statement.is_a?(Transmit) then
|
275
363
|
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
276
|
-
unless (res_name(statement.left).name.to_s.include? "'") ||
|
364
|
+
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
277
365
|
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
278
366
|
new_signal = att_signal(statement.left, "#")
|
279
367
|
# Check list and add new variables to inner if they do not duplicate.
|
@@ -286,130 +374,188 @@ class Block
|
|
286
374
|
|
287
375
|
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
288
376
|
|
377
|
+
new_yes.add_statement(new_statement.clone)
|
378
|
+
|
379
|
+
|
289
380
|
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
290
|
-
|
381
|
+
|
291
382
|
else
|
292
|
-
|
383
|
+
new_yes.add_statement(statement.clone)
|
293
384
|
end
|
294
385
|
else
|
295
|
-
|
386
|
+
new_yes.add_statement(statement.clone)
|
296
387
|
end
|
297
|
-
end
|
298
|
-
end
|
388
|
+
end
|
299
389
|
|
300
|
-
|
390
|
+
# Confirm that "else" exists and convert it if it exists.
|
391
|
+
# Because error occurs when trying to convert when "else" does not exist.
|
392
|
+
if statement.no.is_a? (Block) then
|
393
|
+
no = statement.no.flatten
|
394
|
+
new_no = Block.new(no.mode,"")
|
395
|
+
|
396
|
+
no.each_inner do |inner|
|
397
|
+
# I read inner, but when I am par, I delete all '.
|
398
|
+
unless (list.include?(inner.name.to_s)) then
|
399
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
400
|
+
list << inner.name.to_s
|
401
|
+
new_block.add_inner(inner.clone)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
end
|
301
405
|
|
302
|
-
|
303
|
-
|
304
|
-
|
406
|
+
no.each_statement do |statement|
|
407
|
+
# If statement is Transmit, it is an expression and should be processed.
|
408
|
+
if statement.is_a?(Transmit) then
|
409
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
410
|
+
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
305
411
|
|
306
|
-
|
307
|
-
# If statement is Transmit, it is an expression and should be processed.
|
308
|
-
if statement.is_a?(Transmit) then
|
309
|
-
# # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
310
|
-
unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
|
311
|
-
# # Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
312
|
-
new_signal = att_signal(statement.left, "#")
|
313
|
-
# Check list and add new variables to inner if they do not duplicate.
|
314
|
-
unless (list.include?(new_signal.name.to_s)) then
|
315
|
-
list << new_signal.name.to_s
|
316
|
-
new_block.add_inner(new_signal)
|
317
|
-
end
|
412
|
+
new_signal = att_signal(statement.left, "#")
|
318
413
|
|
319
|
-
|
414
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
415
|
+
unless (list.include?(new_signal.name.to_s)) then
|
416
|
+
list << new_signal.name.to_s
|
417
|
+
new_block.add_inner(new_signal)
|
418
|
+
end
|
320
419
|
|
321
|
-
|
420
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
322
421
|
|
323
|
-
|
324
|
-
|
422
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
423
|
+
|
424
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
425
|
+
new_no.add_statement(new_statement.clone)
|
426
|
+
else
|
427
|
+
new_no.add_statement(statement.clone)
|
428
|
+
end
|
325
429
|
else
|
326
|
-
|
327
|
-
end
|
328
|
-
else
|
329
|
-
new_when_smt.add_statement(statement.clone)
|
430
|
+
new_no.add_statement(statement.clone)
|
431
|
+
end
|
330
432
|
end
|
331
433
|
end
|
332
434
|
|
333
|
-
|
334
|
-
new_statement.
|
335
|
-
|
435
|
+
# Rebuild the converted "if" as a new" statement (If)".
|
436
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
437
|
+
|
438
|
+
# Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
|
439
|
+
# After that, add the converted "noif" to "If".
|
440
|
+
statement.each_noif do |condition, block|
|
441
|
+
noif = block.flatten
|
442
|
+
new_noif = Block.new(noif.mode,"")
|
443
|
+
|
444
|
+
noif.each_inner do |inner|
|
445
|
+
# I read inner, but when I am par, I delete all '.
|
446
|
+
unless (list.include?(inner.name.to_s)) then
|
447
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
448
|
+
list << inner.name.to_s
|
449
|
+
new_block.add_inner(inner.clone)
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
336
453
|
|
337
|
-
new_block.add_statement(new_statement)
|
338
454
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
455
|
+
noif.each_statement do |statement|
|
456
|
+
# If statement is Transmit, it is an expression and should be processed.
|
457
|
+
if statement.is_a?(Transmit) then
|
458
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
459
|
+
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
344
460
|
|
345
|
-
|
346
|
-
elsif statement.is_a?(If) then
|
347
|
-
yes = statement.yes.flatten # Smooth yes of if statement.
|
348
|
-
new_yes = Block.new(yes.mode,"") # New yes storage block
|
461
|
+
new_signal = att_signal(statement.left, "#")
|
349
462
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
new_block.add_inner(inner.clone)
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
463
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
464
|
+
unless (list.include?(new_signal.name.to_s)) then
|
465
|
+
list << new_signal.name.to_s
|
466
|
+
new_block.add_inner(new_signal)
|
467
|
+
end
|
359
468
|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
new_block.add_inner(new_signal)
|
469
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
470
|
+
|
471
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
472
|
+
|
473
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
474
|
+
new_noif.add_statement(new_statement.clone)
|
475
|
+
else
|
476
|
+
new_noif.add_statement(statement.clone)
|
477
|
+
end
|
478
|
+
else
|
479
|
+
new_noif.add_statement(statement.clone)
|
372
480
|
end
|
481
|
+
end
|
373
482
|
|
374
|
-
|
483
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
484
|
+
end
|
375
485
|
|
376
|
-
|
486
|
+
new_block.add_statement(new_statement.clone)
|
377
487
|
|
378
|
-
|
488
|
+
$fm.rep_sharp.each_key do |key|
|
489
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
490
|
+
new_block.add_statement(new_smt.clone)
|
491
|
+
end
|
492
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
379
493
|
|
494
|
+
# Process when "statement" is "Transmit" (just expression).
|
495
|
+
# Record the expression in fm_par used for par-> seq and add the expression to new_block which is the "new block".
|
496
|
+
elsif statement.is_a?(Transmit) then
|
497
|
+
if self.mode == :seq then
|
498
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = statement.right
|
499
|
+
end
|
500
|
+
new_block.add_statement(statement.clone)
|
380
501
|
|
381
|
-
|
502
|
+
# When statement is Block (lower layer exists).
|
503
|
+
# Smooth the lower layer with do_flat.
|
504
|
+
# Add the added variables (inner) and expressions (statement) to new_block, respectively.
|
505
|
+
elsif statement.is_a?(Block) then
|
506
|
+
smt = statement.do_flat(self.mode)
|
382
507
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
508
|
+
smt.each_inner do |inner|
|
509
|
+
# I read inner, but when I am par, I delete all '.
|
510
|
+
unless (list.include?(inner.name.to_s)) then
|
511
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
512
|
+
list << inner.name.to_s
|
513
|
+
new_block.add_inner(inner.clone)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
smt.each_statement do |tmt|
|
518
|
+
# Retrieve the RefName of the variable on the left side and store it in this_name.
|
519
|
+
if ((tmt.is_a? (Transmit)) && (self.mode == :seq)) then
|
520
|
+
$fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right
|
521
|
+
end
|
522
|
+
new_block.add_statement(tmt.clone)
|
388
523
|
end
|
524
|
+
else
|
525
|
+
# Other statements are simply added as is.
|
526
|
+
new_block.add_statement(statement.clone)
|
389
527
|
end
|
528
|
+
end
|
390
529
|
|
391
|
-
|
392
|
-
# Because error occurs when trying to convert when "else" does not exist.
|
393
|
-
if statement.no.is_a? (Block) then
|
394
|
-
no = statement.no.flatten
|
395
|
-
new_no = Block.new(no.mode,"")
|
530
|
+
return new_block # Return the new_block that completed the smoothing.
|
396
531
|
|
397
|
-
|
532
|
+
# Processing when there is no block beneath.
|
533
|
+
# Unlike ordinary "if" and "case" blocks come down, we check individually block under block.
|
534
|
+
else
|
535
|
+
self.each_statement do |statement|
|
536
|
+
# If the if statement, convert it, otherwise add it as is
|
537
|
+
if statement.is_a?(If) then
|
538
|
+
# Since yes always exists, it is no problem even if it is converted as it is.
|
539
|
+
yes = statement.yes.flatten
|
540
|
+
new_yes = Block.new(yes.mode,"")
|
541
|
+
|
542
|
+
yes.each_inner do |inner|
|
398
543
|
# I read inner, but when I am par, I delete all '.
|
399
544
|
unless (list.include?(inner.name.to_s)) then
|
400
|
-
if (
|
545
|
+
if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
|
401
546
|
list << inner.name.to_s
|
402
547
|
new_block.add_inner(inner.clone)
|
403
548
|
end
|
404
549
|
end
|
405
550
|
end
|
406
551
|
|
407
|
-
|
552
|
+
# Check the statements in "yes" in order.
|
553
|
+
yes.each_statement do |statement|
|
408
554
|
# If statement is Transmit, it is an expression and should be processed.
|
409
555
|
if statement.is_a?(Transmit) then
|
410
556
|
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
411
557
|
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
412
|
-
|
558
|
+
# Generate a new signal to return #.
|
413
559
|
new_signal = att_signal(statement.left, "#")
|
414
560
|
|
415
561
|
# Double declaration of existing variable can not be done, so it is excluded.
|
@@ -423,320 +569,378 @@ class Block
|
|
423
569
|
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
424
570
|
|
425
571
|
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
426
|
-
|
572
|
+
new_yes.add_statement(new_statement.clone)
|
427
573
|
else
|
428
|
-
|
574
|
+
new_yes.add_statement(statement.clone)
|
429
575
|
end
|
430
576
|
else
|
431
|
-
|
577
|
+
new_yes.add_statement(statement.clone)
|
432
578
|
end
|
433
579
|
end
|
434
|
-
end
|
435
580
|
|
436
|
-
|
437
|
-
|
581
|
+
# Confirm that "else" exists and convert it if it exists.
|
582
|
+
# Because error occurs when trying to convert when "else" does not exist.
|
583
|
+
if statement.no.is_a? (Block) then
|
584
|
+
no = statement.no.flatten
|
585
|
+
new_no = Block.new(no.mode,"")
|
586
|
+
|
587
|
+
no.each_inner do |inner|
|
588
|
+
# I read inner, but when I am par, I delete all '.
|
589
|
+
unless (list.include?(inner.name.to_s)) then
|
590
|
+
if (no.mode == :seq) || (inner.name.to_s.include? "#") then
|
591
|
+
list << inner.name.to_s
|
592
|
+
new_block.add_inner(inner.clone)
|
593
|
+
end
|
594
|
+
end
|
595
|
+
end
|
438
596
|
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
597
|
+
no.each_statement do |statement|
|
598
|
+
# If statement is Transmit, it is an expression and should be processed.
|
599
|
+
if statement.is_a?(Transmit) then
|
600
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
601
|
+
unless (res_name(statement.left).name.to_s.include? "'") || no.mode == :par then
|
444
602
|
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
603
|
+
new_signal = att_signal(statement.left, "#")
|
604
|
+
|
605
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
606
|
+
unless (list.include?(new_signal.name.to_s)) then
|
607
|
+
list << new_signal.name.to_s
|
608
|
+
new_block.add_inner(new_signal)
|
609
|
+
end
|
610
|
+
|
611
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
612
|
+
|
613
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
614
|
+
|
615
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
616
|
+
new_no.add_statement(new_statement.clone)
|
617
|
+
else
|
618
|
+
new_no.add_statement(statement.clone)
|
619
|
+
end
|
620
|
+
else
|
621
|
+
new_no.add_statement(statement.clone)
|
622
|
+
end
|
452
623
|
end
|
453
624
|
end
|
625
|
+
# Rebuild the converted "if" as a new" statement (If)".
|
626
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
627
|
+
# Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
|
628
|
+
# After that, add the converted "noif" to "If".
|
629
|
+
statement.each_noif do |condition, block|
|
630
|
+
|
631
|
+
noif = block.flatten
|
632
|
+
new_noif = Block.new(noif.mode,"")
|
633
|
+
|
634
|
+
noif.each_inner do |inner|
|
635
|
+
# I read inner, but when I am par, I delete all '.
|
636
|
+
unless (list.include?(inner.name.to_s)) then
|
637
|
+
if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
|
638
|
+
list << inner.name.to_s
|
639
|
+
new_block.add_inner(inner.clone)
|
640
|
+
end
|
641
|
+
end
|
642
|
+
end
|
454
643
|
|
455
644
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
645
|
+
noif.each_statement do |statement|
|
646
|
+
# If statement is Transmit, it is an expression and should be processed.
|
647
|
+
if statement.is_a?(Transmit) then
|
648
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
649
|
+
unless (res_name(statement.left).name.to_s.include? "'") || noif.mode == :par then
|
461
650
|
|
462
|
-
|
651
|
+
new_signal = att_signal(statement.left, "#")
|
463
652
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
653
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
654
|
+
unless (list.include?(new_signal.name.to_s)) then
|
655
|
+
list << new_signal.name.to_s
|
656
|
+
new_block.add_inner(new_signal)
|
657
|
+
end
|
469
658
|
|
470
|
-
|
659
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
471
660
|
|
472
|
-
|
661
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
473
662
|
|
474
|
-
|
475
|
-
|
663
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
664
|
+
new_noif.add_statement(new_statement.clone)
|
665
|
+
else
|
666
|
+
new_noif.add_statement(statement.clone)
|
667
|
+
end
|
476
668
|
else
|
477
669
|
new_noif.add_statement(statement.clone)
|
478
|
-
end
|
479
|
-
else
|
480
|
-
new_noif.add_statement(statement.clone)
|
670
|
+
end
|
481
671
|
end
|
482
|
-
end
|
483
672
|
|
484
|
-
|
485
|
-
|
673
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
674
|
+
end
|
486
675
|
|
487
|
-
|
676
|
+
new_block.add_statement(new_statement.clone)
|
488
677
|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
678
|
+
$fm.rep_sharp.each_key do |key|
|
679
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
680
|
+
new_block.add_statement(new_smt.clone)
|
681
|
+
end
|
682
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
494
683
|
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
$fm.fm_par["#{statement.left.to_verilog}"] = statement.right
|
500
|
-
end
|
501
|
-
new_block.add_statement(statement.clone)
|
684
|
+
elsif statement.is_a?(Case) then
|
685
|
+
if statement.default.is_a?(Block)
|
686
|
+
new_default = statement.default.flatten
|
687
|
+
end
|
502
688
|
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
smt = statement.do_flat(self.mode)
|
689
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
690
|
+
statement.each_when do |whens|
|
691
|
+
new_when_statement = whens.statement.flatten
|
692
|
+
new_when = When.new(whens.match.clone,new_when_statement.clone)
|
508
693
|
|
509
|
-
|
510
|
-
# I read inner, but when I am par, I delete all '.
|
511
|
-
unless (list.include?(inner.name.to_s)) then
|
512
|
-
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
513
|
-
list << inner.name.to_s
|
514
|
-
new_block.add_inner(inner.clone)
|
515
|
-
end
|
694
|
+
new_statement.add_when(new_when.clone)
|
516
695
|
end
|
696
|
+
|
697
|
+
new_block.add_statement(new_statement)
|
698
|
+
else
|
699
|
+
new_block.add_statement(statement.clone)
|
517
700
|
end
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
701
|
+
end
|
702
|
+
return new_block
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
706
|
+
def do_flat(mode = nil)
|
707
|
+
flat = Block.new(self.mode,"") # Block between lower layers when converting.
|
708
|
+
trans = Block.new(self.mode,"") # The block used for converting itself.
|
709
|
+
replase = Block.new(self.mode,"") # block to be used for further conversion in case of if statement.
|
710
|
+
list = []
|
711
|
+
rep_list = []
|
712
|
+
|
713
|
+
# If there is a block inside the statement it is not the lowest layer. If there is, it is the lowest layer.
|
714
|
+
if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)} || (self.each_statement.find {|stmnt| stmnt.is_a?(If)}) || (self.each_statement.find {|stmnt| stmnt.is_a?(Case)}))then
|
715
|
+
# In the case of seq, the lower layer is par. Isolate fm_par so that it is not crosstalked.
|
716
|
+
if(self.mode == :seq) then
|
717
|
+
fm_buckup = $fm.fm_par.clone
|
718
|
+
$fm.fm_par.clear()
|
719
|
+
|
720
|
+
new_block = change_branch(self)
|
525
721
|
else
|
526
|
-
|
527
|
-
new_block.add_statement(statement.clone)
|
722
|
+
new_block = self.clone
|
528
723
|
end
|
529
|
-
end
|
530
724
|
|
531
|
-
|
725
|
+
# Process for each statement.
|
726
|
+
new_block.each_statement do |statement|
|
727
|
+
# If statement is If, convert yes, no, noif and add them to flat.
|
728
|
+
if statement.is_a?(Case) then
|
729
|
+
if(self.mode == :seq) then
|
730
|
+
fm_buckup_if = $fm.fm_par.clone
|
731
|
+
end
|
532
732
|
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
yes = statement.yes.flatten
|
541
|
-
new_yes = Block.new(yes.mode,"")
|
542
|
-
|
543
|
-
yes.each_inner do |inner|
|
544
|
-
# I read inner, but when I am par, I delete all '.
|
545
|
-
unless (list.include?(inner.name.to_s)) then
|
546
|
-
if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
|
547
|
-
list << inner.name.to_s
|
548
|
-
new_block.add_inner(inner.clone)
|
549
|
-
end
|
733
|
+
if statement.default.is_a?(Block)
|
734
|
+
default = statement.default.flatten
|
735
|
+
new_default = Block.new(default.mode,"")
|
736
|
+
|
737
|
+
default.each_statement do |statement|
|
738
|
+
new_default.add_statement(statement.clone)
|
739
|
+
end
|
550
740
|
end
|
551
|
-
end
|
552
741
|
|
553
|
-
# Check the statements in "yes" in order.
|
554
|
-
yes.each_statement do |statement|
|
555
|
-
# If statement is Transmit, it is an expression and should be processed.
|
556
|
-
if statement.is_a?(Transmit) then
|
557
|
-
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
558
|
-
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
559
|
-
# Generate a new signal to return #.
|
560
|
-
new_signal = att_signal(statement.left, "#")
|
561
742
|
|
562
|
-
|
563
|
-
unless (list.include?(new_signal.name.to_s)) then
|
564
|
-
list << new_signal.name.to_s
|
565
|
-
new_block.add_inner(new_signal)
|
566
|
-
end
|
743
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
567
744
|
|
568
|
-
|
745
|
+
statement.each_when do |whens|
|
746
|
+
if(self.mode == :seq) then
|
747
|
+
fm_buckup_if.each_key do |key|
|
748
|
+
$fm.fm_par[key] = fm_buckup_if[key]
|
749
|
+
end
|
750
|
+
end
|
569
751
|
|
570
|
-
|
752
|
+
when_smt = whens.statement.flatten
|
753
|
+
new_when = When.new(whens.match.clone,when_smt.clone)
|
754
|
+
new_statement.add_when(new_when.clone)
|
755
|
+
end
|
756
|
+
flat.add_statement(new_statement)
|
571
757
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
new_yes.add_statement(statement.clone)
|
576
|
-
end
|
577
|
-
else
|
578
|
-
new_yes.add_statement(statement.clone)
|
758
|
+
elsif statement.is_a?(If) then
|
759
|
+
if(self.mode == :seq) then
|
760
|
+
fm_buckup_if = $fm.fm_par.clone
|
579
761
|
end
|
580
|
-
end
|
581
762
|
|
582
|
-
|
583
|
-
|
584
|
-
if statement.no.is_a? (Block) then
|
585
|
-
no = statement.no.flatten
|
586
|
-
new_no = Block.new(no.mode,"")
|
763
|
+
# Since yes always exist, convert without confirming.
|
764
|
+
new_yes = statement.yes.flatten
|
587
765
|
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
end
|
766
|
+
# I do not know whether no (else) exists, so convert it if it is confirmed.
|
767
|
+
if statement.no.is_a? (Block) then
|
768
|
+
|
769
|
+
if(self.mode == :seq) then
|
770
|
+
fm_buckup_if.each_key do |key|
|
771
|
+
$fm.fm_par[key] = fm_buckup_if[key]
|
772
|
+
end
|
595
773
|
end
|
774
|
+
|
775
|
+
new_no = statement.no.flatten
|
596
776
|
end
|
777
|
+
# Create a new if statement with converted yes and no.
|
778
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
779
|
+
|
780
|
+
# Since I do not know whether there is noifs (elsif), I convert it and add it if it is confirmed.
|
781
|
+
statement.each_noif do |condition, block|
|
782
|
+
if(self.mode == :seq) then
|
783
|
+
fm_buckup_if.each_key do |key|
|
784
|
+
$fm.fm_par[key] = fm_buckup_if[key]
|
785
|
+
end
|
786
|
+
end
|
597
787
|
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
788
|
+
new_noif = block.flatten
|
789
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
790
|
+
end
|
791
|
+
# Add the new statement (if statement) created to flat.
|
792
|
+
flat.add_statement(new_statement.clone)
|
603
793
|
|
604
|
-
|
794
|
+
# If statement is Transmit, record the expression in fm_par and add the expression to flat as it is.
|
795
|
+
elsif statement.is_a?(Transmit) then
|
796
|
+
if(self.mode == :seq) then
|
797
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = statement.right.clone
|
798
|
+
end
|
605
799
|
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
800
|
+
flat.add_statement(statement.clone)
|
801
|
+
# If statement is Block, convert it with do_flat and add the returned expression and variable to flat respectively.
|
802
|
+
|
803
|
+
elsif statement.is_a?(Block) then
|
804
|
+
smt = statement.do_flat(self.mode)
|
805
|
+
# If smt has inner, check it separately and add it if it's convenient.
|
806
|
+
smt.each_inner do |inner|
|
807
|
+
if self.mode == :seq then
|
808
|
+
unless (list.include?(inner.name.to_s)) then
|
809
|
+
list << inner.name.to_s
|
810
|
+
flat.add_inner(inner.clone)
|
811
|
+
end
|
812
|
+
else
|
813
|
+
unless (list.include?(inner.name.to_s)) then
|
814
|
+
if(inner.name.to_s.include? "#") then
|
815
|
+
list << inner.name.to_s
|
816
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
610
817
|
end
|
818
|
+
end
|
819
|
+
end
|
820
|
+
end
|
821
|
+
# If it is seq, the expression after conversion is also likely to be used, so record the expression.
|
822
|
+
smt.each_statement do |tmt|
|
823
|
+
if self.mode == :seq then
|
824
|
+
$fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right.clone
|
825
|
+
end
|
826
|
+
flat.add_statement(tmt.clone)
|
827
|
+
end
|
828
|
+
end
|
829
|
+
end
|
611
830
|
|
612
|
-
|
831
|
+
# Overwrite to restore fm_par which was quarantined.
|
832
|
+
if(self.mode == :seq) then
|
833
|
+
$fm.fm_par.clear()
|
834
|
+
fm_buckup.each_key do |key|
|
835
|
+
$fm.fm_par[key] = fm_buckup[key]
|
836
|
+
end
|
837
|
+
end
|
613
838
|
|
614
|
-
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
615
839
|
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
840
|
+
|
841
|
+
# Since it is a middle tier itself, it performs flat transformation, shifts inner, and returns the result.
|
842
|
+
trans = flat.to_conversion(mode)
|
843
|
+
|
844
|
+
|
845
|
+
# Write an expression that assigns an identifier that added # to an identifier that has not added.
|
846
|
+
trans.each_statement do |statement|
|
847
|
+
replase.add_statement(statement.clone)
|
848
|
+
if statement.is_a?(If)
|
849
|
+
$fm.rep_sharp.each_key do |key|
|
850
|
+
new_statement = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
851
|
+
replase.add_statement(new_statement.clone)
|
624
852
|
end
|
853
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
625
854
|
end
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
855
|
+
end
|
856
|
+
|
857
|
+
# Extract the inner left in flat and add it to replase.
|
858
|
+
flat.each_inner do |inner|
|
859
|
+
replase.add_inner(inner.clone)
|
860
|
+
end
|
861
|
+
|
862
|
+
# Extract the inner left in trans and add it to replase.
|
863
|
+
trans.each_inner do |inner|
|
864
|
+
replase.add_inner(inner.clone)
|
865
|
+
end
|
866
|
+
|
867
|
+
return replase
|
868
|
+
|
869
|
+
# Processing when there is no block (reaching the bottom layer).
|
870
|
+
else
|
871
|
+
# Since it is the lowest layer, it does not smooth but converts itself and returns it.
|
872
|
+
flat = self.to_conversion(mode)
|
873
|
+
return flat
|
874
|
+
end
|
875
|
+
end
|
631
876
|
|
632
|
-
|
633
|
-
|
877
|
+
def to_conversion(mode = nil, rst = true, rep = true)
|
878
|
+
flat = Block.new(mode,"") # Block that stores results.
|
879
|
+
new_yes = Block.new(mode,"") # Block containing the new yes.
|
880
|
+
new_no = Block.new(mode,"") # Block containing the new no.
|
881
|
+
new_noif = Block.new(mode,"") # Block containing the new noif.
|
882
|
+
list = []
|
883
|
+
|
884
|
+
if rst == false then
|
885
|
+
fm_seq_backup = $fm.fm_seq.dup
|
886
|
+
end
|
887
|
+
|
888
|
+
# The statement is divided (since it is the lowest layer, there is only Transmit).
|
889
|
+
self.each_statement do |statement|
|
890
|
+
# Various processing is performed depending on the type of Transmit.
|
891
|
+
# If the mode of the upper layer = its own mode, it compresses as it is.
|
892
|
+
|
893
|
+
if(mode == self.mode) then
|
894
|
+
new_statement = statement.clone
|
895
|
+
# In the case of an If statement, processing of if, else, elsif is performed.
|
896
|
+
elsif statement.is_a?(Case) then
|
634
897
|
|
635
|
-
|
898
|
+
if statement.default.is_a?(Block)
|
899
|
+
rep_buckup = $fm.rep.dup
|
900
|
+
$fm.rep.clear()
|
901
|
+
default = statement.default.to_conversion(mode,false,false)
|
902
|
+
$fm.rep.clear()
|
903
|
+
rep_buckup.each_key do |key|
|
904
|
+
$fm.rep[key] = rep_buckup[key]
|
905
|
+
end
|
906
|
+
|
907
|
+
new_default = Block.new(default.mode,"")
|
908
|
+
|
909
|
+
default.each_inner do |inner|
|
636
910
|
# I read inner, but when I am par, I delete all '.
|
637
911
|
unless (list.include?(inner.name.to_s)) then
|
638
|
-
if (
|
912
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
639
913
|
list << inner.name.to_s
|
640
|
-
|
914
|
+
flat.add_inner(inner.clone)
|
641
915
|
end
|
642
916
|
end
|
643
917
|
end
|
644
918
|
|
645
|
-
|
646
|
-
noif.each_statement do |statement|
|
919
|
+
default.each_statement do |statement|
|
647
920
|
# If statement is Transmit, it is an expression and should be processed.
|
648
921
|
if statement.is_a?(Transmit) then
|
649
922
|
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
650
|
-
unless (res_name(statement.left).name.to_s.include? "'") ||
|
651
|
-
|
923
|
+
unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
|
924
|
+
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
652
925
|
new_signal = att_signal(statement.left, "#")
|
653
|
-
|
654
|
-
# Double declaration of existing variable can not be done, so it is excluded.
|
926
|
+
# Check list and add new variables to inner if they do not duplicate.
|
655
927
|
unless (list.include?(new_signal.name.to_s)) then
|
656
928
|
list << new_signal.name.to_s
|
657
|
-
|
929
|
+
flat.add_inner(new_signal)
|
658
930
|
end
|
659
931
|
|
660
|
-
|
932
|
+
new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
661
933
|
|
662
934
|
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
663
935
|
|
664
|
-
$fm.fm_par["#{statement.left.to_verilog}"] =
|
665
|
-
|
936
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
|
937
|
+
new_default.add_statement(new_smt.clone)
|
666
938
|
else
|
667
|
-
|
939
|
+
new_default.add_statement(statement.clone)
|
668
940
|
end
|
669
941
|
else
|
670
|
-
|
942
|
+
new_default.add_statement(statement.clone)
|
671
943
|
end
|
672
|
-
end
|
673
|
-
|
674
|
-
new_statement.add_noif(condition.clone,new_noif.clone)
|
675
|
-
end
|
676
|
-
|
677
|
-
new_block.add_statement(new_statement.clone)
|
678
|
-
|
679
|
-
$fm.rep_sharp.each_key do |key|
|
680
|
-
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
681
|
-
new_block.add_statement(new_smt.clone)
|
682
|
-
end
|
683
|
-
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
684
|
-
|
685
|
-
elsif statement.is_a?(Case) then
|
686
|
-
if statement.default.is_a?(Block)
|
687
|
-
new_default = statement.default.flatten
|
688
|
-
end
|
689
|
-
|
690
|
-
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
691
|
-
statement.each_when do |whens|
|
692
|
-
new_when_statement = whens.statement.flatten
|
693
|
-
new_when = When.new(whens.match.clone,new_when_statement.clone)
|
694
|
-
|
695
|
-
new_statement.add_when(new_when.clone)
|
696
|
-
end
|
697
|
-
|
698
|
-
new_block.add_statement(new_statement)
|
699
|
-
else
|
700
|
-
new_block.add_statement(statement.clone)
|
701
|
-
end
|
702
|
-
end
|
703
|
-
return new_block
|
704
|
-
end
|
705
|
-
end
|
706
|
-
|
707
|
-
def do_flat(mode = nil)
|
708
|
-
flat = Block.new(self.mode,"") # Block between lower layers when converting.
|
709
|
-
trans = Block.new(self.mode,"") # The block used for converting itself.
|
710
|
-
replase = Block.new(self.mode,"") # block to be used for further conversion in case of if statement.
|
711
|
-
list = []
|
712
|
-
rep_list = []
|
713
|
-
|
714
|
-
# If there is a block inside the statement it is not the lowest layer. If there is, it is the lowest layer.
|
715
|
-
if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)} || (self.each_statement.find {|stmnt| stmnt.is_a?(If)}) || (self.each_statement.find {|stmnt| stmnt.is_a?(Case)}))then
|
716
|
-
# In the case of seq, the lower layer is par. Isolate fm_par so that it is not crosstalked.
|
717
|
-
if(self.mode == :seq) then
|
718
|
-
fm_buckup = $fm.fm_par.clone
|
719
|
-
$fm.fm_par.clear()
|
720
|
-
|
721
|
-
new_block = change_branch(self)
|
722
|
-
else
|
723
|
-
new_block = self.clone
|
724
|
-
end
|
725
|
-
|
726
|
-
# Process for each statement.
|
727
|
-
new_block.each_statement do |statement|
|
728
|
-
# If statement is If, convert yes, no, noif and add them to flat.
|
729
|
-
if statement.is_a?(Case) then
|
730
|
-
if(self.mode == :seq) then
|
731
|
-
fm_buckup_if = $fm.fm_par.clone
|
732
|
-
end
|
733
|
-
|
734
|
-
if statement.default.is_a?(Block)
|
735
|
-
default = statement.default.flatten
|
736
|
-
new_default = Block.new(default.mode,"")
|
737
|
-
|
738
|
-
default.each_statement do |statement|
|
739
|
-
new_default.add_statement(statement.clone)
|
740
944
|
end
|
741
945
|
end
|
742
946
|
|
@@ -744,1501 +948,1165 @@ class Block
|
|
744
948
|
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
745
949
|
|
746
950
|
statement.each_when do |whens|
|
747
|
-
if(self.mode == :seq) then
|
748
|
-
fm_buckup_if.each_key do |key|
|
749
|
-
$fm.fm_par[key] = fm_buckup_if[key]
|
750
|
-
end
|
751
|
-
end
|
752
951
|
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
elsif statement.is_a?(If) then
|
760
|
-
if(self.mode == :seq) then
|
761
|
-
fm_buckup_if = $fm.fm_par.clone
|
762
|
-
end
|
763
|
-
|
764
|
-
# Since yes always exist, convert without confirming.
|
765
|
-
new_yes = statement.yes.flatten
|
766
|
-
|
767
|
-
# I do not know whether no (else) exists, so convert it if it is confirmed.
|
768
|
-
if statement.no.is_a? (Block) then
|
769
|
-
|
770
|
-
if(self.mode == :seq) then
|
771
|
-
fm_buckup_if.each_key do |key|
|
772
|
-
$fm.fm_par[key] = fm_buckup_if[key]
|
773
|
-
end
|
952
|
+
rep_buckup = $fm.rep.dup
|
953
|
+
$fm.rep.clear()
|
954
|
+
when_smt = whens.statement.to_conversion(mode,false,false)
|
955
|
+
$fm.rep.clear()
|
956
|
+
rep_buckup.each_key do |key|
|
957
|
+
$fm.rep[key] = rep_buckup[key]
|
774
958
|
end
|
775
959
|
|
776
|
-
|
777
|
-
end
|
778
|
-
# Create a new if statement with converted yes and no.
|
779
|
-
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
780
|
-
|
781
|
-
# Since I do not know whether there is noifs (elsif), I convert it and add it if it is confirmed.
|
782
|
-
statement.each_noif do |condition, block|
|
783
|
-
if(self.mode == :seq) then
|
784
|
-
fm_buckup_if.each_key do |key|
|
785
|
-
$fm.fm_par[key] = fm_buckup_if[key]
|
786
|
-
end
|
787
|
-
end
|
960
|
+
new_when_smt = Block.new(when_smt.mode,"")
|
788
961
|
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
962
|
+
when_smt.each_statement do |statement|
|
963
|
+
# If statement is Transmit, it is an expression and should be processed.
|
964
|
+
if statement.is_a?(Transmit) then
|
965
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
966
|
+
unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
|
967
|
+
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
968
|
+
new_signal = att_signal(statement.left, "#")
|
969
|
+
# Check list and add new variables to inner if they do not duplicate.
|
970
|
+
unless (list.include?(new_signal.name.to_s)) then
|
971
|
+
list << new_signal.name.to_s
|
972
|
+
flat.add_inner(new_signal)
|
973
|
+
end
|
794
974
|
|
795
|
-
|
796
|
-
elsif statement.is_a?(Transmit) then
|
797
|
-
if(self.mode == :seq) then
|
798
|
-
$fm.fm_par["#{statement.left.to_verilog}"] = statement.right.clone
|
799
|
-
end
|
975
|
+
new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
800
976
|
|
801
|
-
|
802
|
-
# If statement is Block, convert it with do_flat and add the returned expression and variable to flat respectively.
|
977
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
803
978
|
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
flat.add_inner(inner.clone)
|
979
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
|
980
|
+
new_when_smt.add_statement(new_smt.clone)
|
981
|
+
else
|
982
|
+
new_when_smt.add_statement(statement.clone)
|
983
|
+
end
|
984
|
+
else
|
985
|
+
new_when_smt.add_statement(statement.clone)
|
812
986
|
end
|
813
|
-
else
|
814
|
-
unless (list.include?(inner.name.to_s)) then
|
815
|
-
if(inner.name.to_s.include? "#") then
|
816
|
-
list << inner.name.to_s
|
817
|
-
flat.add_inner(inner.clone) # It was new_block. why?
|
818
|
-
end
|
819
|
-
end
|
820
987
|
end
|
821
|
-
end
|
822
|
-
# If it is seq, the expression after conversion is also likely to be used, so record the expression.
|
823
|
-
smt.each_statement do |tmt|
|
824
|
-
if self.mode == :seq then
|
825
|
-
$fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right.clone
|
826
|
-
end
|
827
|
-
flat.add_statement(tmt.clone)
|
828
|
-
end
|
829
|
-
end
|
830
|
-
end
|
831
|
-
|
832
|
-
# Overwrite to restore fm_par which was quarantined.
|
833
|
-
if(self.mode == :seq) then
|
834
|
-
$fm.fm_par.clear()
|
835
|
-
fm_buckup.each_key do |key|
|
836
|
-
$fm.fm_par[key] = fm_buckup[key]
|
837
|
-
end
|
838
|
-
end
|
839
|
-
|
840
988
|
|
841
|
-
|
842
|
-
|
843
|
-
trans = flat.to_conversion(mode)
|
844
|
-
|
845
|
-
|
846
|
-
# Write an expression that assigns an identifier that added # to an identifier that has not added.
|
847
|
-
trans.each_statement do |statement|
|
848
|
-
replase.add_statement(statement.clone)
|
849
|
-
if statement.is_a?(If)
|
850
|
-
$fm.rep_sharp.each_key do |key|
|
851
|
-
new_statement = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
852
|
-
replase.add_statement(new_statement.clone)
|
989
|
+
new_when = When.new(whens.match.clone,new_when_smt.clone)
|
990
|
+
new_statement.add_when(new_when.clone)
|
853
991
|
end
|
854
|
-
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
855
|
-
end
|
856
|
-
end
|
857
|
-
|
858
|
-
# Extract the inner left in flat and add it to replase.
|
859
|
-
flat.each_inner do |inner|
|
860
|
-
replase.add_inner(inner.clone)
|
861
|
-
end
|
862
|
-
|
863
|
-
# Extract the inner left in trans and add it to replase.
|
864
|
-
trans.each_inner do |inner|
|
865
|
-
replase.add_inner(inner.clone)
|
866
|
-
end
|
867
|
-
|
868
|
-
return replase
|
869
|
-
|
870
|
-
# Processing when there is no block (reaching the bottom layer).
|
871
|
-
else
|
872
|
-
# Since it is the lowest layer, it does not smooth but converts itself and returns it.
|
873
|
-
flat = self.to_conversion(mode)
|
874
|
-
return flat
|
875
|
-
end
|
876
|
-
end
|
877
992
|
|
878
|
-
|
879
|
-
flat = Block.new(mode,"") # Block that stores results.
|
880
|
-
new_yes = Block.new(mode,"") # Block containing the new yes.
|
881
|
-
new_no = Block.new(mode,"") # Block containing the new no.
|
882
|
-
new_noif = Block.new(mode,"") # Block containing the new noif.
|
883
|
-
list = []
|
884
|
-
|
885
|
-
if rst == false then
|
886
|
-
fm_seq_backup = $fm.fm_seq.dup
|
887
|
-
end
|
888
|
-
|
889
|
-
# The statement is divided (since it is the lowest layer, there is only Transmit).
|
890
|
-
self.each_statement do |statement|
|
891
|
-
# Various processing is performed depending on the type of Transmit.
|
892
|
-
# If the mode of the upper layer = its own mode, it compresses as it is.
|
893
|
-
|
894
|
-
if(mode == self.mode) then
|
895
|
-
new_statement = statement.clone
|
896
|
-
# In the case of an If statement, processing of if, else, elsif is performed.
|
897
|
-
elsif statement.is_a?(Case) then
|
993
|
+
elsif statement.is_a?(If) then
|
898
994
|
|
899
|
-
if statement.default.is_a?(Block)
|
900
995
|
rep_buckup = $fm.rep.dup
|
901
996
|
$fm.rep.clear()
|
902
|
-
|
997
|
+
yes = statement.yes.to_conversion(mode, false,false)
|
903
998
|
$fm.rep.clear()
|
904
999
|
rep_buckup.each_key do |key|
|
905
1000
|
$fm.rep[key] = rep_buckup[key]
|
906
1001
|
end
|
907
1002
|
|
908
|
-
|
909
|
-
|
910
|
-
default.each_inner do |inner|
|
911
|
-
# I read inner, but when I am par, I delete all '.
|
1003
|
+
yes.each_inner do |inner|
|
912
1004
|
unless (list.include?(inner.name.to_s)) then
|
913
|
-
if (
|
1005
|
+
if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
|
914
1006
|
list << inner.name.to_s
|
915
|
-
flat.add_inner(inner.clone)
|
1007
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
916
1008
|
end
|
917
1009
|
end
|
918
1010
|
end
|
919
1011
|
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
924
|
-
unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
|
925
|
-
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
926
|
-
new_signal = att_signal(statement.left, "#")
|
927
|
-
# Check list and add new variables to inner if they do not duplicate.
|
928
|
-
unless (list.include?(new_signal.name.to_s)) then
|
929
|
-
list << new_signal.name.to_s
|
930
|
-
flat.add_inner(new_signal)
|
931
|
-
end
|
1012
|
+
yes.each_statement do |smt|
|
1013
|
+
if(yes.mode == :seq) then
|
1014
|
+
new_signal = att_signal(smt.left, "#")
|
932
1015
|
|
933
|
-
|
1016
|
+
unless (list.include?(new_signal.name.to_s)) then
|
1017
|
+
list << new_signal.name.to_s
|
1018
|
+
flat.add_inner(new_signal)
|
1019
|
+
end
|
934
1020
|
|
935
|
-
|
1021
|
+
yes_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
|
936
1022
|
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
end
|
1023
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
1024
|
+
|
1025
|
+
$fm.fm_par["#{smt.left.to_verilog}"] = yes_statement.left
|
1026
|
+
new_yes.add_statement(yes_statement)
|
942
1027
|
else
|
943
|
-
|
1028
|
+
new_yes.add_statement(smt.clone)
|
944
1029
|
end
|
945
|
-
end
|
946
|
-
end
|
947
|
-
|
948
|
-
|
949
|
-
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
1030
|
+
end
|
950
1031
|
|
951
|
-
|
1032
|
+
if statement.no.is_a? (Block) then
|
1033
|
+
rep_buckup = $fm.rep.dup
|
1034
|
+
$fm.rep.clear()
|
1035
|
+
no = statement.no.to_conversion(mode,false,false)
|
1036
|
+
$fm.rep.clear()
|
1037
|
+
rep_buckup.each_key do |key|
|
1038
|
+
$fm.rep[key] = rep_buckup[key]
|
1039
|
+
end
|
952
1040
|
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
1041
|
+
no.each_inner do |inner|
|
1042
|
+
unless (list.include?(inner.name.to_s)) then
|
1043
|
+
if (no.mode == :seq) || (inner.name.to_s.include? "#") then
|
1044
|
+
list << inner.name.to_s
|
1045
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
1046
|
+
end
|
1047
|
+
end
|
1048
|
+
end
|
960
1049
|
|
961
|
-
|
1050
|
+
no.each_statement do |smt|
|
1051
|
+
if(no.mode == :seq) then
|
1052
|
+
new_signal = att_signal(smt.left, "#")
|
962
1053
|
|
963
|
-
when_smt.each_statement do |statement|
|
964
|
-
# If statement is Transmit, it is an expression and should be processed.
|
965
|
-
if statement.is_a?(Transmit) then
|
966
|
-
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
967
|
-
unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
|
968
|
-
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
969
|
-
new_signal = att_signal(statement.left, "#")
|
970
|
-
# Check list and add new variables to inner if they do not duplicate.
|
971
1054
|
unless (list.include?(new_signal.name.to_s)) then
|
972
1055
|
list << new_signal.name.to_s
|
973
1056
|
flat.add_inner(new_signal)
|
974
1057
|
end
|
975
1058
|
|
976
|
-
|
1059
|
+
no_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
|
977
1060
|
|
978
1061
|
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
979
1062
|
|
980
|
-
$fm.fm_par["#{
|
981
|
-
|
1063
|
+
$fm.fm_par["#{smt.left.to_verilog}"] = no_statement.left
|
1064
|
+
new_no.add_statement(no_statement)
|
982
1065
|
else
|
983
|
-
|
984
|
-
end
|
985
|
-
else
|
986
|
-
new_when_smt.add_statement(statement.clone)
|
1066
|
+
new_no.add_statement(smt.clone)
|
1067
|
+
end
|
987
1068
|
end
|
988
1069
|
end
|
989
1070
|
|
990
|
-
|
991
|
-
new_statement.add_when(new_when.clone)
|
992
|
-
end
|
993
|
-
|
994
|
-
elsif statement.is_a?(If) then
|
995
|
-
|
996
|
-
rep_buckup = $fm.rep.dup
|
997
|
-
$fm.rep.clear()
|
998
|
-
yes = statement.yes.to_conversion(mode, false,false)
|
999
|
-
$fm.rep.clear()
|
1000
|
-
rep_buckup.each_key do |key|
|
1001
|
-
$fm.rep[key] = rep_buckup[key]
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
yes.each_inner do |inner|
|
1005
|
-
unless (list.include?(inner.name.to_s)) then
|
1006
|
-
if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
|
1007
|
-
list << inner.name.to_s
|
1008
|
-
flat.add_inner(inner.clone) # It was new_block. why?
|
1009
|
-
end
|
1010
|
-
end
|
1011
|
-
end
|
1071
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
1012
1072
|
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1073
|
+
statement.each_noif do |condition, block|
|
1074
|
+
rep_buckup = $fm.rep.dup
|
1075
|
+
$fm.rep.clear()
|
1076
|
+
noif = block.to_conversion(mode,false,false)
|
1077
|
+
$fm.rep.clear()
|
1078
|
+
rep_buckup.each_key do |key|
|
1079
|
+
$fm.rep[key] = rep_buckup[key]
|
1080
|
+
end
|
1016
1081
|
|
1017
|
-
|
1018
|
-
list
|
1019
|
-
|
1082
|
+
noif.each_inner do |inner|
|
1083
|
+
unless (list.include?(inner.name.to_s)) then
|
1084
|
+
if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
|
1085
|
+
list << inner.name.to_s
|
1086
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
1087
|
+
end
|
1088
|
+
end
|
1020
1089
|
end
|
1021
1090
|
|
1022
|
-
|
1091
|
+
noif.each_statement do |smt|
|
1092
|
+
if(noif.mode == :seq) then
|
1093
|
+
new_signal = att_signal(smt.left, "#")
|
1023
1094
|
|
1024
|
-
|
1095
|
+
unless (list.include?(new_signal.name.to_s)) then
|
1096
|
+
list << new_signal.name.to_s
|
1097
|
+
flat.add_inner(new_signal)
|
1098
|
+
end
|
1025
1099
|
|
1026
|
-
|
1027
|
-
new_yes.add_statement(yes_statement)
|
1028
|
-
else
|
1029
|
-
new_yes.add_statement(smt.clone)
|
1030
|
-
end
|
1031
|
-
end
|
1100
|
+
noif_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
|
1032
1101
|
|
1033
|
-
|
1034
|
-
rep_buckup = $fm.rep.dup
|
1035
|
-
$fm.rep.clear()
|
1036
|
-
no = statement.no.to_conversion(mode,false,false)
|
1037
|
-
$fm.rep.clear()
|
1038
|
-
rep_buckup.each_key do |key|
|
1039
|
-
$fm.rep[key] = rep_buckup[key]
|
1040
|
-
end
|
1102
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
1041
1103
|
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
end
|
1104
|
+
$fm.fm_par["#{smt.left.to_verilog}"] = noif_statement.left
|
1105
|
+
new_noif.add_statement(no_statement)
|
1106
|
+
else
|
1107
|
+
new_noif.add_statement(smt.clone)
|
1108
|
+
end
|
1048
1109
|
end
|
1049
|
-
end
|
1050
1110
|
|
1051
|
-
|
1052
|
-
|
1053
|
-
new_signal = att_signal(smt.left, "#")
|
1111
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
1112
|
+
end
|
1054
1113
|
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1114
|
+
# Otherwise, it is necessary to process par-> seq or seq-> par.
|
1115
|
+
else
|
1116
|
+
# Make sure the right side is a formula (Binary).
|
1117
|
+
if statement.right.is_a?(Binary) then
|
1118
|
+
# Check the right side and the left side, and if they are variables, check the corresponding expressions and replace them.
|
1119
|
+
# If it is not a variable, it calls the method to be searched.
|
1120
|
+
if statement.right.left.is_a? (Ref) then
|
1121
|
+
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.left.to_verilog) then
|
1122
|
+
statement_left = $fm.fm_seq["#{statement.right.left.to_verilog}"]
|
1123
|
+
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.left.to_verilog) then
|
1124
|
+
statement_left = $fm.fm_par["#{statement.right.left.to_verilog}"]
|
1125
|
+
else
|
1126
|
+
statement_left = statement.right.left.clone
|
1058
1127
|
end
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
1063
|
-
|
1064
|
-
$fm.fm_par["#{smt.left.to_verilog}"] = no_statement.left
|
1065
|
-
new_no.add_statement(no_statement)
|
1128
|
+
elsif statement.right.left.is_a? (Binary) then
|
1129
|
+
statement_left = statement.right.left.to_change(self.mode)
|
1066
1130
|
else
|
1067
|
-
|
1131
|
+
statement_left = statement.right.left.clone
|
1068
1132
|
end
|
1069
|
-
end
|
1070
|
-
end
|
1071
|
-
|
1072
|
-
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
1073
|
-
|
1074
|
-
statement.each_noif do |condition, block|
|
1075
|
-
rep_buckup = $fm.rep.dup
|
1076
|
-
$fm.rep.clear()
|
1077
|
-
noif = block.to_conversion(mode,false,false)
|
1078
|
-
$fm.rep.clear()
|
1079
|
-
rep_buckup.each_key do |key|
|
1080
|
-
$fm.rep[key] = rep_buckup[key]
|
1081
|
-
end
|
1082
1133
|
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1134
|
+
if statement.right.right.is_a? (Ref) then
|
1135
|
+
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.right.to_verilog) then
|
1136
|
+
statement_right = $fm.fm_seq["#{statement.right.right.to_verilog}"]
|
1137
|
+
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.right.to_verilog) then
|
1138
|
+
statement_right = $fm.fm_par["#{statement.right.right.to_verilog}"]
|
1139
|
+
else
|
1140
|
+
statement_right = statement.right.right.clone
|
1141
|
+
end
|
1142
|
+
elsif statement.right.right.is_a? (Binary) then
|
1143
|
+
statement_right = statement.right.right.to_change(self.mode)
|
1144
|
+
else
|
1145
|
+
statement_right = statement.right.right.clone
|
1146
|
+
end
|
1147
|
+
new_right = Binary.new(statement.right.type,statement.right.operator,statement_left.clone,statement_right.clone)
|
1148
|
+
# Confirm whether it is a variable.
|
1149
|
+
elsif statement.right.is_a?(Ref) then
|
1150
|
+
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.to_verilog) then
|
1151
|
+
new_right = $fm.fm_seq["#{statement.right.to_verilog}"].clone
|
1152
|
+
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.to_verilog) then
|
1153
|
+
new_right = $fm.fm_par["#{statement.right.to_verilog}"].clone
|
1154
|
+
else
|
1155
|
+
new_right = statement.right.clone
|
1089
1156
|
end
|
1157
|
+
# Because it is not a number. Put it in as it is.
|
1158
|
+
else
|
1159
|
+
new_right = statement.right.clone
|
1090
1160
|
end
|
1091
1161
|
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1162
|
+
if (mode == :par && self.mode == :seq) then
|
1163
|
+
# Dock the existing left hand side and the replaced right hand side to create a new expression.
|
1164
|
+
# Record the expression after conversion to hash to continue seq-> par.
|
1165
|
+
new_statement = Transmit.new(statement.left.clone,new_right)
|
1166
|
+
$fm.fm_seq["#{statement.left.to_verilog}"] = new_right
|
1167
|
+
elsif (mode == :seq && self.mode == :par) && (rep) then
|
1168
|
+
unless (res_name(statement.left).name.to_s.include? "#")
|
1169
|
+
# Search the variable on the left side and give 'to the name.
|
1170
|
+
new_signal = att_signal(statement.left,"'")
|
1095
1171
|
|
1096
1172
|
unless (list.include?(new_signal.name.to_s)) then
|
1097
1173
|
list << new_signal.name.to_s
|
1098
1174
|
flat.add_inner(new_signal)
|
1099
1175
|
end
|
1100
1176
|
|
1101
|
-
|
1102
|
-
|
1103
|
-
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
1177
|
+
new_statement = Transmit.new(search_refname(statement.left,"'"),new_right)
|
1104
1178
|
|
1105
|
-
$fm.
|
1106
|
-
new_noif.add_statement(no_statement)
|
1107
|
-
else
|
1108
|
-
new_noif.add_statement(smt.clone)
|
1179
|
+
$fm.rep[statement.left] = new_statement
|
1109
1180
|
end
|
1110
|
-
end
|
1111
|
-
|
1112
|
-
new_statement.add_noif(condition.clone,new_noif.clone)
|
1113
|
-
end
|
1114
|
-
|
1115
|
-
# Otherwise, it is necessary to process par-> seq or seq-> par.
|
1116
|
-
else
|
1117
|
-
# Make sure the right side is a formula (Binary).
|
1118
|
-
if statement.right.is_a?(Binary) then
|
1119
|
-
# Check the right side and the left side, and if they are variables, check the corresponding expressions and replace them.
|
1120
|
-
# If it is not a variable, it calls the method to be searched.
|
1121
|
-
if statement.right.left.is_a? (Ref) then
|
1122
|
-
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.left.to_verilog) then
|
1123
|
-
statement_left = $fm.fm_seq["#{statement.right.left.to_verilog}"]
|
1124
|
-
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.left.to_verilog) then
|
1125
|
-
statement_left = $fm.fm_par["#{statement.right.left.to_verilog}"]
|
1126
|
-
else
|
1127
|
-
statement_left = statement.right.left.clone
|
1128
|
-
end
|
1129
|
-
elsif statement.right.left.is_a? (Binary) then
|
1130
|
-
statement_left = statement.right.left.to_change(self.mode)
|
1131
|
-
else
|
1132
|
-
statement_left = statement.right.left.clone
|
1133
|
-
end
|
1134
|
-
|
1135
|
-
if statement.right.right.is_a? (Ref) then
|
1136
|
-
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.right.to_verilog) then
|
1137
|
-
statement_right = $fm.fm_seq["#{statement.right.right.to_verilog}"]
|
1138
|
-
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.right.to_verilog) then
|
1139
|
-
statement_right = $fm.fm_par["#{statement.right.right.to_verilog}"]
|
1140
|
-
else
|
1141
|
-
statement_right = statement.right.right.clone
|
1142
|
-
end
|
1143
|
-
elsif statement.right.right.is_a? (Binary) then
|
1144
|
-
statement_right = statement.right.right.to_change(self.mode)
|
1145
|
-
else
|
1146
|
-
statement_right = statement.right.right.clone
|
1147
|
-
end
|
1148
|
-
new_right = Binary.new(statement.right.type,statement.right.operator,statement_left.clone,statement_right.clone)
|
1149
|
-
# Confirm whether it is a variable.
|
1150
|
-
elsif statement.right.is_a?(Ref) then
|
1151
|
-
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.to_verilog) then
|
1152
|
-
new_right = $fm.fm_seq["#{statement.right.to_verilog}"].clone
|
1153
|
-
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.to_verilog) then
|
1154
|
-
new_right = $fm.fm_par["#{statement.right.to_verilog}"].clone
|
1155
1181
|
else
|
1156
|
-
|
1157
|
-
end
|
1158
|
-
# Because it is not a number. Put it in as it is.
|
1159
|
-
else
|
1160
|
-
new_right = statement.right.clone
|
1182
|
+
new_statement = Transmit.new(statement.left.clone,new_right)
|
1183
|
+
end
|
1161
1184
|
end
|
1185
|
+
# Add the converted statement to flat (because par -> par or seq -> seq will be added until then).
|
1162
1186
|
|
1163
|
-
if (
|
1164
|
-
|
1165
|
-
|
1166
|
-
new_statement = Transmit.new(statement.left.clone,new_right)
|
1167
|
-
$fm.fm_seq["#{statement.left.to_verilog}"] = new_right
|
1168
|
-
elsif (mode == :seq && self.mode == :par) && (rep) then
|
1169
|
-
unless (res_name(statement.left).name.to_s.include? "#")
|
1170
|
-
# Search the variable on the left side and give 'to the name.
|
1171
|
-
new_signal = att_signal(statement.left,"'")
|
1172
|
-
|
1173
|
-
unless (list.include?(new_signal.name.to_s)) then
|
1174
|
-
list << new_signal.name.to_s
|
1175
|
-
flat.add_inner(new_signal)
|
1176
|
-
end
|
1177
|
-
|
1178
|
-
new_statement = Transmit.new(search_refname(statement.left,"'"),new_right)
|
1179
|
-
|
1180
|
-
$fm.rep[statement.left] = new_statement
|
1187
|
+
if new_statement.is_a?(Transmit) then
|
1188
|
+
unless (mode == :par && self.mode == :seq) && (res_name(new_statement.left).name.to_s.include? "'") then
|
1189
|
+
flat.add_statement(new_statement.clone)
|
1181
1190
|
end
|
1182
1191
|
else
|
1183
|
-
new_statement = Transmit.new(statement.left.clone,new_right)
|
1184
|
-
end
|
1185
|
-
end
|
1186
|
-
# Add the converted statement to flat (because par -> par or seq -> seq will be added until then).
|
1187
|
-
|
1188
|
-
if new_statement.is_a?(Transmit) then
|
1189
|
-
unless (mode == :par && self.mode == :seq) && (res_name(new_statement.left).name.to_s.include? "'") then
|
1190
1192
|
flat.add_statement(new_statement.clone)
|
1191
1193
|
end
|
1192
|
-
else
|
1193
|
-
flat.add_statement(new_statement.clone)
|
1194
|
-
end
|
1195
1194
|
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1195
|
+
if (rep)
|
1196
|
+
$fm.rep_sharp.each_key do |key|
|
1197
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
1198
|
+
flat.add_statement(new_smt.clone)
|
1199
|
+
end
|
1200
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
1200
1201
|
end
|
1201
|
-
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
1202
1202
|
end
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
$fm.rep.clear() # Deactivate rep that has become obsolete.
|
1203
|
+
# Add an expression after paragraph based on rep.
|
1204
|
+
# A complement expression like x = x '.
|
1205
|
+
$fm.rep.each_key do |key|
|
1206
|
+
new_statement = Transmit.new(key.clone,$fm.rep[key].left.clone)
|
1207
|
+
flat.add_statement(new_statement.clone)
|
1208
|
+
end
|
1209
|
+
$fm.rep.clear() # Deactivate rep that has become obsolete.
|
1211
1210
|
|
1212
1211
|
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1212
|
+
# Since seq -> par is the end, fm_par is deleted.
|
1213
|
+
if (mode == :par && self.mode == :seq) then
|
1214
|
+
$fm.fm_seq.clear()
|
1215
|
+
end
|
1217
1216
|
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1217
|
+
# In case of if statement (when rst == false) you can not convert no or else if you delete the contents of fm_seq.
|
1218
|
+
# Therefore, in this case restore the backup to restore.
|
1219
|
+
# This means that it is necessary to erase fm_seq once obtained in the if statement once.
|
1220
|
+
if(rst == false) then
|
1221
|
+
$fm.fm_seq.clear()
|
1222
|
+
fm_seq_backup.each_key do |key|
|
1223
|
+
$fm.fm_seq[key] = fm_seq_backup[key]
|
1224
|
+
end
|
1225
1225
|
end
|
1226
|
-
end
|
1227
1226
|
|
1228
|
-
|
1229
|
-
|
1227
|
+
return flat # Return flat finished checking.
|
1228
|
+
end
|
1230
1229
|
|
1231
1230
|
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1231
|
+
def change_branch(block)
|
1232
|
+
flat = Block.new(self.mode,"") # Store the expression until if is found.
|
1233
|
+
trans = Block.new(self.mode,"") # A block that stores the expression after if is found.
|
1234
|
+
new_block = Block.new(self.mode,"") # Block storing each converted expression.
|
1236
1235
|
|
1237
|
-
|
1238
|
-
|
1236
|
+
has_branch = false # It is true if there is an if in the block.
|
1237
|
+
more_has_branch = false # It is true if there are two or more if in the block.
|
1239
1238
|
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
else
|
1248
|
-
if statement.is_a?(If) || statement.is_a?(Case) then
|
1249
|
-
flat.add_statement(statement.clone)
|
1250
|
-
has_branch = true
|
1239
|
+
# Search each expression for if.
|
1240
|
+
block.each_statement do |statement|
|
1241
|
+
if (has_branch)
|
1242
|
+
trans.add_statement(statement.clone)
|
1243
|
+
if statement.is_a?(If) || statement.is_a?(Case) then
|
1244
|
+
more_has_branch = true
|
1245
|
+
end
|
1251
1246
|
else
|
1252
|
-
|
1247
|
+
if statement.is_a?(If) || statement.is_a?(Case) then
|
1248
|
+
flat.add_statement(statement.clone)
|
1249
|
+
has_branch = true
|
1250
|
+
else
|
1251
|
+
flat.add_statement(statement.clone)
|
1252
|
+
end
|
1253
1253
|
end
|
1254
1254
|
end
|
1255
|
-
end
|
1256
1255
|
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
# Store "trans" contents for "if" and "case" in "flat".
|
1265
|
-
flat.each_statement do |statement|
|
1266
|
-
# Since case statements include defaulu and when, we store the expressions saved in each case.
|
1267
|
-
if statement.is_a?(Case) then
|
1268
|
-
if statement.default.is_a?(Block)
|
1269
|
-
new_default = statement.default.clone
|
1270
|
-
conversion_block.each_statement do |smt|
|
1271
|
-
new_default.add_statement(smt.clone)
|
1272
|
-
end
|
1273
|
-
end
|
1256
|
+
# If there are two or more if, recursively process if.
|
1257
|
+
if(more_has_branch) then
|
1258
|
+
conversion_block = change_branch(trans)
|
1259
|
+
else
|
1260
|
+
conversion_block = trans.clone
|
1261
|
+
end
|
1274
1262
|
|
1275
|
-
|
1263
|
+
# Store "trans" contents for "if" and "case" in "flat".
|
1264
|
+
flat.each_statement do |statement|
|
1265
|
+
# Since case statements include defaulu and when, we store the expressions saved in each case.
|
1266
|
+
if statement.is_a?(Case) then
|
1267
|
+
if statement.default.is_a?(Block)
|
1268
|
+
new_default = statement.default.clone
|
1269
|
+
conversion_block.each_statement do |smt|
|
1270
|
+
new_default.add_statement(smt.clone)
|
1271
|
+
end
|
1272
|
+
end
|
1276
1273
|
|
1277
|
-
|
1278
|
-
new_when = whens.clone
|
1274
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
1279
1275
|
|
1280
|
-
|
1281
|
-
new_when.
|
1282
|
-
end
|
1283
|
-
new_statement.add_when(new_when.clone)
|
1284
|
-
end
|
1276
|
+
statement.each_when do |whens|
|
1277
|
+
new_when = whens.clone
|
1285
1278
|
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
new_yes.add_statement(smt.clone)
|
1292
|
-
end
|
1279
|
+
conversion_block.each_statement do |smt|
|
1280
|
+
new_when.statement.add_statement(smt.clone)
|
1281
|
+
end
|
1282
|
+
new_statement.add_when(new_when.clone)
|
1283
|
+
end
|
1293
1284
|
|
1294
|
-
|
1295
|
-
|
1285
|
+
new_block.add_statement(new_statement.clone)
|
1286
|
+
# Because there are yes, no and noifs in the if statement, store the expression saved in each.
|
1287
|
+
elsif statement.is_a?(If) then
|
1288
|
+
new_yes = statement.yes.clone
|
1296
1289
|
conversion_block.each_statement do |smt|
|
1297
|
-
|
1290
|
+
new_yes.add_statement(smt.clone)
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
if statement.no.is_a? (Block) then
|
1294
|
+
new_no = statement.no.clone
|
1295
|
+
conversion_block.each_statement do |smt|
|
1296
|
+
new_no.add_statement(smt.clone)
|
1297
|
+
end
|
1298
1298
|
end
|
1299
|
-
end
|
1300
1299
|
|
1301
|
-
|
1302
|
-
|
1300
|
+
# Make new if with converted yes and no.
|
1301
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
1303
1302
|
|
1304
1303
|
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1304
|
+
statement.each_noif do |condition, block|
|
1305
|
+
new_noif = block.clone
|
1306
|
+
conversion_block.each_statement do |smt|
|
1307
|
+
new_noif.add_statement(smt.clone)
|
1308
|
+
end
|
1309
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
1309
1310
|
end
|
1310
|
-
|
1311
|
+
# Add the new statement (if) created to flat.
|
1312
|
+
new_block.add_statement(new_statement.clone)
|
1313
|
+
else
|
1314
|
+
new_block.add_statement(statement.clone)
|
1311
1315
|
end
|
1312
|
-
# Add the new statement (if) created to flat.
|
1313
|
-
new_block.add_statement(new_statement.clone)
|
1314
|
-
else
|
1315
|
-
new_block.add_statement(statement.clone)
|
1316
1316
|
end
|
1317
|
-
end
|
1318
1317
|
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
# Generate a signal for the variable to which "'" or "#" is added.
|
1323
|
-
def att_signal(left,att = "'")
|
1324
|
-
this_name = res_name(left)
|
1325
|
-
new_name = RefName.new(this_name.type, this_name.ref.clone, this_name.name.to_s + att)
|
1326
|
-
new_signal = SignalI.new(new_name.name,new_name.type)
|
1318
|
+
return new_block # Return block after conversion.
|
1319
|
+
end
|
1327
1320
|
|
1328
|
-
|
1329
|
-
|
1321
|
+
# Generate a signal for the variable to which "'" or "#" is added.
|
1322
|
+
def att_signal(left,att = "'")
|
1323
|
+
this_name = res_name(left)
|
1324
|
+
new_name = RefName.new(this_name.type, this_name.ref.clone, this_name.name.to_s + att)
|
1325
|
+
new_signal = SignalI.new(new_name.name,new_name.type)
|
1330
1326
|
|
1331
|
-
|
1332
|
-
|
1333
|
-
#if left.is_a?(RefName) then
|
1334
|
-
new_left = search_refname(left, att)
|
1335
|
-
#elsif left.is_a?(RefIndex) then
|
1336
|
-
# new_ref = search_refname(left, att)
|
1337
|
-
# new_left = RefIndex.new(left.type, new_ref, left.index.clone)
|
1338
|
-
#elsif left.is_a?(RefRange) then
|
1339
|
-
# new_ref = search_refname(left, att)
|
1340
|
-
# my_range = left.range
|
1341
|
-
# new_left = RefRange.new(left.type, new_ref, my_range.first.clone..my_range.last.clone)
|
1342
|
-
#end
|
1343
|
-
|
1344
|
-
# Add new signal to hash.
|
1345
|
-
# if(att == "#") then
|
1346
|
-
# $fm.rep_sharp[left] = new_left
|
1347
|
-
# end
|
1348
|
-
return new_left
|
1349
|
-
end
|
1327
|
+
return new_signal
|
1328
|
+
end
|
1350
1329
|
|
1330
|
+
# A method that takes a variable from the sent left side and adds "att".
|
1331
|
+
def att_sharp(left,att = "'")
|
1332
|
+
new_left = search_refname(left, att)
|
1351
1333
|
|
1352
|
-
|
1353
|
-
def search_refname(me,att = "'")
|
1354
|
-
if me.is_a? (RefName) then
|
1355
|
-
return RefName.new(me.type, me.ref.clone, me.name.to_s + att)
|
1356
|
-
elsif me.ref.is_a? (RefName) then
|
1357
|
-
return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s + att)
|
1358
|
-
elsif me.ref.is_a? (RefIndex) then
|
1359
|
-
return RefIndex.new(me.ref.type, search_refname(me.ref), me.ref.index.clone)
|
1360
|
-
elsif me.ref.is_a? (RefRange) then
|
1361
|
-
my_range = me.ref.range
|
1362
|
-
return RefRange.new(me.ref.type, search_refname(me.ref), my_range.first.clone..my_range.last.clone)
|
1334
|
+
return new_left
|
1363
1335
|
end
|
1364
|
-
end
|
1365
1336
|
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s)
|
1337
|
+
|
1338
|
+
# Recursively search, add "att" to RefName and return.
|
1339
|
+
def search_refname(me,att = "'")
|
1340
|
+
if me.is_a? (RefName) then
|
1341
|
+
return RefName.new(me.type, me.ref.clone, me.name.to_s + att)
|
1342
|
+
elsif me.ref.is_a? (RefName) then
|
1343
|
+
return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s + att)
|
1373
1344
|
elsif me.ref.is_a? (RefIndex) then
|
1374
|
-
return
|
1345
|
+
return RefIndex.new(me.ref.type, search_refname(me.ref), me.ref.index.clone)
|
1375
1346
|
elsif me.ref.is_a? (RefRange) then
|
1376
|
-
|
1347
|
+
my_range = me.ref.range
|
1348
|
+
return RefRange.new(me.ref.type, search_refname(me.ref), my_range.first.clone..my_range.last.clone)
|
1377
1349
|
end
|
1378
1350
|
end
|
1379
|
-
end
|
1380
|
-
end
|
1381
1351
|
|
1382
|
-
#
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1352
|
+
# Recursively search, return Refname.
|
1353
|
+
def res_name(me)
|
1354
|
+
if me.is_a? (RefName) then
|
1355
|
+
return me
|
1356
|
+
else
|
1357
|
+
if me.ref.is_a? (RefName) then
|
1358
|
+
return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s)
|
1359
|
+
elsif me.ref.is_a? (RefIndex) then
|
1360
|
+
return res_name(me.ref)
|
1361
|
+
elsif me.ref.is_a? (RefRange) then
|
1362
|
+
return res_name(me.ref)
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
end
|
1389
1366
|
end
|
1390
1367
|
|
1391
|
-
# Used
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1368
|
+
# Used to display variable names.
|
1369
|
+
# Enhance RefName with generation of verilog code.
|
1370
|
+
class RefName
|
1371
|
+
# Converts the system to Verilog code using +renamer+ for producing Verilog-compatible names.
|
1372
|
+
def to_verilog
|
1373
|
+
vname = name_to_verilog(self.name)
|
1374
|
+
self.properties[:verilog_name] = vname
|
1375
|
+
return "#{vname}"
|
1376
|
+
end
|
1395
1377
|
|
1396
|
-
|
1397
|
-
|
1398
|
-
return
|
1399
|
-
|
1400
|
-
|
1378
|
+
# Used for instantiation (emergency procedure).
|
1379
|
+
def to_another_verilog
|
1380
|
+
return "_#{self.name.to_s}"
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
def ancestor(my)
|
1384
|
+
if my.parent.parent.respond_to? (:mode) then
|
1385
|
+
return ancestor(my.parent)
|
1386
|
+
else
|
1387
|
+
return "#{my.parent.mode.to_s}#{my.mode.to_s}"
|
1388
|
+
end
|
1401
1389
|
end
|
1402
1390
|
end
|
1403
|
-
end
|
1404
1391
|
|
1405
|
-
# Used to convert an array.
|
1406
|
-
# Enhance RefIndex with generation of verilog code.
|
1407
|
-
class RefIndex
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1392
|
+
# Used to convert an array.
|
1393
|
+
# Enhance RefIndex with generation of verilog code.
|
1394
|
+
class RefIndex
|
1395
|
+
# Converts the system to Verilog code.
|
1396
|
+
def to_verilog
|
1397
|
+
return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
|
1398
|
+
end
|
1411
1399
|
end
|
1412
|
-
end
|
1413
1400
|
|
1414
1401
|
|
1415
|
-
# Used to indicate the number of bits.
|
1416
|
-
# Enhance TypeVector with generation of verilog code.
|
1417
|
-
class TypeVector
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1402
|
+
# Used to indicate the number of bits.
|
1403
|
+
# Enhance TypeVector with generation of verilog code.
|
1404
|
+
class TypeVector
|
1405
|
+
# Converts the system to Verilog code.
|
1406
|
+
def to_verilog
|
1407
|
+
# if self.base.name.to_s != "bit"
|
1408
|
+
if VERILOG_BASE_TYPES.include?(self.base.name.to_s)
|
1409
|
+
return " #{self.base.name.to_s}[#{self.range.first}:#{self.range.last}]"
|
1410
|
+
end
|
1411
|
+
return " [#{self.range.first}:#{self.range.last}]"
|
1423
1412
|
end
|
1424
|
-
return " [#{self.range.first}:#{self.range.last}]"
|
1425
1413
|
end
|
1426
|
-
end
|
1427
1414
|
|
1428
|
-
# Necessary for displaying bit width (eg, specify and assign).
|
1429
|
-
class RefRange
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1415
|
+
# Necessary for displaying bit width (eg, specify and assign).
|
1416
|
+
class RefRange
|
1417
|
+
# Converts the system to Verilog code.
|
1418
|
+
def to_verilog(unknown = false)
|
1419
|
+
return "#{self.ref.to_verilog}[#{self.range.first.to_getrange}:#{self.range.last.to_getrange}]"
|
1420
|
+
end
|
1433
1421
|
end
|
1434
|
-
end
|
1435
1422
|
|
1436
|
-
# Use it when collecting references.
|
1437
|
-
class RefConcat
|
1438
|
-
|
1439
|
-
|
1423
|
+
# Use it when collecting references.
|
1424
|
+
class RefConcat
|
1425
|
+
def to_verilog
|
1426
|
+
ref = self.each_ref.to_a
|
1440
1427
|
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1428
|
+
result = "{"
|
1429
|
+
ref[0..-2].each do |ref|
|
1430
|
+
result << "#{ref.to_verilog},"
|
1431
|
+
end
|
1432
|
+
result << "#{ref.last.to_verilog}}"
|
1446
1433
|
|
1447
|
-
|
1434
|
+
return result
|
1435
|
+
end
|
1448
1436
|
end
|
1449
|
-
end
|
1450
1437
|
|
1451
|
-
# Used to output bitstring.
|
1452
|
-
# Enhance HDLRuby with generation of verilog code.
|
1453
|
-
class HDLRuby::BitString
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1438
|
+
# Used to output bitstring.
|
1439
|
+
# Enhance HDLRuby with generation of verilog code.
|
1440
|
+
class HDLRuby::BitString
|
1441
|
+
# Converts the system to Verilog code.
|
1442
|
+
def to_verilog
|
1443
|
+
return "#{self.to_s}"
|
1444
|
+
end
|
1457
1445
|
end
|
1458
|
-
end
|
1459
1446
|
|
1460
|
-
# Used for connection using choice.
|
1461
|
-
# Enhance Select with generation of verilog code.
|
1462
|
-
class Select
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1447
|
+
# Used for connection using choice.
|
1448
|
+
# Enhance Select with generation of verilog code.
|
1449
|
+
class Select
|
1450
|
+
# Converts the system to Verilog code.
|
1451
|
+
def to_verilog
|
1452
|
+
# Outputs the first and second choices (choice (0) and choice (1)).
|
1453
|
+
return "#{self.select.to_verilog} == 1 #{self.operator} #{self.get_choice(0).to_verilog} : #{self.get_choice(1).to_verilog}"
|
1454
|
+
end
|
1467
1455
|
end
|
1468
|
-
end
|
1469
1456
|
|
1470
|
-
# Used to output numbers.
|
1471
|
-
# Enhance Value with generation of verilog code.
|
1472
|
-
class Value
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1457
|
+
# Used to output numbers.
|
1458
|
+
# Enhance Value with generation of verilog code.
|
1459
|
+
class Value
|
1460
|
+
# Converts the system to Verilog code.
|
1461
|
+
# If it is bit, it is b, and if it is int, it is represented by d. (Example: 4'b0000, 32'd1)
|
1462
|
+
def to_verilog(unknown = nil)
|
1463
|
+
if self.type.base.name.to_s == "bit"
|
1464
|
+
return "#{self.type.range.first + 1}'b#{self.content.to_verilog}"
|
1465
|
+
elsif self.type.name.to_s == "integer"
|
1466
|
+
str = self.content.to_verilog
|
1467
|
+
if str[0] == "-" then
|
1468
|
+
# Negative value.
|
1469
|
+
return "-#{self.type.range.first + 1}'d#{str[1..-1]}"
|
1470
|
+
else
|
1471
|
+
return "#{self.type.range.first + 1}'d#{str}"
|
1472
|
+
end
|
1485
1473
|
end
|
1474
|
+
return "#{self.type.range.first + 1}'b#{self.content.to_verilog}"
|
1475
|
+
end
|
1476
|
+
# How to use when simply obtaining the width
|
1477
|
+
def to_getrange
|
1478
|
+
return "#{self.content.to_verilog}"
|
1486
1479
|
end
|
1487
|
-
return "#{self.type.range.first + 1}'b#{self.content.to_verilog}"
|
1488
|
-
end
|
1489
|
-
# How to use when simply obtaining the width
|
1490
|
-
def to_getrange
|
1491
|
-
return "#{self.content.to_verilog}"
|
1492
1480
|
end
|
1493
|
-
end
|
1494
1481
|
|
1495
1482
|
|
1496
|
-
# Used to transrate if.
|
1497
|
-
# Enhance If with generation of verilog code.
|
1498
|
-
class If
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1483
|
+
# Used to transrate if.
|
1484
|
+
# Enhance If with generation of verilog code.
|
1485
|
+
class If
|
1486
|
+
# # Converts the system to Verilog code.
|
1487
|
+
# def to_verilog(mode = nil)
|
1488
|
+
# Converts to Verilog code, checking adding 'spc' spaces at the begining
|
1489
|
+
# of each line.
|
1490
|
+
def to_verilog(spc = 3)
|
1504
1491
|
|
1505
|
-
|
1492
|
+
$blocking = false
|
1506
1493
|
|
1507
|
-
|
1508
|
-
# result = " " * ($space_count) # Indented based on space_count.
|
1509
|
-
# else
|
1510
|
-
# result = ""
|
1511
|
-
# end
|
1512
|
-
# $space_count += 1 # Add count to be used for indentation.
|
1513
|
-
result = " " * spc # Indented based on space_count.
|
1494
|
+
result = " " * spc # Indented based on space_count.
|
1514
1495
|
|
1515
|
-
|
1516
|
-
result << "if (#{self.condition.to_verilog}) "
|
1496
|
+
result << "if (#{self.condition.to_verilog}) "
|
1517
1497
|
|
1518
1498
|
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
# end
|
1524
|
-
# result << "#{" " * $space_count} end\n"
|
1525
|
-
result << self.yes.to_verilog(spc)
|
1526
|
-
end
|
1499
|
+
# Check if there is yes (if) and output yes or less.
|
1500
|
+
if self.respond_to? (:yes)
|
1501
|
+
result << self.yes.to_verilog(spc)
|
1502
|
+
end
|
1527
1503
|
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1535
|
-
# end
|
1536
|
-
# result << "#{" "* $space_count} end\n"
|
1537
|
-
result << block.to_verilog(spc)
|
1538
|
-
end
|
1504
|
+
# If noif (else if) exists, it outputs it.
|
1505
|
+
# Since noif is directly under, respond_to is unnecessary.
|
1506
|
+
self.each_noif do |condition, block|
|
1507
|
+
result << "\n#{" "*spc}else if (#{condition.to_verilog}) "
|
1508
|
+
result << block.to_verilog(spc)
|
1509
|
+
end
|
1539
1510
|
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1546
|
-
# end
|
1547
|
-
# result << "#{" " * $space_count} end\n"
|
1548
|
-
result << self.no.to_verilog(spc)
|
1549
|
-
end
|
1511
|
+
# Check if there is no (else) and output no or less.
|
1512
|
+
if self.no.respond_to?(:mode)
|
1513
|
+
result << "\n#{" " * spc}else "
|
1514
|
+
result << self.no.to_verilog(spc)
|
1515
|
+
end
|
1550
1516
|
|
1551
|
-
|
1552
|
-
|
1517
|
+
return result
|
1518
|
+
end
|
1553
1519
|
end
|
1554
|
-
end
|
1555
1520
|
|
1556
|
-
# Used to translate case
|
1557
|
-
class Case
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
result << " " * (spc+3) + "#{whens.match.to_verilog}: "
|
1580
|
-
|
1581
|
-
# if whens.statement.each_statement.count > 1 then
|
1582
|
-
# result << "begin\n"
|
1583
|
-
# whens.statement.each_statement do |statement|
|
1584
|
-
# result << " "+ " " *$space_count +"#{statement.to_verilog}"
|
1585
|
-
# end
|
1586
|
-
# result << " " + " " *$space_count + "end\n"
|
1587
|
-
# elsif whens.statement.each_statement.count == 1 then
|
1588
|
-
# whens.statement.each_statement do |statement|
|
1589
|
-
# result << "#{statement.to_verilog}"
|
1590
|
-
# end
|
1591
|
-
# else
|
1592
|
-
# # Empty statement case.
|
1593
|
-
# result << "\n"
|
1594
|
-
# end
|
1595
|
-
if whens.statement.each_statement.count >= 1 then
|
1596
|
-
result << whens.statement.to_verilog(spc+3)
|
1597
|
-
else
|
1598
|
-
result << "\n"
|
1521
|
+
# Used to translate case
|
1522
|
+
class Case
|
1523
|
+
# def to_verilog(mode = nil)
|
1524
|
+
#
|
1525
|
+
# Converts to Verilog code, checking if variables are register
|
1526
|
+
# or wire adding 'spc' spaces at the begining of each line.
|
1527
|
+
def to_verilog(spc = 3)
|
1528
|
+
|
1529
|
+
result = " " * spc # Indented based on space_count.
|
1530
|
+
|
1531
|
+
result = ""
|
1532
|
+
result << "case(#{self.value.to_verilog})\n"
|
1533
|
+
|
1534
|
+
# n the case statement, each branch is partitioned by when. Process each time when.
|
1535
|
+
self.each_when do |whens|
|
1536
|
+
# Reads and stores the numbers and expressions stored in when.
|
1537
|
+
result << " " * (spc+3) + "#{whens.match.to_verilog}: "
|
1538
|
+
|
1539
|
+
if whens.statement.each_statement.count >= 1 then
|
1540
|
+
result << whens.statement.to_verilog(spc+3)
|
1541
|
+
else
|
1542
|
+
result << "\n"
|
1543
|
+
end
|
1599
1544
|
end
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
# result << " end\n"
|
1609
|
-
# elsif self.default.each_statement.count == 1 then
|
1610
|
-
# result << " " + " " *$space_count + "default: "
|
1611
|
-
# self.default.each_statement do |statement|
|
1612
|
-
# result << "#{statement.to_verilog}"
|
1613
|
-
# end
|
1614
|
-
# end
|
1615
|
-
# end
|
1616
|
-
if self.default then
|
1617
|
-
if self.default.each_statement.count >= 1 then
|
1618
|
-
result << self.default.each_statement.to_verilog(spc+3)
|
1619
|
-
else
|
1620
|
-
result << "\n"
|
1545
|
+
if self.default then
|
1546
|
+
if self.default.each_statement.count >= 1 then
|
1547
|
+
result << self.default.each_statement.map do |stmnt|
|
1548
|
+
stmnt.to_verilog(spc+3)
|
1549
|
+
end.join("\n")
|
1550
|
+
else
|
1551
|
+
result << "\n"
|
1552
|
+
end
|
1621
1553
|
end
|
1622
|
-
|
1623
|
-
# result << " " + " " *$space_count + "endcase\n" # Conclusion.
|
1624
|
-
result << " " * spc + "endcase\n" # Conclusion.
|
1625
|
-
|
1626
|
-
# $space_count -= 1 # Since the output ends, reduce the count.
|
1627
|
-
return result # Return case after translation.
|
1628
|
-
end
|
1629
|
-
end
|
1554
|
+
result << " " * spc + "endcase\n" # Conclusion.
|
1630
1555
|
|
1631
|
-
#
|
1632
|
-
# Enhance Connection with generation of verilog code.
|
1633
|
-
class Connection
|
1634
|
-
# Converts the system to Verilog code.
|
1635
|
-
|
1636
|
-
# Method used for array.
|
1637
|
-
def array_connection(left,right)
|
1638
|
-
expression = right.each_expression.to_a
|
1639
|
-
result = ""
|
1640
|
-
expression[0..-2].each do |expression|
|
1641
|
-
result << " assign #{left.to_verilog}[#{expression.content.to_s}] = #{expression.to_verilog};\n"
|
1556
|
+
return result # Return case after translation.
|
1642
1557
|
end
|
1643
|
-
result << " assign #{left.to_verilog}[#{expression.last.content.to_s}] = #{expression.last.to_verilog};\n"
|
1644
|
-
return result
|
1645
1558
|
end
|
1646
1559
|
|
1647
|
-
|
1648
|
-
|
1649
|
-
|
1650
|
-
#
|
1651
|
-
|
1652
|
-
#
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
choice = self.right.each_choice.to_a
|
1659
|
-
choice.each do |choice|
|
1660
|
-
bit += 1
|
1560
|
+
# Translate expression of combination circuit.
|
1561
|
+
# Enhance Connection with generation of verilog code.
|
1562
|
+
class Connection
|
1563
|
+
# Converts the system to Verilog code.
|
1564
|
+
|
1565
|
+
# Method used for array.
|
1566
|
+
def array_connection(left,right)
|
1567
|
+
expression = right.each_expression.to_a
|
1568
|
+
result = ""
|
1569
|
+
expression[0..-2].each do |expression|
|
1570
|
+
result << " assign #{left.to_verilog}[#{expression.content.to_s}] = #{expression.to_verilog};\n"
|
1661
1571
|
end
|
1572
|
+
result << " assign #{left.to_verilog}[#{expression.last.content.to_s}] = #{expression.last.to_verilog};\n"
|
1573
|
+
return result
|
1662
1574
|
end
|
1663
1575
|
|
1664
|
-
|
1665
|
-
|
1666
|
-
#
|
1667
|
-
|
1668
|
-
|
1669
|
-
#
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1576
|
+
def to_verilog
|
1577
|
+
# Decide whether to assign to array by if.
|
1578
|
+
# NOTICE: Now array assignment is done trough constant initialization, will be treated later.
|
1579
|
+
# if self.right.respond_to? (:each_expression)
|
1580
|
+
# array_connection(self.left,self.right);
|
1581
|
+
# else
|
1582
|
+
cnt = 0 # Use count.
|
1583
|
+
bit = -2 # Used to determine the bit width. Since there are 0 and default, -2.
|
1584
|
+
|
1585
|
+
# Measure the number of choices on the right side (case statement if it is 3 or more).
|
1586
|
+
if self.right.respond_to? (:each_choice)
|
1587
|
+
choice = self.right.each_choice.to_a
|
1588
|
+
choice.each do |choice|
|
1589
|
+
bit += 1
|
1590
|
+
end
|
1676
1591
|
end
|
1677
|
-
# At the end, it becomes default because it needs default.
|
1678
|
-
result << " default: #{self.left.to_verilog} = #{choice.last.to_verilog}\n"
|
1679
|
-
result << " endcase\n"
|
1680
|
-
result << " end\n"
|
1681
|
-
return result
|
1682
|
-
end
|
1683
1592
|
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1593
|
+
# Three or more choices.
|
1594
|
+
if (bit > 2)
|
1595
|
+
# The bit width is obtained by converting the bit into a binary number and obtaining the size.
|
1596
|
+
bit = bit.to_s(2).size
|
1597
|
+
|
1598
|
+
# Create a case statement.
|
1599
|
+
result = " begin\n"
|
1600
|
+
result << " case(#{self.right.select.to_verilog})\n"
|
1601
|
+
# Output other than the last one in order.
|
1602
|
+
choice[0..-2].each do |choice|
|
1603
|
+
result << " #{bit}'#{cnt}: #{self.left.to_verilog} = #{choice.to_verilog}\n"
|
1604
|
+
cnt += 1
|
1605
|
+
end
|
1606
|
+
# At the end, it becomes default because it needs default.
|
1607
|
+
result << " default: #{self.left.to_verilog} = #{choice.last.to_verilog}\n"
|
1608
|
+
result << " endcase\n"
|
1609
|
+
result << " end\n"
|
1610
|
+
return result
|
1611
|
+
end
|
1689
1612
|
|
1690
|
-
# It
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1613
|
+
# It is not a case so call it normally.
|
1614
|
+
return " assign #{self.left.to_verilog} = #{self.right.to_verilog};\n"
|
1615
|
+
# end
|
1616
|
+
end
|
1694
1617
|
end
|
1695
|
-
end
|
1696
1618
|
|
1697
|
-
#
|
1698
|
-
class
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1619
|
+
# It could be used for instantiation.
|
1620
|
+
class RefThis
|
1621
|
+
def to_another_verilog
|
1622
|
+
return ""
|
1623
|
+
end
|
1702
1624
|
end
|
1703
|
-
end
|
1704
1625
|
|
1705
|
-
# Used when
|
1706
|
-
class
|
1707
|
-
|
1708
|
-
|
1709
|
-
|
1710
|
-
def to_verilog
|
1711
|
-
# return "#{self.type.to_verilog}'(#{self.child.to_verilog})"
|
1712
|
-
if self.child.is_a?(Value) then
|
1713
|
-
return self.child.to_verilog
|
1626
|
+
# Used when using "~" for expressions.
|
1627
|
+
class Unary
|
1628
|
+
# Converts the system to Verilog code.
|
1629
|
+
def to_verilog
|
1630
|
+
return "#{self.operator[0]}#{self.child.to_verilog}"
|
1714
1631
|
end
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
# Need to truncate
|
1726
|
-
return "$signed(#{self.child.to_verilog}[#{sw-1}:0])"
|
1727
|
-
else
|
1728
|
-
# Only enforce signed.
|
1729
|
-
return "$signed(#{self.child.to_verilog})"
|
1632
|
+
end
|
1633
|
+
|
1634
|
+
# Used when casting expressions.
|
1635
|
+
class Cast
|
1636
|
+
# Converts the system to Verilog code.
|
1637
|
+
# NOTE: the cast is rounded up size bit-width cast is not supported
|
1638
|
+
# by traditional verilog.
|
1639
|
+
def to_verilog
|
1640
|
+
if self.child.is_a?(Value) then
|
1641
|
+
return self.child.to_verilog
|
1730
1642
|
end
|
1731
|
-
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1643
|
+
# Get the type widths, used for computing extensions or truncations.
|
1644
|
+
cw = self.child.type.width
|
1645
|
+
sw = self.type.width
|
1646
|
+
if self.type.signed? then
|
1647
|
+
if (sw>cw) then
|
1648
|
+
# Need to sign extend.
|
1649
|
+
return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," +
|
1650
|
+
"#{self.child.to_verilog}})"
|
1651
|
+
elsif (sw<cw) then
|
1652
|
+
# Need to truncate
|
1653
|
+
return "$signed(#{self.child.to_verilog}[#{sw-1}:0])"
|
1654
|
+
else
|
1655
|
+
# Only enforce signed.
|
1656
|
+
return "$signed(#{self.child.to_verilog})"
|
1657
|
+
end
|
1739
1658
|
else
|
1740
|
-
|
1741
|
-
|
1659
|
+
if (sw>cw) then
|
1660
|
+
# Need to extend.
|
1661
|
+
return "$unsigned({{#{sw-cw}{1'b0}},#{self.child.to_verilog}})"
|
1662
|
+
elsif (sw<cw) then
|
1663
|
+
# Need to truncate
|
1664
|
+
return "$unsigned(#{self.child.to_verilog}[#{sw-1}:0])"
|
1665
|
+
else
|
1666
|
+
# Only enforce signed.
|
1667
|
+
return "$unsigned(#{self.child.to_verilog})"
|
1668
|
+
end
|
1742
1669
|
end
|
1743
1670
|
end
|
1744
1671
|
end
|
1745
|
-
end
|
1746
1672
|
|
1747
|
-
# For declaring variables.
|
1748
|
-
# Enhance SignalI with generation of verilog code.
|
1749
|
-
class SignalI
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1673
|
+
# For declaring variables.
|
1674
|
+
# Enhance SignalI with generation of verilog code.
|
1675
|
+
class SignalI
|
1676
|
+
# Converts the system to Verilog code.
|
1677
|
+
def to_verilog
|
1678
|
+
# Convert unusable characters and return them.
|
1679
|
+
vname = name_to_verilog(self.name)
|
1680
|
+
self.properties[:verilog_name] = vname
|
1681
|
+
return "#{vname}"
|
1682
|
+
end
|
1754
1683
|
end
|
1755
|
-
end
|
1756
1684
|
|
1757
|
-
# If it is signed, it outputs signed.
|
1758
|
-
# Enhance Type with generation of verilog code.
|
1759
|
-
class Type
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1685
|
+
# If it is signed, it outputs signed.
|
1686
|
+
# Enhance Type with generation of verilog code.
|
1687
|
+
class Type
|
1688
|
+
# Converts the type to Verilog code.
|
1689
|
+
def to_verilog
|
1690
|
+
return self.name == :signed ? "#{self.name.to_s} " : ""
|
1691
|
+
end
|
1763
1692
|
end
|
1764
|
-
end
|
1765
1693
|
|
1766
|
-
# Replace type by refered type.
|
1767
|
-
class TypeDef
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1694
|
+
# Replace type by refered type.
|
1695
|
+
class TypeDef
|
1696
|
+
# Converts the type to verilog code.
|
1697
|
+
def to_verilog
|
1698
|
+
return self.def.to_verilog
|
1699
|
+
end
|
1771
1700
|
end
|
1772
|
-
end
|
1773
1701
|
|
1774
|
-
# Use it when collecting.
|
1775
|
-
class Concat
|
1776
|
-
|
1777
|
-
|
1702
|
+
# Use it when collecting.
|
1703
|
+
class Concat
|
1704
|
+
def to_verilog
|
1705
|
+
expression = self.each_expression.to_a
|
1778
1706
|
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1707
|
+
result = "{"
|
1708
|
+
expression[0..-2].each do |expression|
|
1709
|
+
result << "#{expression.to_verilog},"
|
1710
|
+
end
|
1711
|
+
result << "#{expression.last.to_verilog}}"
|
1784
1712
|
|
1785
|
-
|
1713
|
+
return result
|
1714
|
+
end
|
1786
1715
|
end
|
1787
|
-
end
|
1788
1716
|
|
1789
|
-
# Look at the unit of time, convert the time to ps and output it.
|
1790
|
-
# One of two people, TimeWait and Delay.
|
1791
|
-
class TimeWait
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1717
|
+
# Look at the unit of time, convert the time to ps and output it.
|
1718
|
+
# One of two people, TimeWait and Delay.
|
1719
|
+
class TimeWait
|
1720
|
+
def to_verilog(spc = 3)
|
1721
|
+
return (" " * spc) + self.delay.to_verilog + "\n"
|
1722
|
+
end
|
1795
1723
|
end
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
|
1724
|
+
class Delay
|
1725
|
+
def to_verilog
|
1726
|
+
time = self.value.to_s
|
1727
|
+
if(self.unit.to_s == "ps") then
|
1728
|
+
return "##{time};"
|
1729
|
+
elsif(self.unit.to_s == "ns")
|
1730
|
+
return "##{time}000;"
|
1731
|
+
elsif(self.unit.to_s == "us")
|
1732
|
+
return "##{time}000000;"
|
1733
|
+
elsif(self.unit.to_s == "ms")
|
1734
|
+
return "##{time}000000000;"
|
1735
|
+
elsif(self.unit.to_s == "s")
|
1736
|
+
return "##{time}000000000000;"
|
1737
|
+
end
|
1810
1738
|
end
|
1811
1739
|
end
|
1812
|
-
end
|
1813
1740
|
|
1814
|
-
# Those who disappeared.
|
1815
|
-
#class SystemI
|
1816
|
-
#class TypeTuple
|
1817
|
-
#class Event
|
1818
|
-
|
1819
|
-
# Enhance SystemT with generation of verilog code.
|
1820
|
-
class SystemT
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1741
|
+
# Those who disappeared.
|
1742
|
+
#class SystemI
|
1743
|
+
#class TypeTuple
|
1744
|
+
#class Event
|
1745
|
+
|
1746
|
+
# Enhance SystemT with generation of verilog code.
|
1747
|
+
class SystemT
|
1748
|
+
|
1749
|
+
## Tells if a connection is actually a port connection.
|
1750
|
+
def port_output_connection?(connection)
|
1751
|
+
return self.each_systemI.find do |systemI|
|
1752
|
+
if connection.right.is_a?(RefName) &&
|
1753
|
+
connection.right.ref.is_a?(RefName) &&
|
1754
|
+
systemI.name == connection.right.ref.name
|
1755
|
+
puts "port_connection for right=#{connection.right.name} and systemI=#{systemI.name}"
|
1756
|
+
true
|
1757
|
+
else
|
1758
|
+
false
|
1759
|
+
end
|
1832
1760
|
end
|
1833
1761
|
end
|
1834
|
-
end
|
1835
1762
|
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1763
|
+
## Tells if an expression is a reference to port +systemI.signal+.
|
1764
|
+
def port_assign?(expr, systemI, signal)
|
1765
|
+
return expr.is_a?(RefName) && expr.name == signal.name &&
|
1766
|
+
expr.ref.is_a?(RefName) && expr.ref.name == systemI.name
|
1767
|
+
end
|
1841
1768
|
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1769
|
+
## Extracts the assignments to port +systemI.signal+ and returns
|
1770
|
+
# the resulting reference to a port wire.
|
1771
|
+
#
|
1772
|
+
# NOTE: assumes to_upper_space! and with_port! has been called.
|
1773
|
+
def extract_port_assign!(systemI,signal)
|
1774
|
+
# Extract the assignment.
|
1775
|
+
assign = nil
|
1776
|
+
self.each_connection.to_a.each do |connection|
|
1777
|
+
if self.port_assign?(connection.left,systemI,signal) then
|
1778
|
+
# The left is the port.
|
1779
|
+
# Delete the connection.
|
1780
|
+
self.scope.delete_connection!(connection)
|
1781
|
+
# And return a copy of the right.
|
1782
|
+
return connection.right.clone
|
1783
|
+
elsif self.port_assign?(connection.right,systemI,signal) then
|
1784
|
+
# The right is the port.
|
1785
|
+
# Delete the connection.
|
1786
|
+
self.scope.delete_connection!(connection)
|
1787
|
+
# And return a copy of the left.
|
1788
|
+
return connection.left.clone
|
1789
|
+
end
|
1862
1790
|
end
|
1791
|
+
# No port found, nothing to do
|
1792
|
+
return nil
|
1863
1793
|
end
|
1864
|
-
# No port found, nothing to do
|
1865
|
-
return nil
|
1866
|
-
end
|
1867
1794
|
|
1868
1795
|
|
1869
1796
|
|
1870
|
-
|
1871
|
-
|
1872
|
-
|
1873
|
-
|
1874
|
-
|
1875
|
-
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
block.each_statement do |statement|
|
1882
|
-
if statement.is_a?(Transmit)
|
1883
|
-
HDLRuby::Low::VERILOG_REGS << statement.left.to_verilog
|
1797
|
+
# Converts the system to Verilog code.
|
1798
|
+
def to_verilog
|
1799
|
+
# Detect the registers
|
1800
|
+
HDLRuby::Low::VERILOG_REGS.clear
|
1801
|
+
# The left values.
|
1802
|
+
self.each_behavior do |behavior|
|
1803
|
+
behavior.each_block_deep do |block|
|
1804
|
+
block.each_statement do |statement|
|
1805
|
+
if statement.is_a?(Transmit)
|
1806
|
+
HDLRuby::Low::VERILOG_REGS << statement.left.to_verilog
|
1807
|
+
end
|
1884
1808
|
end
|
1885
1809
|
end
|
1886
1810
|
end
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
# self.scope.each_connection do |connection|
|
1892
|
-
# # Skip port connections.
|
1893
|
-
# next if !self.port_output_connection?(connection)
|
1894
|
-
# # puts "Not counting left in connection: #{connection.to_verilog}"
|
1895
|
-
# # puts "i.e.: #{connection.left.to_verilog}"
|
1896
|
-
# regs.delete(connection.left.to_verilog)
|
1897
|
-
# end
|
1898
|
-
# # puts "Now regs has clk?: #{regs.include?("clk")}"
|
1899
|
-
# And the initialized signals.
|
1900
|
-
self.each_output do |output|
|
1901
|
-
# regs << output.to_verilog if output.value
|
1902
|
-
HDLRuby::Low::VERILOG_REGS << output.to_verilog if output.value
|
1903
|
-
end
|
1904
|
-
self.each_inner do |inner|
|
1905
|
-
# regs << inner.to_verilog if inner.value
|
1906
|
-
HDLRuby::Low::VERILOG_REGS << inner.to_verilog if inner.value
|
1907
|
-
end
|
1908
|
-
# And the array types signals.
|
1909
|
-
self.each_signal do |sig|
|
1910
|
-
# # regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1911
|
-
# regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1912
|
-
if sig.type.vector? && sig.type.base.vector? then
|
1913
|
-
HDLRuby::Low::VERILOG_REGS << sig.to_verilog
|
1811
|
+
# And the initialized signals.
|
1812
|
+
self.each_output do |output|
|
1813
|
+
# regs << output.to_verilog if output.value
|
1814
|
+
HDLRuby::Low::VERILOG_REGS << output.to_verilog if output.value
|
1914
1815
|
end
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1816
|
+
self.each_inner do |inner|
|
1817
|
+
# regs << inner.to_verilog if inner.value
|
1818
|
+
HDLRuby::Low::VERILOG_REGS << inner.to_verilog if inner.value
|
1819
|
+
end
|
1820
|
+
# And the array types signals.
|
1821
|
+
self.each_signal do |sig|
|
1822
|
+
if sig.type.vector? && sig.type.base.vector? then
|
1823
|
+
HDLRuby::Low::VERILOG_REGS << sig.to_verilog
|
1824
|
+
end
|
1825
|
+
end
|
1826
|
+
self.each_inner do |sig|
|
1827
|
+
if sig.type.vector? && sig.type.base.vector? then
|
1828
|
+
HDLRuby::Low::VERILOG_REGS << sig.to_verilog
|
1829
|
+
end
|
1921
1830
|
end
|
1922
|
-
end
|
1923
1831
|
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1832
|
+
# Code generation
|
1833
|
+
inputs = 0
|
1834
|
+
outputs = 0
|
1835
|
+
inout = 0
|
1928
1836
|
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1837
|
+
inputs = self.each_input.to_a
|
1838
|
+
outputs = self.each_output.to_a
|
1839
|
+
inout = self.each_inout.to_a
|
1932
1840
|
|
1933
|
-
|
1934
|
-
|
1935
|
-
# Output the module name.
|
1936
|
-
code << "module #{name_to_verilog(self.name)}("
|
1841
|
+
# Spelling necessary for simulation.
|
1842
|
+
code = "`timescale 1ps/1ps\n\n"
|
1937
1843
|
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
# When only input is used, it is necessary to close (), so it branches with if.
|
1943
|
-
if outputs.empty? && inout.empty? then
|
1944
|
-
# code << " #{inputs.last.to_verilog} ); \n" unless inputs.empty?
|
1945
|
-
if (inputs.empty?)
|
1946
|
-
code << " ); \n"
|
1947
|
-
end
|
1948
|
-
else
|
1949
|
-
code << " #{inputs.last.to_verilog}," unless inputs.empty?
|
1950
|
-
end
|
1844
|
+
vname = name_to_verilog(self.name)
|
1845
|
+
self.properties[:verilog_name] = vname
|
1846
|
+
# Output the module name.
|
1847
|
+
code << "module #{vname}("
|
1951
1848
|
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1849
|
+
# Output the last two to the input.
|
1850
|
+
inputs[0..-2].each do |input|
|
1851
|
+
code << " #{input.to_verilog},"
|
1852
|
+
end
|
1853
|
+
# When only input is used, it is necessary to close (), so it branches with if.
|
1854
|
+
if outputs.empty? && inout.empty? then
|
1855
|
+
if (inputs.empty?)
|
1856
|
+
code << " ); \n"
|
1857
|
+
end
|
1858
|
+
else
|
1859
|
+
code << " #{inputs.last.to_verilog}," unless inputs.empty?
|
1860
|
+
end
|
1962
1861
|
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
# Declare "input"
|
1971
|
-
self.each_input do |input|
|
1972
|
-
if input.type.respond_to? (:each_type) then
|
1973
|
-
$vector_reg = "#{input.to_verilog}"
|
1974
|
-
$vector_cnt = 0
|
1975
|
-
input.type.each_type do |type|
|
1976
|
-
code << "input #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
|
1977
|
-
$vector_cnt += 1
|
1978
|
-
end
|
1862
|
+
# Output the last two to the output.
|
1863
|
+
outputs[0..-2].each do |output|
|
1864
|
+
code << " #{output.to_verilog},"
|
1865
|
+
end
|
1866
|
+
# When only input and output are used, it is necessary to close (), so it branches with if.
|
1867
|
+
if inout.empty? then
|
1868
|
+
code << " #{outputs.last.to_verilog} ); \n" unless outputs.empty?
|
1979
1869
|
else
|
1980
|
-
code << "
|
1870
|
+
code << " #{outputs.last.to_verilog}," unless outputs.empty?
|
1871
|
+
end
|
1872
|
+
|
1873
|
+
# Output the last two to the inout.
|
1874
|
+
inout[0..-2].each do |inout|
|
1875
|
+
code << " #{inout.to_verilog},"
|
1876
|
+
end
|
1877
|
+
# There is no comma as it is the last one
|
1878
|
+
code << " #{inout.last.to_verilog} ); \n" unless inout.empty?
|
1879
|
+
|
1880
|
+
# Declare "input"
|
1881
|
+
self.each_input do |input|
|
1882
|
+
if input.type.respond_to? (:each_type) then
|
1883
|
+
$vector_reg = "#{input.to_verilog}"
|
1884
|
+
$vector_cnt = 0
|
1885
|
+
input.type.each_type do |type|
|
1886
|
+
code << "input #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
|
1887
|
+
$vector_cnt += 1
|
1888
|
+
end
|
1889
|
+
else
|
1890
|
+
code << " input#{input.type.to_verilog} #{input.to_verilog};\n"
|
1891
|
+
end
|
1981
1892
|
end
|
1982
|
-
end
|
1983
1893
|
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1894
|
+
# Declare "output"
|
1895
|
+
self.each_output do |output|
|
1896
|
+
if output.type.respond_to? (:each_type) then
|
1897
|
+
$vector_reg = "#{output.to_verilog}"
|
1898
|
+
$vector_cnt = 0
|
1899
|
+
output.type.each_type do |type|
|
1900
|
+
# if regs.include?(type.name) then
|
1901
|
+
if HDLRuby::Low::VERILOG_REGS.include?(type.name) then
|
1902
|
+
code << " output reg"
|
1903
|
+
else
|
1904
|
+
code << " output"
|
1905
|
+
end
|
1906
|
+
code << "#{type.to_verilog} #{$vector_reg}:#{$vector_cnt}"
|
1907
|
+
if output.value then
|
1908
|
+
# There is an initial value.
|
1909
|
+
code << " = #{output.value.to_verilog}"
|
1910
|
+
end
|
1911
|
+
code << ";\n"
|
1912
|
+
$vector_cnt += 1
|
1913
|
+
end
|
1914
|
+
else
|
1915
|
+
if HDLRuby::Low::VERILOG_REGS.include?(output.to_verilog) then
|
1992
1916
|
code << " output reg"
|
1993
1917
|
else
|
1994
1918
|
code << " output"
|
1995
1919
|
end
|
1996
|
-
|
1997
|
-
code << "#{type.to_verilog} #{$vector_reg}:#{$vector_cnt}"
|
1920
|
+
code << "#{output.type.to_verilog} #{output.to_verilog}"
|
1998
1921
|
if output.value then
|
1999
1922
|
# There is an initial value.
|
2000
1923
|
code << " = #{output.value.to_verilog}"
|
2001
1924
|
end
|
2002
1925
|
code << ";\n"
|
2003
|
-
$vector_cnt += 1
|
2004
|
-
end
|
2005
|
-
else
|
2006
|
-
# if regs.include?(output.name) then
|
2007
|
-
# if regs.include?(output.to_verilog) then
|
2008
|
-
if HDLRuby::Low::VERILOG_REGS.include?(output.to_verilog) then
|
2009
|
-
code << " output reg"
|
2010
|
-
else
|
2011
|
-
code << " output"
|
2012
|
-
end
|
2013
|
-
# code << "#{output.type.to_verilog} #{output.to_verilog};\n"
|
2014
|
-
code << "#{output.type.to_verilog} #{output.to_verilog}"
|
2015
|
-
if output.value then
|
2016
|
-
# There is an initial value.
|
2017
|
-
code << " = #{output.value.to_verilog}"
|
2018
1926
|
end
|
2019
|
-
code << ";\n"
|
2020
|
-
end
|
2021
|
-
end
|
2022
|
-
|
2023
|
-
# Declare "inout"
|
2024
|
-
self.each_inout do |inout|
|
2025
|
-
if inout.type.respond_to? (:each_type) then
|
2026
|
-
$vector_reg = "#{inout.to_verilog}"
|
2027
|
-
$vector_cnt = 0
|
2028
|
-
inout.type.each_type do |type|
|
2029
|
-
code << "inout #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
|
2030
|
-
$vector_cnt += 1
|
2031
|
-
end
|
2032
|
-
else
|
2033
|
-
code << " inout#{inout.type.to_verilog} #{inout.to_verilog};\n"
|
2034
|
-
end
|
2035
|
-
end
|
2036
|
-
|
2037
|
-
# Declare "inner".
|
2038
|
-
self.each_inner do |inner|
|
2039
|
-
# # if regs.include?(inner.name) then
|
2040
|
-
# if regs.include?(inner.to_verilog) then
|
2041
|
-
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
2042
|
-
code << " reg"
|
2043
|
-
else
|
2044
|
-
code << " wire"
|
2045
1927
|
end
|
2046
1928
|
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
1929
|
+
# Declare "inout"
|
1930
|
+
self.each_inout do |inout|
|
1931
|
+
if inout.type.respond_to? (:each_type) then
|
1932
|
+
$vector_reg = "#{inout.to_verilog}"
|
1933
|
+
$vector_cnt = 0
|
1934
|
+
inout.type.each_type do |type|
|
1935
|
+
code << "inout #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
|
1936
|
+
$vector_cnt += 1
|
1937
|
+
end
|
2051
1938
|
else
|
2052
|
-
|
2053
|
-
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
1939
|
+
code << " inout#{inout.type.to_verilog} #{inout.to_verilog};\n"
|
2054
1940
|
end
|
2055
|
-
else
|
2056
|
-
# code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
2057
|
-
code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
2058
|
-
end
|
2059
|
-
if inner.value then
|
2060
|
-
# There is an initial value.
|
2061
|
-
code << " = #{inner.value.to_verilog}"
|
2062
1941
|
end
|
2063
|
-
code << ";\n"
|
2064
|
-
end
|
2065
1942
|
|
2066
|
-
|
2067
|
-
|
2068
|
-
scope.each_inner do |inner|
|
2069
|
-
# # if regs.include?(inner.name) then
|
2070
|
-
# if regs.include?(inner.to_verilog) then
|
1943
|
+
# Declare "inner".
|
1944
|
+
self.each_inner do |inner|
|
2071
1945
|
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
2072
|
-
code << " reg
|
1946
|
+
code << " reg"
|
2073
1947
|
else
|
2074
|
-
code << " wire
|
1948
|
+
code << " wire"
|
2075
1949
|
end
|
2076
1950
|
|
2077
|
-
if inner.type.
|
2078
|
-
if inner.type.base.base?
|
2079
|
-
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
1951
|
+
if inner.type.base?
|
1952
|
+
if inner.type.base.base?
|
2080
1953
|
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
2081
1954
|
else
|
2082
|
-
# code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
2083
1955
|
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
2084
1956
|
end
|
2085
1957
|
else
|
2086
|
-
|
2087
|
-
code << "inner #{inner.type.to_verilog} #{inner.to_verilog}"
|
1958
|
+
code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
2088
1959
|
end
|
2089
1960
|
if inner.value then
|
2090
1961
|
# There is an initial value.
|
2091
1962
|
code << " = #{inner.value.to_verilog}"
|
2092
1963
|
end
|
2093
1964
|
code << ";\n"
|
2094
|
-
end
|
2095
|
-
|
2096
|
-
scope.each_connection do |connection|
|
2097
|
-
code << "\n"
|
2098
|
-
code << "#{connection.to_verilog}"
|
2099
1965
|
end
|
2100
|
-
end
|
2101
1966
|
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
1967
|
+
# If there is scope in scope, translate it.
|
1968
|
+
self.each_scope do |scope|
|
1969
|
+
scope.each_inner do |inner|
|
1970
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
1971
|
+
code << " reg "
|
1972
|
+
else
|
1973
|
+
code << " wire "
|
1974
|
+
end
|
1975
|
+
|
1976
|
+
if inner.type.respond_to? (:base)
|
1977
|
+
if inner.type.base.base?
|
1978
|
+
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
1979
|
+
else
|
1980
|
+
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
1981
|
+
end
|
1982
|
+
else
|
1983
|
+
code << "inner #{inner.type.to_verilog} #{inner.to_verilog}"
|
1984
|
+
end
|
1985
|
+
if inner.value then
|
1986
|
+
# There is an initial value.
|
1987
|
+
code << " = #{inner.value.to_verilog}"
|
1988
|
+
end
|
1989
|
+
code << ";\n"
|
1990
|
+
end
|
1991
|
+
|
1992
|
+
scope.each_connection do |connection|
|
1993
|
+
code << "\n"
|
1994
|
+
code << "#{connection.to_verilog}"
|
2122
1995
|
end
|
2123
1996
|
end
|
2124
|
-
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
1997
|
+
|
1998
|
+
code << "\n"
|
1999
|
+
|
2000
|
+
# puts "For system=#{self.name}"
|
2001
|
+
# transliation of the instantiation part.
|
2002
|
+
# Generate the instances connections.
|
2003
|
+
self.each_systemI do |systemI|
|
2004
|
+
# puts "Processing systemI = #{systemI.name}"
|
2005
|
+
# Its Declaration.
|
2006
|
+
code << " " * 3
|
2007
|
+
systemT = systemI.systemT
|
2008
|
+
code << name_to_verilog(systemT.name) << " "
|
2009
|
+
vname = name_to_verilog(systemI.name)
|
2010
|
+
systemI.properties[:verilog_name] = vname
|
2011
|
+
code << vname << "("
|
2012
|
+
# Its ports connections
|
2013
|
+
# Inputs
|
2014
|
+
systemT.each_input do |input|
|
2015
|
+
ref = self.extract_port_assign!(systemI,input)
|
2016
|
+
if ref then
|
2017
|
+
code << "." << name_to_verilog(input.name) << "("
|
2018
|
+
code << ref.to_verilog
|
2019
|
+
code << "),"
|
2020
|
+
end
|
2131
2021
|
end
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
|
2136
|
-
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2022
|
+
# Outputs
|
2023
|
+
systemT.each_output do |output|
|
2024
|
+
ref = self.extract_port_assign!(systemI,output)
|
2025
|
+
if ref then
|
2026
|
+
code << "." << name_to_verilog(output.name) << "("
|
2027
|
+
code << ref.to_verilog
|
2028
|
+
code << "),"
|
2029
|
+
end
|
2030
|
+
end
|
2031
|
+
# Inouts
|
2032
|
+
systemT.each_inout do |inout|
|
2033
|
+
ref = self.extract_port_assign!(systemI,inout)
|
2034
|
+
if ref then
|
2035
|
+
code << "." << name_to_verilog(inout.name) << "("
|
2036
|
+
code << ref.to_verilog
|
2037
|
+
code << "),"
|
2038
|
+
end
|
2140
2039
|
end
|
2040
|
+
# Remove the last "," for conforming with Verilog syntax.
|
2041
|
+
# and close the port connection.
|
2042
|
+
code[-1] = ");\n"
|
2141
2043
|
end
|
2142
|
-
# Remove the last "," for conforming with Verilog syntax.
|
2143
|
-
# and close the port connection.
|
2144
|
-
code[-1] = ");\n"
|
2145
|
-
end
|
2146
2044
|
|
2147
2045
|
|
2148
2046
|
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
2047
|
+
# translation of the connection part (assigen).
|
2048
|
+
self.each_connection do |connection|
|
2049
|
+
code << "#{connection.to_verilog}\n"
|
2050
|
+
end
|
2153
2051
|
|
2154
|
-
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2162
|
-
|
2163
|
-
code << " initial "
|
2164
|
-
else
|
2165
|
-
# Generate a standard process.
|
2166
|
-
code << " always @( "
|
2167
|
-
# If there is no "always" condition, it is always @("*").
|
2168
|
-
if behavior.each_event.to_a.empty? then
|
2169
|
-
code << "*"
|
2052
|
+
# Translation of behavior part (always).
|
2053
|
+
self.each_behavior do |behavior|
|
2054
|
+
if behavior.block.is_a?(TimeBlock) then
|
2055
|
+
# Extract and translate the TimeRepeat separately.
|
2056
|
+
behavior.each_block_deep do |blk|
|
2057
|
+
code << blk.repeat_to_verilog!
|
2058
|
+
end
|
2059
|
+
# And generate an initial block.
|
2060
|
+
code << " initial "
|
2170
2061
|
else
|
2171
|
-
|
2172
|
-
|
2173
|
-
|
2174
|
-
|
2175
|
-
|
2062
|
+
# Generate a standard process.
|
2063
|
+
code << " always @( "
|
2064
|
+
# If there is no "always" condition, it is always @("*").
|
2065
|
+
if behavior.each_event.to_a.empty? then
|
2066
|
+
code << "*"
|
2067
|
+
else
|
2068
|
+
event = behavior.each_event.to_a
|
2069
|
+
event[0..-2].each do |event|
|
2070
|
+
# If "posedge" or "negedge" does not exist, the variable is set to condition.
|
2071
|
+
if (event.type.to_s != "posedge" && event.type.to_s != "negedge") then
|
2072
|
+
code << "#{event.ref.to_verilog}, "
|
2073
|
+
else
|
2074
|
+
# Otherwise, it outputs "psoedge" or "negedge" as a condition.
|
2075
|
+
code << "#{event.type.to_s} #{event.ref.to_verilog}, "
|
2076
|
+
end
|
2077
|
+
end
|
2078
|
+
# Since no comma is necessary at the end, we try not to separate commas separately at the end.
|
2079
|
+
if (event.last.type.to_s != "posedge" && event.last.type.to_s != "negedge") then
|
2080
|
+
code << "#{event.last.ref.to_verilog}"
|
2176
2081
|
else
|
2177
|
-
|
2178
|
-
code << "#{event.type.to_s} #{event.ref.to_verilog}, "
|
2082
|
+
code << "#{event.last.type.to_s} #{event.last.ref.to_verilog}"
|
2179
2083
|
end
|
2180
2084
|
end
|
2181
|
-
|
2182
|
-
if (event.last.type.to_s != "posedge" && event.last.type.to_s != "negedge") then
|
2183
|
-
code << "#{event.last.ref.to_verilog}"
|
2184
|
-
else
|
2185
|
-
code << "#{event.last.type.to_s} #{event.last.ref.to_verilog}"
|
2186
|
-
end
|
2085
|
+
code << " ) "
|
2187
2086
|
end
|
2188
|
-
# code << " ) begin\n"
|
2189
|
-
code << " ) "
|
2190
|
-
end
|
2191
|
-
|
2192
|
-
# # Perform "scheduling" using the method "flatten".
|
2193
|
-
# block = behavior.block.flatten(behavior.block.mode.to_s)
|
2194
|
-
# code << block.to_verilog(regs)
|
2195
|
-
code << behavior.block.to_verilog
|
2196
|
-
|
2197
|
-
# # Declaration of "inner" part within "always".
|
2198
|
-
# block.each_inner do |inner|
|
2199
|
-
# # if regs.include?(inner.name) then
|
2200
|
-
# if regs.include?(inner.to_verilog) then
|
2201
|
-
# code << " reg"
|
2202
|
-
# else
|
2203
|
-
# code << " wire"
|
2204
|
-
# end
|
2205
|
-
|
2206
|
-
# # Variable has "base", but if there is width etc, it is not in "base".
|
2207
|
-
# # It is determined by an if.
|
2208
|
-
# if inner.type.base?
|
2209
|
-
# if inner.type.base.base?
|
2210
|
-
# # code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
2211
|
-
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
2212
|
-
# else
|
2213
|
-
# # code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
2214
|
-
# code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
2215
|
-
# end
|
2216
|
-
# else
|
2217
|
-
# # code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
2218
|
-
# code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
2219
|
-
# end
|
2220
|
-
# if inner.value then
|
2221
|
-
# # There is an initial value.
|
2222
|
-
# code << " = #{inner.value.to_verilog}"
|
2223
|
-
# end
|
2224
|
-
# code << ";\n"
|
2225
|
-
# end
|
2226
2087
|
|
2227
|
-
|
2228
|
-
# block.each_statement do |statement|
|
2229
|
-
# code << "\n #{statement.to_verilog(behavior.block.mode.to_s)}"
|
2230
|
-
# end
|
2088
|
+
code << behavior.block.to_verilog
|
2231
2089
|
|
2232
|
-
|
2090
|
+
end
|
2233
2091
|
|
2234
|
-
#
|
2092
|
+
# Conclusion.
|
2093
|
+
code << "\nendmodule"
|
2094
|
+
return code
|
2235
2095
|
end
|
2096
|
+
end
|
2236
2097
|
|
2237
|
-
|
2238
|
-
|
2239
|
-
|
2098
|
+
|
2099
|
+
# Enhance StringE with generation of verilog code.
|
2100
|
+
class StringE
|
2101
|
+
# Converts the system to Verilog code.
|
2102
|
+
def to_verilog(spc = 3)
|
2103
|
+
code = "\"#{Low.v_string(self.content)}" +
|
2104
|
+
"#{self.each_arg.map do |arg|
|
2105
|
+
to.to_verilog
|
2106
|
+
end.join(",")}\""
|
2107
|
+
return code
|
2108
|
+
end
|
2240
2109
|
end
|
2241
|
-
end
|
2242
2110
|
|
2243
2111
|
end
|
2244
2112
|
|