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