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