HDLRuby 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/HDLRuby.gemspec +36 -0
- data/LICENSE.txt +21 -0
- data/README.md +2774 -0
- data/README.pdf +0 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/hdrcc +3 -0
- data/lib/HDLRuby/alcc.rb +137 -0
- data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
- data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
- data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
- data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
- data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
- data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
- data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
- data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
- data/lib/HDLRuby/hdr_samples/include.rb +14 -0
- data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
- data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
- data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
- data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
- data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
- data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
- data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
- data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
- data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
- data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
- data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
- data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
- data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
- data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
- data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
- data/lib/HDLRuby/hdrcc.rb +623 -0
- data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
- data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
- data/lib/HDLRuby/high_samples/adder.rb +21 -0
- data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
- data/lib/HDLRuby/high_samples/addsub.rb +33 -0
- data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
- data/lib/HDLRuby/high_samples/after.rb +28 -0
- data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
- data/lib/HDLRuby/high_samples/alu.rb +61 -0
- data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
- data/lib/HDLRuby/high_samples/before.rb +28 -0
- data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
- data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
- data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
- data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
- data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
- data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
- data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
- data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
- data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
- data/lib/HDLRuby/high_samples/case.rb +32 -0
- data/lib/HDLRuby/high_samples/case2.rb +30 -0
- data/lib/HDLRuby/high_samples/change.rb +23 -0
- data/lib/HDLRuby/high_samples/clocks.rb +35 -0
- data/lib/HDLRuby/high_samples/comparer.rb +21 -0
- data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
- data/lib/HDLRuby/high_samples/dff.rb +23 -0
- data/lib/HDLRuby/high_samples/each.rb +28 -0
- data/lib/HDLRuby/high_samples/exporter.rb +42 -0
- data/lib/HDLRuby/high_samples/functions.rb +60 -0
- data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
- data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
- data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
- data/lib/HDLRuby/high_samples/instance.rb +37 -0
- data/lib/HDLRuby/high_samples/memory.rb +64 -0
- data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
- data/lib/HDLRuby/high_samples/overload.rb +32 -0
- data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
- data/lib/HDLRuby/high_samples/ram.rb +27 -0
- data/lib/HDLRuby/high_samples/registers.rb +139 -0
- data/lib/HDLRuby/high_samples/rom.rb +23 -0
- data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
- data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
- data/lib/HDLRuby/high_samples/shift.rb +31 -0
- data/lib/HDLRuby/high_samples/shift2.rb +40 -0
- data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
- data/lib/HDLRuby/high_samples/test_all.sh +10 -0
- data/lib/HDLRuby/high_samples/typedef.rb +24 -0
- data/lib/HDLRuby/high_samples/values.rb +70 -0
- data/lib/HDLRuby/high_samples/vector.rb +22 -0
- data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
- data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
- data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
- data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
- data/lib/HDLRuby/hruby_bstr.rb +1085 -0
- data/lib/HDLRuby/hruby_check.rb +317 -0
- data/lib/HDLRuby/hruby_db.rb +432 -0
- data/lib/HDLRuby/hruby_error.rb +44 -0
- data/lib/HDLRuby/hruby_high.rb +4103 -0
- data/lib/HDLRuby/hruby_low.rb +4735 -0
- data/lib/HDLRuby/hruby_low2c.rb +1986 -0
- data/lib/HDLRuby/hruby_low2high.rb +738 -0
- data/lib/HDLRuby/hruby_low2seq.rb +248 -0
- data/lib/HDLRuby/hruby_low2sym.rb +126 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
- data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
- data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
- data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
- data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
- data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
- data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
- data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
- data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
- data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
- data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
- data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
- data/lib/HDLRuby/hruby_serializer.rb +398 -0
- data/lib/HDLRuby/hruby_tools.rb +37 -0
- data/lib/HDLRuby/hruby_types.rb +239 -0
- data/lib/HDLRuby/hruby_values.rb +64 -0
- data/lib/HDLRuby/hruby_verilog.rb +1888 -0
- data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
- data/lib/HDLRuby/low_samples/adder.yaml +97 -0
- data/lib/HDLRuby/low_samples/after.yaml +228 -0
- data/lib/HDLRuby/low_samples/before.yaml +223 -0
- data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
- data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
- data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
- data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
- data/lib/HDLRuby/low_samples/case.yaml +327 -0
- data/lib/HDLRuby/low_samples/change.yaml +135 -0
- data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
- data/lib/HDLRuby/low_samples/cloner.rb +22 -0
- data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
- data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
- data/lib/HDLRuby/low_samples/dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/each.yaml +1328 -0
- data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
- data/lib/HDLRuby/low_samples/functions.yaml +298 -0
- data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
- data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
- data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
- data/lib/HDLRuby/low_samples/memory.yaml +678 -0
- data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
- data/lib/HDLRuby/low_samples/overload.yaml +226 -0
- data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
- data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/ram.yaml +207 -0
- data/lib/HDLRuby/low_samples/registers.yaml +228 -0
- data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
- data/lib/HDLRuby/low_samples/shift.yaml +230 -0
- data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
- data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
- data/lib/HDLRuby/low_samples/test_all.sh +43 -0
- data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
- data/lib/HDLRuby/low_samples/values.yaml +577 -0
- data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/vector.yaml +56 -0
- data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
- data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
- data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
- data/lib/HDLRuby/sim/Makefile +19 -0
- data/lib/HDLRuby/sim/hruby_sim.h +590 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
- data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
- data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
- data/lib/HDLRuby/std/channel.rb +354 -0
- data/lib/HDLRuby/std/clocks.rb +165 -0
- data/lib/HDLRuby/std/counters.rb +82 -0
- data/lib/HDLRuby/std/decoder.rb +214 -0
- data/lib/HDLRuby/std/fsm.rb +516 -0
- data/lib/HDLRuby/std/pipeline.rb +220 -0
- data/lib/HDLRuby/std/reconf.rb +309 -0
- data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
- data/lib/HDLRuby/test_hruby_high.rb +594 -0
- data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
- data/lib/HDLRuby/test_hruby_low.rb +934 -0
- data/lib/HDLRuby/v_samples/adder.v +10 -0
- data/lib/HDLRuby/v_samples/dff.v +12 -0
- data/lib/HDLRuby/v_samples/ram.v +20 -0
- data/lib/HDLRuby/v_samples/rom.v +270 -0
- data/lib/HDLRuby/version.rb +3 -0
- data/lib/HDLRuby.rb +11 -0
- data/makedoc +1 -0
- data/metadata.yaml +4 -0
- metadata +299 -0
|
@@ -0,0 +1,1888 @@
|
|
|
1
|
+
require "HDLRuby.rb"
|
|
2
|
+
require "HDLRuby/hruby_verilog_name.rb"
|
|
3
|
+
|
|
4
|
+
require 'HDLRuby/hruby_low_mutable'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# module HDLRuby::Verilog
|
|
8
|
+
include HDLRuby::Verilog
|
|
9
|
+
|
|
10
|
+
#include HDLRuby::Low
|
|
11
|
+
module HDLRuby::Low
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Sample of very handy for programming.
|
|
15
|
+
# puts "class=#{self.yes.class}" # Confirm class of self.yes.
|
|
16
|
+
# puts "methods=#{self.right.methods}" # Confirm method of self.right.
|
|
17
|
+
# puts "outputs=#{outputs}" # Confirm outputs
|
|
18
|
+
|
|
19
|
+
# each. do |*arg| # I forgot this.
|
|
20
|
+
# puts args
|
|
21
|
+
# end
|
|
22
|
+
|
|
23
|
+
# Global variable used for indentation and structure (temporary).
|
|
24
|
+
$space_count = 0 # Count used for increasing indent by if statement. (temporary)
|
|
25
|
+
$vector_reg = "" # For storing signal type at structure declaration. (temporary)
|
|
26
|
+
$vector_cnt = 0 # For allocating numbers at structure declaration. (temporary)
|
|
27
|
+
|
|
28
|
+
class Fixnum
|
|
29
|
+
def to_verilog
|
|
30
|
+
to_s
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Class summarizing "hash" used for "par" or "seq" conversion.
|
|
35
|
+
class Fm
|
|
36
|
+
attr_reader :fm_seq, :fm_par, :rep, :rep_sharp
|
|
37
|
+
def initialize
|
|
38
|
+
@fm_seq = {} # Used to seq -> par.
|
|
39
|
+
@fm_par = {} # Used to par -> seq.
|
|
40
|
+
@rep = {} # Used to give ' to variables
|
|
41
|
+
@rep_sharp = {} # Used to give # to variables
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Declaration of fm to manage each hash.
|
|
46
|
+
$fm = Fm.new
|
|
47
|
+
|
|
48
|
+
# A class that translates the left-hand side, operator, and right-hand side into form of expression.
|
|
49
|
+
class Binary
|
|
50
|
+
# Converts the system to Verilog code.
|
|
51
|
+
def to_verilog
|
|
52
|
+
return "(#{self.left.to_verilog} #{self.operator} #{self.right.to_verilog})"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Method called when two or more expression terms are present.
|
|
56
|
+
# When translating par into seq mode = seq, when translating seq to par mode = par.
|
|
57
|
+
# Search recursively and replace if hash matches identifier.
|
|
58
|
+
def to_change(mode)
|
|
59
|
+
# Recursively search the left side and the right side, check the identifier and replace it.
|
|
60
|
+
if self.left.is_a? (Binary) then
|
|
61
|
+
# If there is an expression on the left side of the right side, to_chang is executed again.
|
|
62
|
+
left = self.left.to_change(mode)
|
|
63
|
+
else
|
|
64
|
+
# If you need to replace the variable, replace it. Otherwise we will get a clone.
|
|
65
|
+
if $fm.fm_par.has_key?(self.left.to_verilog) && mode == :par then
|
|
66
|
+
left = $fm.fm_par["#{self.left.to_verilog}"]
|
|
67
|
+
elsif $fm.fm_seq.has_key?(self.left.to_verilog) && mode == :seq then
|
|
68
|
+
left = $fm.fm_seq["#{self.left.to_verilog}"]
|
|
69
|
+
else
|
|
70
|
+
left = self.left.clone
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
if self.right.is_a? (Binary) then
|
|
74
|
+
# Recursively search the right side and the right side, check the identifier and replace it.
|
|
75
|
+
right = self.right.to_change(mode)
|
|
76
|
+
else
|
|
77
|
+
# If you need to replace the variable, replace it. Otherwise we will get a clone.
|
|
78
|
+
if $fm.fm_par.has_key?(self.right.to_verilog) && mode == :par then
|
|
79
|
+
right = $fm.fm_par["#{self.right.to_verilog}"]
|
|
80
|
+
elsif $fm.fm_seq.has_key?(self.right.to_verilog) && mode == :seq then
|
|
81
|
+
right = $fm.fm_seq["#{self.right.to_verilog}"]
|
|
82
|
+
else
|
|
83
|
+
right = self.right.clone
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
# After confirmation, we create and return an expression.
|
|
87
|
+
return Binary.new(self.type,self.operator,left.clone,right.clone)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# class of Represent blocking substitution or nonblocking assignment.
|
|
92
|
+
# Enhance Transmit with generation of verilog code.
|
|
93
|
+
class Transmit
|
|
94
|
+
# Converts the system to Verilog code.
|
|
95
|
+
def to_verilog(mode = nil)
|
|
96
|
+
# Determine blocking assignment or nonblocking substitution from mode and return it.
|
|
97
|
+
code = "#{self.left.to_verilog} #{mode == "seq" ? "=" : "<="} #{self.right.to_verilog};\n"
|
|
98
|
+
return code
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# To scheduling to the Block.
|
|
103
|
+
# Enhance Block with generation of verilog code.
|
|
104
|
+
class Block
|
|
105
|
+
# Converts the system to Verilog code.
|
|
106
|
+
def to_verilog(mode = nil)
|
|
107
|
+
# No translation is done in this class.
|
|
108
|
+
puts "Block to_verilog not found" # For debugging
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Process top layer of Block.
|
|
112
|
+
# Determine whether there is a block under block and convert it.
|
|
113
|
+
def flatten(mode = nil)
|
|
114
|
+
new_block = Block.new(self.mode,"") # A new block to store the converted statement.
|
|
115
|
+
list = [] # A list for confirming that variable declarations do not overlap.
|
|
116
|
+
|
|
117
|
+
# Is block in the statement?
|
|
118
|
+
if (self.each_statement.find {|stmnt| stmnt.is_a?(Block)}) then
|
|
119
|
+
# Process for each type of statement in block.
|
|
120
|
+
self.each_statement do |statement|
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# If statement is case, there is a block for each default and when, so translate each.
|
|
124
|
+
if statement.is_a?(Case) then
|
|
125
|
+
if statement.default.is_a?(Block)
|
|
126
|
+
default = statement.default.flatten
|
|
127
|
+
new_default = Block.new(default.mode,"")
|
|
128
|
+
|
|
129
|
+
default.each_inner do |inner|
|
|
130
|
+
# I read inner, but when I am par, I delete all '.
|
|
131
|
+
unless (list.include?(inner.name.to_s)) then
|
|
132
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
133
|
+
list << inner.name.to_s
|
|
134
|
+
new_block.add_inner(inner.clone)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
default.each_statement do |statement|
|
|
140
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
141
|
+
if statement.is_a?(Transmit) then
|
|
142
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
143
|
+
unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
|
|
144
|
+
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
|
145
|
+
new_signal = att_signal(statement.left, "#")
|
|
146
|
+
# Check list and add new variables to inner if they do not duplicate.
|
|
147
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
148
|
+
list << new_signal.name.to_s
|
|
149
|
+
new_block.add_inner(new_signal)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
153
|
+
|
|
154
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
155
|
+
|
|
156
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
|
157
|
+
new_default.add_statement(new_statement.clone)
|
|
158
|
+
else
|
|
159
|
+
new_default.add_statement(statement.clone)
|
|
160
|
+
end
|
|
161
|
+
else
|
|
162
|
+
new_default.add_statement(statement.clone)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
|
168
|
+
|
|
169
|
+
statement.each_when do |whens|
|
|
170
|
+
when_smt = whens.statement.flatten
|
|
171
|
+
new_when_smt = Block.new(when_smt.mode,"")
|
|
172
|
+
|
|
173
|
+
when_smt.each_statement do |statement|
|
|
174
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
175
|
+
if statement.is_a?(Transmit) then
|
|
176
|
+
# # If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
177
|
+
unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
|
|
178
|
+
# # Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
|
179
|
+
new_signal = att_signal(statement.left, "#")
|
|
180
|
+
# Check list and add new variables to inner if they do not duplicate.
|
|
181
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
182
|
+
list << new_signal.name.to_s
|
|
183
|
+
new_block.add_inner(new_signal)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
187
|
+
|
|
188
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
189
|
+
|
|
190
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
|
|
191
|
+
new_when_smt.add_statement(new_smt.clone)
|
|
192
|
+
else
|
|
193
|
+
new_when_smt.add_statement(statement.clone)
|
|
194
|
+
end
|
|
195
|
+
else
|
|
196
|
+
new_when_smt.add_statement(statement.clone)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
new_when = When.new(whens.match.clone,new_when_smt.clone)
|
|
201
|
+
new_statement.add_when(new_when.clone)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
new_block.add_statement(new_statement)
|
|
205
|
+
|
|
206
|
+
$fm.rep_sharp.each_key do |key|
|
|
207
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
|
208
|
+
new_block.add_statement(new_smt.clone)
|
|
209
|
+
end
|
|
210
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
|
211
|
+
|
|
212
|
+
# If the statement is if, there is a block for each of yes, no, noifs, so translate each.
|
|
213
|
+
elsif statement.is_a?(If) then
|
|
214
|
+
yes = statement.yes.flatten # Smooth yes of if statement.
|
|
215
|
+
new_yes = Block.new(yes.mode,"") # New yes storage block
|
|
216
|
+
|
|
217
|
+
yes.each_inner do |inner|
|
|
218
|
+
# I read inner, but when I am par, I delete all '.
|
|
219
|
+
unless (list.include?(inner.name.to_s)) then
|
|
220
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
221
|
+
list << inner.name.to_s
|
|
222
|
+
new_block.add_inner(inner.clone)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Check the statements in "yes" in order.
|
|
228
|
+
yes.each_statement do |statement|
|
|
229
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
230
|
+
if statement.is_a?(Transmit) then
|
|
231
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
232
|
+
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
|
233
|
+
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
|
234
|
+
new_signal = att_signal(statement.left, "#")
|
|
235
|
+
# Check list and add new variables to inner if they do not duplicate.
|
|
236
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
237
|
+
list << new_signal.name.to_s
|
|
238
|
+
new_block.add_inner(new_signal)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
242
|
+
|
|
243
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
244
|
+
|
|
245
|
+
new_yes.add_statement(new_statement.clone)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
|
249
|
+
|
|
250
|
+
else
|
|
251
|
+
new_yes.add_statement(statement.clone)
|
|
252
|
+
end
|
|
253
|
+
else
|
|
254
|
+
new_yes.add_statement(statement.clone)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Confirm that "else" exists and convert it if it exists.
|
|
259
|
+
# Because error occurs when trying to convert when "else" does not exist.
|
|
260
|
+
if statement.no.is_a? (Block) then
|
|
261
|
+
no = statement.no.flatten
|
|
262
|
+
new_no = Block.new(no.mode,"")
|
|
263
|
+
|
|
264
|
+
no.each_inner do |inner|
|
|
265
|
+
# I read inner, but when I am par, I delete all '.
|
|
266
|
+
unless (list.include?(inner.name.to_s)) then
|
|
267
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
268
|
+
list << inner.name.to_s
|
|
269
|
+
new_block.add_inner(inner.clone)
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
no.each_statement do |statement|
|
|
275
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
276
|
+
if statement.is_a?(Transmit) then
|
|
277
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
278
|
+
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
|
279
|
+
|
|
280
|
+
new_signal = att_signal(statement.left, "#")
|
|
281
|
+
|
|
282
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
|
283
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
284
|
+
list << new_signal.name.to_s
|
|
285
|
+
new_block.add_inner(new_signal)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
289
|
+
|
|
290
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
291
|
+
|
|
292
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
|
293
|
+
new_no.add_statement(new_statement.clone)
|
|
294
|
+
else
|
|
295
|
+
new_no.add_statement(statement.clone)
|
|
296
|
+
end
|
|
297
|
+
else
|
|
298
|
+
new_no.add_statement(statement.clone)
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# Rebuild the converted "if" as a new" statement (If)".
|
|
304
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
|
305
|
+
|
|
306
|
+
# Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
|
|
307
|
+
# After that, add the converted "noif" to "If".
|
|
308
|
+
statement.each_noif do |condition, block|
|
|
309
|
+
noif = block.flatten
|
|
310
|
+
new_noif = Block.new(noif.mode,"")
|
|
311
|
+
|
|
312
|
+
noif.each_inner do |inner|
|
|
313
|
+
# I read inner, but when I am par, I delete all '.
|
|
314
|
+
unless (list.include?(inner.name.to_s)) then
|
|
315
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
316
|
+
list << inner.name.to_s
|
|
317
|
+
new_block.add_inner(inner.clone)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
noif.each_statement do |statement|
|
|
324
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
325
|
+
if statement.is_a?(Transmit) then
|
|
326
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
327
|
+
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
|
328
|
+
|
|
329
|
+
new_signal = att_signal(statement.left, "#")
|
|
330
|
+
|
|
331
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
|
332
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
333
|
+
list << new_signal.name.to_s
|
|
334
|
+
new_block.add_inner(new_signal)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
338
|
+
|
|
339
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
340
|
+
|
|
341
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
|
342
|
+
new_noif.add_statement(new_statement.clone)
|
|
343
|
+
else
|
|
344
|
+
new_noif.add_statement(statement.clone)
|
|
345
|
+
end
|
|
346
|
+
else
|
|
347
|
+
new_noif.add_statement(statement.clone)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
new_block.add_statement(new_statement.clone)
|
|
355
|
+
|
|
356
|
+
$fm.rep_sharp.each_key do |key|
|
|
357
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
|
358
|
+
new_block.add_statement(new_smt.clone)
|
|
359
|
+
end
|
|
360
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
|
361
|
+
|
|
362
|
+
# Process when "statement" is "Transmit" (just expression).
|
|
363
|
+
# Record the expression in fm_par used for par-> seq and add the expression to new_block which is the "new block".
|
|
364
|
+
elsif statement.is_a?(Transmit) then
|
|
365
|
+
if self.mode == :seq then
|
|
366
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = statement.right
|
|
367
|
+
end
|
|
368
|
+
new_block.add_statement(statement.clone)
|
|
369
|
+
|
|
370
|
+
# When statement is Block (lower layer exists).
|
|
371
|
+
# Smooth the lower layer with do_flat.
|
|
372
|
+
# Add the added variables (inner) and expressions (statement) to new_block, respectively.
|
|
373
|
+
elsif statement.is_a?(Block) then
|
|
374
|
+
smt = statement.do_flat(self.mode)
|
|
375
|
+
|
|
376
|
+
smt.each_inner do |inner|
|
|
377
|
+
# I read inner, but when I am par, I delete all '.
|
|
378
|
+
unless (list.include?(inner.name.to_s)) then
|
|
379
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
380
|
+
list << inner.name.to_s
|
|
381
|
+
new_block.add_inner(inner.clone)
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
smt.each_statement do |tmt|
|
|
386
|
+
# Retrieve the RefName of the variable on the left side and store it in this_name.
|
|
387
|
+
if ((tmt.is_a? (Transmit)) && (self.mode == :seq)) then
|
|
388
|
+
$fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right
|
|
389
|
+
end
|
|
390
|
+
new_block.add_statement(tmt.clone)
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
return new_block # Return the new_block that completed the smoothing.
|
|
396
|
+
|
|
397
|
+
# Processing when there is no block beneath.
|
|
398
|
+
# Unlike ordinary "if" and "case" blocks come down, we check individually block under block.
|
|
399
|
+
else
|
|
400
|
+
self.each_statement do |statement|
|
|
401
|
+
# If the if statement, convert it, otherwise add it as is
|
|
402
|
+
if statement.is_a?(If) then
|
|
403
|
+
# Since yes always exists, it is no problem even if it is converted as it is.
|
|
404
|
+
yes = statement.yes.flatten
|
|
405
|
+
new_yes = Block.new(yes.mode,"")
|
|
406
|
+
|
|
407
|
+
yes.each_inner do |inner|
|
|
408
|
+
# I read inner, but when I am par, I delete all '.
|
|
409
|
+
unless (list.include?(inner.name.to_s)) then
|
|
410
|
+
if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
411
|
+
list << inner.name.to_s
|
|
412
|
+
new_block.add_inner(inner.clone)
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
# Check the statements in "yes" in order.
|
|
418
|
+
yes.each_statement do |statement|
|
|
419
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
420
|
+
if statement.is_a?(Transmit) then
|
|
421
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
422
|
+
unless (res_name(statement.left).name.to_s.include? "'") || yes.mode == :par then
|
|
423
|
+
# Generate a new signal to return #.
|
|
424
|
+
new_signal = att_signal(statement.left, "#")
|
|
425
|
+
|
|
426
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
|
427
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
428
|
+
list << new_signal.name.to_s
|
|
429
|
+
new_block.add_inner(new_signal)
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
433
|
+
|
|
434
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
435
|
+
|
|
436
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
|
437
|
+
new_yes.add_statement(new_statement.clone)
|
|
438
|
+
else
|
|
439
|
+
new_yes.add_statement(statement.clone)
|
|
440
|
+
end
|
|
441
|
+
else
|
|
442
|
+
new_yes.add_statement(statement.clone)
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Confirm that "else" exists and convert it if it exists.
|
|
447
|
+
# Because error occurs when trying to convert when "else" does not exist.
|
|
448
|
+
if statement.no.is_a? (Block) then
|
|
449
|
+
no = statement.no.flatten
|
|
450
|
+
new_no = Block.new(no.mode,"")
|
|
451
|
+
|
|
452
|
+
no.each_inner do |inner|
|
|
453
|
+
# I read inner, but when I am par, I delete all '.
|
|
454
|
+
unless (list.include?(inner.name.to_s)) then
|
|
455
|
+
if (no.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
456
|
+
list << inner.name.to_s
|
|
457
|
+
new_block.add_inner(inner.clone)
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
no.each_statement do |statement|
|
|
463
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
464
|
+
if statement.is_a?(Transmit) then
|
|
465
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
466
|
+
unless (res_name(statement.left).name.to_s.include? "'") || no.mode == :par then
|
|
467
|
+
|
|
468
|
+
new_signal = att_signal(statement.left, "#")
|
|
469
|
+
|
|
470
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
|
471
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
472
|
+
list << new_signal.name.to_s
|
|
473
|
+
new_block.add_inner(new_signal)
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
477
|
+
|
|
478
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
479
|
+
|
|
480
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
|
481
|
+
new_no.add_statement(new_statement.clone)
|
|
482
|
+
else
|
|
483
|
+
new_no.add_statement(statement.clone)
|
|
484
|
+
end
|
|
485
|
+
else
|
|
486
|
+
new_no.add_statement(statement.clone)
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
# Rebuild the converted "if" as a new" statement (If)".
|
|
491
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
|
492
|
+
# Just like "no", check if "noifs (elsif)" exists and if there is, take one by one and convert.
|
|
493
|
+
# After that, add the converted "noif" to "If".
|
|
494
|
+
statement.each_noif do |condition, block|
|
|
495
|
+
|
|
496
|
+
noif = block.flatten
|
|
497
|
+
new_noif = Block.new(noif.mode,"")
|
|
498
|
+
|
|
499
|
+
noif.each_inner do |inner|
|
|
500
|
+
# I read inner, but when I am par, I delete all '.
|
|
501
|
+
unless (list.include?(inner.name.to_s)) then
|
|
502
|
+
if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
503
|
+
list << inner.name.to_s
|
|
504
|
+
new_block.add_inner(inner.clone)
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
noif.each_statement do |statement|
|
|
511
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
512
|
+
if statement.is_a?(Transmit) then
|
|
513
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
514
|
+
unless (res_name(statement.left).name.to_s.include? "'") || noif.mode == :par then
|
|
515
|
+
|
|
516
|
+
new_signal = att_signal(statement.left, "#")
|
|
517
|
+
|
|
518
|
+
# Double declaration of existing variable can not be done, so it is excluded.
|
|
519
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
520
|
+
list << new_signal.name.to_s
|
|
521
|
+
new_block.add_inner(new_signal)
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
new_statement = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
525
|
+
|
|
526
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
527
|
+
|
|
528
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_statement.left
|
|
529
|
+
new_noif.add_statement(new_statement.clone)
|
|
530
|
+
else
|
|
531
|
+
new_noif.add_statement(statement.clone)
|
|
532
|
+
end
|
|
533
|
+
else
|
|
534
|
+
new_noif.add_statement(statement.clone)
|
|
535
|
+
end
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
new_block.add_statement(new_statement.clone)
|
|
542
|
+
|
|
543
|
+
$fm.rep_sharp.each_key do |key|
|
|
544
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
|
545
|
+
new_block.add_statement(new_smt.clone)
|
|
546
|
+
end
|
|
547
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
|
548
|
+
|
|
549
|
+
elsif statement.is_a?(Case) then
|
|
550
|
+
if statement.default.is_a?(Block)
|
|
551
|
+
new_default = statement.default.flatten
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
|
555
|
+
statement.each_when do |whens|
|
|
556
|
+
new_when_statement = whens.statement.flatten
|
|
557
|
+
new_when = When.new(whens.match.clone,new_when_statement.clone)
|
|
558
|
+
|
|
559
|
+
new_statement.add_when(new_when.clone)
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
new_block.add_statement(new_statement)
|
|
563
|
+
else
|
|
564
|
+
new_block.add_statement(statement.clone)
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
return new_block
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
def do_flat(mode = nil)
|
|
572
|
+
flat = Block.new(self.mode,"") # Block between lower layers when converting.
|
|
573
|
+
trans = Block.new(self.mode,"") # The block used for converting itself.
|
|
574
|
+
replase = Block.new(self.mode,"") # block to be used for further conversion in case of if statement.
|
|
575
|
+
list = []
|
|
576
|
+
rep_list = []
|
|
577
|
+
|
|
578
|
+
# If there is a block inside the statement it is not the lowest layer. If there is, it is the lowest layer.
|
|
579
|
+
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
|
|
580
|
+
# In the case of seq, the lower layer is par. Isolate fm_par so that it is not crosstalked.
|
|
581
|
+
if(self.mode == :seq) then
|
|
582
|
+
fm_buckup = $fm.fm_par.clone
|
|
583
|
+
$fm.fm_par.clear()
|
|
584
|
+
|
|
585
|
+
new_block = change_branch(self)
|
|
586
|
+
else
|
|
587
|
+
new_block = self.clone
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
# Process for each statement.
|
|
591
|
+
new_block.each_statement do |statement|
|
|
592
|
+
# If statement is If, convert yes, no, noif and add them to flat.
|
|
593
|
+
if statement.is_a?(Case) then
|
|
594
|
+
if(self.mode == :seq) then
|
|
595
|
+
fm_buckup_if = $fm.fm_par.clone
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
if statement.default.is_a?(Block)
|
|
599
|
+
default = statement.default.flatten
|
|
600
|
+
new_default = Block.new(default.mode,"")
|
|
601
|
+
|
|
602
|
+
default.each_statement do |statement|
|
|
603
|
+
new_default.add_statement(statement.clone)
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
|
609
|
+
|
|
610
|
+
statement.each_when do |whens|
|
|
611
|
+
if(self.mode == :seq) then
|
|
612
|
+
fm_buckup_if.each_key do |key|
|
|
613
|
+
$fm.fm_par[key] = fm_buckup_if[key]
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
when_smt = whens.statement.flatten
|
|
618
|
+
new_when = When.new(whens.match.clone,when_smt.clone)
|
|
619
|
+
new_statement.add_when(new_when.clone)
|
|
620
|
+
end
|
|
621
|
+
flat.add_statement(new_statement)
|
|
622
|
+
|
|
623
|
+
elsif statement.is_a?(If) then
|
|
624
|
+
if(self.mode == :seq) then
|
|
625
|
+
fm_buckup_if = $fm.fm_par.clone
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
# Since yes always exist, convert without confirming.
|
|
629
|
+
new_yes = statement.yes.flatten
|
|
630
|
+
|
|
631
|
+
# I do not know whether no (else) exists, so convert it if it is confirmed.
|
|
632
|
+
if statement.no.is_a? (Block) then
|
|
633
|
+
|
|
634
|
+
if(self.mode == :seq) then
|
|
635
|
+
fm_buckup_if.each_key do |key|
|
|
636
|
+
$fm.fm_par[key] = fm_buckup_if[key]
|
|
637
|
+
end
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
new_no = statement.no.flatten
|
|
641
|
+
end
|
|
642
|
+
# Create a new if statement with converted yes and no.
|
|
643
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
|
644
|
+
|
|
645
|
+
# Since I do not know whether there is noifs (elsif), I convert it and add it if it is confirmed.
|
|
646
|
+
statement.each_noif do |condition, block|
|
|
647
|
+
if(self.mode == :seq) then
|
|
648
|
+
fm_buckup_if.each_key do |key|
|
|
649
|
+
$fm.fm_par[key] = fm_buckup_if[key]
|
|
650
|
+
end
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
new_noif = block.flatten
|
|
654
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
|
655
|
+
end
|
|
656
|
+
# Add the new statement (if statement) created to flat.
|
|
657
|
+
flat.add_statement(new_statement.clone)
|
|
658
|
+
|
|
659
|
+
# If statement is Transmit, record the expression in fm_par and add the expression to flat as it is.
|
|
660
|
+
elsif statement.is_a?(Transmit) then
|
|
661
|
+
if(self.mode == :seq) then
|
|
662
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = statement.right.clone
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
flat.add_statement(statement.clone)
|
|
666
|
+
# If statement is Block, convert it with do_flat and add the returned expression and variable to flat respectively.
|
|
667
|
+
|
|
668
|
+
elsif statement.is_a?(Block) then
|
|
669
|
+
smt = statement.do_flat(self.mode)
|
|
670
|
+
# If smt has inner, check it separately and add it if it's convenient.
|
|
671
|
+
smt.each_inner do |inner|
|
|
672
|
+
if self.mode == :seq then
|
|
673
|
+
unless (list.include?(inner.name.to_s)) then
|
|
674
|
+
list << inner.name.to_s
|
|
675
|
+
flat.add_inner(inner.clone)
|
|
676
|
+
end
|
|
677
|
+
else
|
|
678
|
+
unless (list.include?(inner.name.to_s)) then
|
|
679
|
+
if(inner.name.to_s.include? "#") then
|
|
680
|
+
list << inner.name.to_s
|
|
681
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
|
682
|
+
end
|
|
683
|
+
end
|
|
684
|
+
end
|
|
685
|
+
end
|
|
686
|
+
# If it is seq, the expression after conversion is also likely to be used, so record the expression.
|
|
687
|
+
smt.each_statement do |tmt|
|
|
688
|
+
if self.mode == :seq then
|
|
689
|
+
$fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right.clone
|
|
690
|
+
end
|
|
691
|
+
flat.add_statement(tmt.clone)
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
# Overwrite to restore fm_par which was quarantined.
|
|
697
|
+
if(self.mode == :seq) then
|
|
698
|
+
$fm.fm_par.clear()
|
|
699
|
+
fm_buckup.each_key do |key|
|
|
700
|
+
$fm.fm_par[key] = fm_buckup[key]
|
|
701
|
+
end
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
# Since it is a middle tier itself, it performs flat transformation, shifts inner, and returns the result.
|
|
707
|
+
trans = flat.to_conversion(mode)
|
|
708
|
+
|
|
709
|
+
|
|
710
|
+
# Write an expression that assigns an identifier that added # to an identifier that has not added.
|
|
711
|
+
trans.each_statement do |statement|
|
|
712
|
+
replase.add_statement(statement.clone)
|
|
713
|
+
if statement.is_a?(If)
|
|
714
|
+
$fm.rep_sharp.each_key do |key|
|
|
715
|
+
new_statement = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
|
716
|
+
replase.add_statement(new_statement.clone)
|
|
717
|
+
end
|
|
718
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
|
719
|
+
end
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
# Extract the inner left in flat and add it to replase.
|
|
723
|
+
flat.each_inner do |inner|
|
|
724
|
+
replase.add_inner(inner.clone)
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
# Extract the inner left in trans and add it to replase.
|
|
728
|
+
trans.each_inner do |inner|
|
|
729
|
+
replase.add_inner(inner.clone)
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
return replase
|
|
733
|
+
|
|
734
|
+
# Processing when there is no block (reaching the bottom layer).
|
|
735
|
+
else
|
|
736
|
+
# Since it is the lowest layer, it does not smooth but converts itself and returns it.
|
|
737
|
+
flat = self.to_conversion(mode)
|
|
738
|
+
return flat
|
|
739
|
+
end
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
def to_conversion(mode = nil, rst = true, rep = true)
|
|
743
|
+
flat = Block.new(mode,"") # Block that stores results.
|
|
744
|
+
new_yes = Block.new(mode,"") # Block containing the new yes.
|
|
745
|
+
new_no = Block.new(mode,"") # Block containing the new no.
|
|
746
|
+
new_noif = Block.new(mode,"") # Block containing the new noif.
|
|
747
|
+
list = []
|
|
748
|
+
|
|
749
|
+
if rst == false then
|
|
750
|
+
fm_seq_backup = $fm.fm_seq.dup
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
# The statement is divided (since it is the lowest layer, there is only Transmit).
|
|
754
|
+
self.each_statement do |statement|
|
|
755
|
+
# Various processing is performed depending on the type of Transmit.
|
|
756
|
+
# If the mode of the upper layer = its own mode, it compresses as it is.
|
|
757
|
+
|
|
758
|
+
if(mode == self.mode) then
|
|
759
|
+
new_statement = statement.clone
|
|
760
|
+
# In the case of an If statement, processing of if, else, elsif is performed.
|
|
761
|
+
elsif statement.is_a?(Case) then
|
|
762
|
+
|
|
763
|
+
if statement.default.is_a?(Block)
|
|
764
|
+
rep_buckup = $fm.rep.dup
|
|
765
|
+
$fm.rep.clear()
|
|
766
|
+
default = statement.default.to_conversion(mode,false,false)
|
|
767
|
+
$fm.rep.clear()
|
|
768
|
+
rep_buckup.each_key do |key|
|
|
769
|
+
$fm.rep[key] = rep_buckup[key]
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
new_default = Block.new(default.mode,"")
|
|
773
|
+
|
|
774
|
+
default.each_inner do |inner|
|
|
775
|
+
# I read inner, but when I am par, I delete all '.
|
|
776
|
+
unless (list.include?(inner.name.to_s)) then
|
|
777
|
+
if (self.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
778
|
+
list << inner.name.to_s
|
|
779
|
+
flat.add_inner(inner.clone)
|
|
780
|
+
end
|
|
781
|
+
end
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
default.each_statement do |statement|
|
|
785
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
786
|
+
if statement.is_a?(Transmit) then
|
|
787
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
788
|
+
unless (res_name(statement.left).name.to_s.include? "'") || default.mode == :par then
|
|
789
|
+
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
|
790
|
+
new_signal = att_signal(statement.left, "#")
|
|
791
|
+
# Check list and add new variables to inner if they do not duplicate.
|
|
792
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
793
|
+
list << new_signal.name.to_s
|
|
794
|
+
flat.add_inner(new_signal)
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
798
|
+
|
|
799
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
800
|
+
|
|
801
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
|
|
802
|
+
new_default.add_statement(new_smt.clone)
|
|
803
|
+
else
|
|
804
|
+
new_default.add_statement(statement.clone)
|
|
805
|
+
end
|
|
806
|
+
else
|
|
807
|
+
new_default.add_statement(statement.clone)
|
|
808
|
+
end
|
|
809
|
+
end
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
|
814
|
+
|
|
815
|
+
statement.each_when do |whens|
|
|
816
|
+
|
|
817
|
+
rep_buckup = $fm.rep.dup
|
|
818
|
+
$fm.rep.clear()
|
|
819
|
+
when_smt = whens.statement.to_conversion(mode,false,false)
|
|
820
|
+
$fm.rep.clear()
|
|
821
|
+
rep_buckup.each_key do |key|
|
|
822
|
+
$fm.rep[key] = rep_buckup[key]
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
new_when_smt = Block.new(when_smt.mode,"")
|
|
826
|
+
|
|
827
|
+
when_smt.each_statement do |statement|
|
|
828
|
+
# If statement is Transmit, it is an expression and should be processed.
|
|
829
|
+
if statement.is_a?(Transmit) then
|
|
830
|
+
# If you add a # to the one with 'on the left side, the shape of the formula will collapse and it will be removed.
|
|
831
|
+
unless (res_name(statement.left).name.to_s.include? "'") || when_smt.mode == :par then
|
|
832
|
+
# Prepare a new signal with the # on the variable on the left side using the att_signal method.
|
|
833
|
+
new_signal = att_signal(statement.left, "#")
|
|
834
|
+
# Check list and add new variables to inner if they do not duplicate.
|
|
835
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
836
|
+
list << new_signal.name.to_s
|
|
837
|
+
flat.add_inner(new_signal)
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
new_smt = Transmit.new(search_refname(statement.left,"#"),statement.right.clone)
|
|
841
|
+
|
|
842
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
843
|
+
|
|
844
|
+
$fm.fm_par["#{statement.left.to_verilog}"] = new_smt.left
|
|
845
|
+
new_when_smt.add_statement(new_smt.clone)
|
|
846
|
+
else
|
|
847
|
+
new_when_smt.add_statement(statement.clone)
|
|
848
|
+
end
|
|
849
|
+
else
|
|
850
|
+
new_when_smt.add_statement(statement.clone)
|
|
851
|
+
end
|
|
852
|
+
end
|
|
853
|
+
|
|
854
|
+
new_when = When.new(whens.match.clone,new_when_smt.clone)
|
|
855
|
+
new_statement.add_when(new_when.clone)
|
|
856
|
+
end
|
|
857
|
+
|
|
858
|
+
elsif statement.is_a?(If) then
|
|
859
|
+
|
|
860
|
+
rep_buckup = $fm.rep.dup
|
|
861
|
+
$fm.rep.clear()
|
|
862
|
+
yes = statement.yes.to_conversion(mode, false,false)
|
|
863
|
+
$fm.rep.clear()
|
|
864
|
+
rep_buckup.each_key do |key|
|
|
865
|
+
$fm.rep[key] = rep_buckup[key]
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
yes.each_inner do |inner|
|
|
869
|
+
unless (list.include?(inner.name.to_s)) then
|
|
870
|
+
if (yes.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
871
|
+
list << inner.name.to_s
|
|
872
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
|
873
|
+
end
|
|
874
|
+
end
|
|
875
|
+
end
|
|
876
|
+
|
|
877
|
+
yes.each_statement do |smt|
|
|
878
|
+
if(yes.mode == :seq) then
|
|
879
|
+
new_signal = att_signal(smt.left, "#")
|
|
880
|
+
|
|
881
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
882
|
+
list << new_signal.name.to_s
|
|
883
|
+
flat.add_inner(new_signal)
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
yes_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
|
|
887
|
+
|
|
888
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
889
|
+
|
|
890
|
+
$fm.fm_par["#{smt.left.to_verilog}"] = yes_statement.left
|
|
891
|
+
new_yes.add_statement(yes_statement)
|
|
892
|
+
else
|
|
893
|
+
new_yes.add_statement(smt.clone)
|
|
894
|
+
end
|
|
895
|
+
end
|
|
896
|
+
|
|
897
|
+
if statement.no.is_a? (Block) then
|
|
898
|
+
rep_buckup = $fm.rep.dup
|
|
899
|
+
$fm.rep.clear()
|
|
900
|
+
no = statement.no.to_conversion(mode,false,false)
|
|
901
|
+
$fm.rep.clear()
|
|
902
|
+
rep_buckup.each_key do |key|
|
|
903
|
+
$fm.rep[key] = rep_buckup[key]
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
no.each_inner do |inner|
|
|
907
|
+
unless (list.include?(inner.name.to_s)) then
|
|
908
|
+
if (no.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
909
|
+
list << inner.name.to_s
|
|
910
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
|
911
|
+
end
|
|
912
|
+
end
|
|
913
|
+
end
|
|
914
|
+
|
|
915
|
+
no.each_statement do |smt|
|
|
916
|
+
if(no.mode == :seq) then
|
|
917
|
+
new_signal = att_signal(smt.left, "#")
|
|
918
|
+
|
|
919
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
920
|
+
list << new_signal.name.to_s
|
|
921
|
+
flat.add_inner(new_signal)
|
|
922
|
+
end
|
|
923
|
+
|
|
924
|
+
no_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
|
|
925
|
+
|
|
926
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
927
|
+
|
|
928
|
+
$fm.fm_par["#{smt.left.to_verilog}"] = no_statement.left
|
|
929
|
+
new_no.add_statement(no_statement)
|
|
930
|
+
else
|
|
931
|
+
new_no.add_statement(smt.clone)
|
|
932
|
+
end
|
|
933
|
+
end
|
|
934
|
+
end
|
|
935
|
+
|
|
936
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
|
937
|
+
|
|
938
|
+
statement.each_noif do |condition, block|
|
|
939
|
+
rep_buckup = $fm.rep.dup
|
|
940
|
+
$fm.rep.clear()
|
|
941
|
+
noif = block.to_conversion(mode,false,false)
|
|
942
|
+
$fm.rep.clear()
|
|
943
|
+
rep_buckup.each_key do |key|
|
|
944
|
+
$fm.rep[key] = rep_buckup[key]
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
noif.each_inner do |inner|
|
|
948
|
+
unless (list.include?(inner.name.to_s)) then
|
|
949
|
+
if (noif.mode == :seq) || (inner.name.to_s.include? "#") then
|
|
950
|
+
list << inner.name.to_s
|
|
951
|
+
flat.add_inner(inner.clone) # It was new_block. why?
|
|
952
|
+
end
|
|
953
|
+
end
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
noif.each_statement do |smt|
|
|
957
|
+
if(noif.mode == :seq) then
|
|
958
|
+
new_signal = att_signal(smt.left, "#")
|
|
959
|
+
|
|
960
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
961
|
+
list << new_signal.name.to_s
|
|
962
|
+
flat.add_inner(new_signal)
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
noif_statement = Transmit.new(search_refname(smt.left,"#"),smt.right.clone)
|
|
966
|
+
|
|
967
|
+
$fm.rep_sharp[statement.left] = search_refname(statement.left,"#")
|
|
968
|
+
|
|
969
|
+
$fm.fm_par["#{smt.left.to_verilog}"] = noif_statement.left
|
|
970
|
+
new_noif.add_statement(no_statement)
|
|
971
|
+
else
|
|
972
|
+
new_noif.add_statement(smt.clone)
|
|
973
|
+
end
|
|
974
|
+
end
|
|
975
|
+
|
|
976
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
|
977
|
+
end
|
|
978
|
+
|
|
979
|
+
# Otherwise, it is necessary to process par-> seq or seq-> par.
|
|
980
|
+
else
|
|
981
|
+
# Make sure the right side is a formula (Binary).
|
|
982
|
+
if statement.right.is_a?(Binary) then
|
|
983
|
+
# Check the right side and the left side, and if they are variables, check the corresponding expressions and replace them.
|
|
984
|
+
# If it is not a variable, it calls the method to be searched.
|
|
985
|
+
if statement.right.left.is_a? (Ref) then
|
|
986
|
+
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.left.to_verilog) then
|
|
987
|
+
statement_left = $fm.fm_seq["#{statement.right.left.to_verilog}"]
|
|
988
|
+
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.left.to_verilog) then
|
|
989
|
+
statement_left = $fm.fm_par["#{statement.right.left.to_verilog}"]
|
|
990
|
+
else
|
|
991
|
+
statement_left = statement.right.left.clone
|
|
992
|
+
end
|
|
993
|
+
elsif statement.right.left.is_a? (Binary) then
|
|
994
|
+
statement_left = statement.right.left.to_change(self.mode)
|
|
995
|
+
else
|
|
996
|
+
statement_left = statement.right.left.clone
|
|
997
|
+
end
|
|
998
|
+
|
|
999
|
+
if statement.right.right.is_a? (Ref) then
|
|
1000
|
+
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.right.to_verilog) then
|
|
1001
|
+
statement_right = $fm.fm_seq["#{statement.right.right.to_verilog}"]
|
|
1002
|
+
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.right.to_verilog) then
|
|
1003
|
+
statement_right = $fm.fm_par["#{statement.right.right.to_verilog}"]
|
|
1004
|
+
else
|
|
1005
|
+
statement_right = statement.right.right.clone
|
|
1006
|
+
end
|
|
1007
|
+
elsif statement.right.right.is_a? (Binary) then
|
|
1008
|
+
statement_right = statement.right.right.to_change(self.mode)
|
|
1009
|
+
else
|
|
1010
|
+
statement_right = statement.right.right.clone
|
|
1011
|
+
end
|
|
1012
|
+
new_right = Binary.new(statement.right.type,statement.right.operator,statement_left.clone,statement_right.clone)
|
|
1013
|
+
# Confirm whether it is a variable.
|
|
1014
|
+
elsif statement.right.is_a?(Ref) then
|
|
1015
|
+
if (mode == :par && self.mode == :seq) && $fm.fm_seq.has_key?(statement.right.to_verilog) then
|
|
1016
|
+
new_right = $fm.fm_seq["#{statement.right.to_verilog}"].clone
|
|
1017
|
+
elsif (mode == :seq && self.mode == :par) && $fm.fm_par.has_key?(statement.right.to_verilog) then
|
|
1018
|
+
new_right = $fm.fm_par["#{statement.right.to_verilog}"].clone
|
|
1019
|
+
else
|
|
1020
|
+
new_right = statement.right.clone
|
|
1021
|
+
end
|
|
1022
|
+
# Because it is not a number. Put it in as it is.
|
|
1023
|
+
else
|
|
1024
|
+
new_right = statement.right.clone
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
if (mode == :par && self.mode == :seq) then
|
|
1028
|
+
# Dock the existing left hand side and the replaced right hand side to create a new expression.
|
|
1029
|
+
# Record the expression after conversion to hash to continue seq-> par.
|
|
1030
|
+
new_statement = Transmit.new(statement.left.clone,new_right)
|
|
1031
|
+
$fm.fm_seq["#{statement.left.to_verilog}"] = new_right
|
|
1032
|
+
elsif (mode == :seq && self.mode == :par) && (rep) then
|
|
1033
|
+
unless (res_name(statement.left).name.to_s.include? "#")
|
|
1034
|
+
# Search the variable on the left side and give 'to the name.
|
|
1035
|
+
new_signal = att_signal(statement.left,"'")
|
|
1036
|
+
|
|
1037
|
+
unless (list.include?(new_signal.name.to_s)) then
|
|
1038
|
+
list << new_signal.name.to_s
|
|
1039
|
+
flat.add_inner(new_signal)
|
|
1040
|
+
end
|
|
1041
|
+
|
|
1042
|
+
new_statement = Transmit.new(search_refname(statement.left,"'"),new_right)
|
|
1043
|
+
|
|
1044
|
+
$fm.rep[statement.left] = new_statement
|
|
1045
|
+
end
|
|
1046
|
+
else
|
|
1047
|
+
new_statement = Transmit.new(statement.left.clone,new_right)
|
|
1048
|
+
end
|
|
1049
|
+
end
|
|
1050
|
+
# Add the converted statement to flat (because par -> par or seq -> seq will be added until then).
|
|
1051
|
+
|
|
1052
|
+
if new_statement.is_a?(Transmit) then
|
|
1053
|
+
unless (mode == :par && self.mode == :seq) && (res_name(new_statement.left).name.to_s.include? "'") then
|
|
1054
|
+
flat.add_statement(new_statement.clone)
|
|
1055
|
+
end
|
|
1056
|
+
else
|
|
1057
|
+
flat.add_statement(new_statement.clone)
|
|
1058
|
+
end
|
|
1059
|
+
|
|
1060
|
+
if (rep)
|
|
1061
|
+
$fm.rep_sharp.each_key do |key|
|
|
1062
|
+
new_smt = Transmit.new(key.clone,$fm.rep_sharp[key].clone)
|
|
1063
|
+
flat.add_statement(new_smt.clone)
|
|
1064
|
+
end
|
|
1065
|
+
$fm.rep_sharp.clear() # Deactivate rep that has become obsolete.
|
|
1066
|
+
end
|
|
1067
|
+
end
|
|
1068
|
+
# Add an expression after paragraph based on rep.
|
|
1069
|
+
# A complement expression like x = x '.
|
|
1070
|
+
$fm.rep.each_key do |key|
|
|
1071
|
+
new_statement = Transmit.new(key.clone,$fm.rep[key].left.clone)
|
|
1072
|
+
flat.add_statement(new_statement.clone)
|
|
1073
|
+
end
|
|
1074
|
+
$fm.rep.clear() # Deactivate rep that has become obsolete.
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
# Since seq -> par is the end, fm_par is deleted.
|
|
1078
|
+
if (mode == :par && self.mode == :seq) then
|
|
1079
|
+
$fm.fm_seq.clear()
|
|
1080
|
+
end
|
|
1081
|
+
|
|
1082
|
+
# In case of if statement (when rst == false) you can not convert no or else if you delete the contents of fm_seq.
|
|
1083
|
+
# Therefore, in this case restore the backup to restore.
|
|
1084
|
+
# This means that it is necessary to erase fm_seq once obtained in the if statement once.
|
|
1085
|
+
if(rst == false) then
|
|
1086
|
+
$fm.fm_seq.clear()
|
|
1087
|
+
fm_seq_backup.each_key do |key|
|
|
1088
|
+
$fm.fm_seq[key] = fm_seq_backup[key]
|
|
1089
|
+
end
|
|
1090
|
+
end
|
|
1091
|
+
|
|
1092
|
+
return flat # Return flat finished checking.
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
def change_branch(block)
|
|
1097
|
+
flat = Block.new(self.mode,"") # Store the expression until if is found.
|
|
1098
|
+
trans = Block.new(self.mode,"") # A block that stores the expression after if is found.
|
|
1099
|
+
new_block = Block.new(self.mode,"") # Block storing each converted expression.
|
|
1100
|
+
|
|
1101
|
+
has_branch = false # It is true if there is an if in the block.
|
|
1102
|
+
more_has_branch = false # It is true if there are two or more if in the block.
|
|
1103
|
+
|
|
1104
|
+
# Search each expression for if.
|
|
1105
|
+
block.each_statement do |statement|
|
|
1106
|
+
if (has_branch)
|
|
1107
|
+
trans.add_statement(statement.clone)
|
|
1108
|
+
if statement.is_a?(If) || statement.is_a?(Case) then
|
|
1109
|
+
more_has_branch = true
|
|
1110
|
+
end
|
|
1111
|
+
else
|
|
1112
|
+
if statement.is_a?(If) || statement.is_a?(Case) then
|
|
1113
|
+
flat.add_statement(statement.clone)
|
|
1114
|
+
has_branch = true
|
|
1115
|
+
else
|
|
1116
|
+
flat.add_statement(statement.clone)
|
|
1117
|
+
end
|
|
1118
|
+
end
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
# If there are two or more if, recursively process if.
|
|
1122
|
+
if(more_has_branch) then
|
|
1123
|
+
conversion_block = change_branch(trans)
|
|
1124
|
+
else
|
|
1125
|
+
conversion_block = trans.clone
|
|
1126
|
+
end
|
|
1127
|
+
|
|
1128
|
+
# Store "trans" contents for "if" and "case" in "flat".
|
|
1129
|
+
flat.each_statement do |statement|
|
|
1130
|
+
# Since case statements include defaulu and when, we store the expressions saved in each case.
|
|
1131
|
+
if statement.is_a?(Case) then
|
|
1132
|
+
if statement.default.is_a?(Block)
|
|
1133
|
+
new_default = statement.default.clone
|
|
1134
|
+
conversion_block.each_statement do |smt|
|
|
1135
|
+
new_default.add_statement(smt.clone)
|
|
1136
|
+
end
|
|
1137
|
+
end
|
|
1138
|
+
|
|
1139
|
+
new_statement = Case.new(statement.value.clone,statement.default ? new_default.clone : nil,[])
|
|
1140
|
+
|
|
1141
|
+
statement.each_when do |whens|
|
|
1142
|
+
new_when = whens.clone
|
|
1143
|
+
|
|
1144
|
+
conversion_block.each_statement do |smt|
|
|
1145
|
+
new_when.statement.add_statement(smt.clone)
|
|
1146
|
+
end
|
|
1147
|
+
new_statement.add_when(new_when.clone)
|
|
1148
|
+
end
|
|
1149
|
+
|
|
1150
|
+
new_block.add_statement(new_statement.clone)
|
|
1151
|
+
# Because there are yes, no and noifs in the if statement, store the expression saved in each.
|
|
1152
|
+
elsif statement.is_a?(If) then
|
|
1153
|
+
new_yes = statement.yes.clone
|
|
1154
|
+
conversion_block.each_statement do |smt|
|
|
1155
|
+
new_yes.add_statement(smt.clone)
|
|
1156
|
+
end
|
|
1157
|
+
|
|
1158
|
+
if statement.no.is_a? (Block) then
|
|
1159
|
+
new_no = statement.no.clone
|
|
1160
|
+
conversion_block.each_statement do |smt|
|
|
1161
|
+
new_no.add_statement(smt.clone)
|
|
1162
|
+
end
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
# Make new if with converted yes and no.
|
|
1166
|
+
new_statement = If.new(statement.condition.clone,new_yes.clone,statement.no ? new_no.clone : nil)
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
statement.each_noif do |condition, block|
|
|
1170
|
+
new_noif = block.clone
|
|
1171
|
+
conversion_block.each_statement do |smt|
|
|
1172
|
+
new_noif.add_statement(smt.clone)
|
|
1173
|
+
end
|
|
1174
|
+
new_statement.add_noif(condition.clone,new_noif.clone)
|
|
1175
|
+
end
|
|
1176
|
+
# Add the new statement (if) created to flat.
|
|
1177
|
+
new_block.add_statement(new_statement.clone)
|
|
1178
|
+
else
|
|
1179
|
+
new_block.add_statement(statement.clone)
|
|
1180
|
+
end
|
|
1181
|
+
end
|
|
1182
|
+
|
|
1183
|
+
return new_block # Return block after conversion.
|
|
1184
|
+
end
|
|
1185
|
+
|
|
1186
|
+
# Generate a signal for the variable to which "'" or "#" is added.
|
|
1187
|
+
def att_signal(left,att = "'")
|
|
1188
|
+
this_name = res_name(left)
|
|
1189
|
+
new_name = RefName.new(this_name.type, this_name.ref.clone, this_name.name.to_s + att)
|
|
1190
|
+
new_signal = SignalI.new(new_name.name,new_name.type)
|
|
1191
|
+
|
|
1192
|
+
return new_signal
|
|
1193
|
+
end
|
|
1194
|
+
|
|
1195
|
+
# A method that takes a variable from the sent left side and adds "att".
|
|
1196
|
+
def att_sharp(left,att = "'")
|
|
1197
|
+
#if left.is_a?(RefName) then
|
|
1198
|
+
new_left = search_refname(left, att)
|
|
1199
|
+
#elsif left.is_a?(RefIndex) then
|
|
1200
|
+
# new_ref = search_refname(left, att)
|
|
1201
|
+
# new_left = RefIndex.new(left.type, new_ref, left.index.clone)
|
|
1202
|
+
#elsif left.is_a?(RefRange) then
|
|
1203
|
+
# new_ref = search_refname(left, att)
|
|
1204
|
+
# my_range = left.range
|
|
1205
|
+
# new_left = RefRange.new(left.type, new_ref, my_range.first.clone..my_range.last.clone)
|
|
1206
|
+
#end
|
|
1207
|
+
|
|
1208
|
+
# Add new signal to hash.
|
|
1209
|
+
# if(att == "#") then
|
|
1210
|
+
# $fm.rep_sharp[left] = new_left
|
|
1211
|
+
# end
|
|
1212
|
+
return new_left
|
|
1213
|
+
end
|
|
1214
|
+
|
|
1215
|
+
|
|
1216
|
+
# Recursively search, add "att" to RefName and return.
|
|
1217
|
+
def search_refname(me,att = "'")
|
|
1218
|
+
if me.is_a? (RefName) then
|
|
1219
|
+
return RefName.new(me.type, me.ref.clone, me.name.to_s + att)
|
|
1220
|
+
elsif me.ref.is_a? (RefName) then
|
|
1221
|
+
return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s + att)
|
|
1222
|
+
elsif me.ref.is_a? (RefIndex) then
|
|
1223
|
+
return RefIndex.new(me.ref.type, search_refname(me.ref), me.ref.index.clone)
|
|
1224
|
+
elsif me.ref.is_a? (RefRange) then
|
|
1225
|
+
my_range = me.ref.range
|
|
1226
|
+
return RefRange.new(me.ref.type, search_refname(me.ref), my_range.first.clone..my_range.last.clone)
|
|
1227
|
+
end
|
|
1228
|
+
end
|
|
1229
|
+
|
|
1230
|
+
# Recursively search, return Refname.
|
|
1231
|
+
def res_name(me)
|
|
1232
|
+
if me.is_a? (RefName) then
|
|
1233
|
+
return me
|
|
1234
|
+
else
|
|
1235
|
+
if me.ref.is_a? (RefName) then
|
|
1236
|
+
return RefName.new(me.ref.type, me.ref.ref.clone, me.ref.name.to_s)
|
|
1237
|
+
elsif me.ref.is_a? (RefIndex) then
|
|
1238
|
+
return res_name(me.ref)
|
|
1239
|
+
elsif me.ref.is_a? (RefRange) then
|
|
1240
|
+
return res_name(me.ref)
|
|
1241
|
+
end
|
|
1242
|
+
end
|
|
1243
|
+
end
|
|
1244
|
+
end
|
|
1245
|
+
|
|
1246
|
+
# Used to display variable names.
|
|
1247
|
+
# Enhance RefName with generation of verilog code.
|
|
1248
|
+
class RefName
|
|
1249
|
+
# Converts the system to Verilog code using +renamer+ for producing Verilog-compatible names.
|
|
1250
|
+
def to_verilog
|
|
1251
|
+
# return "#{self.name.to_s}"
|
|
1252
|
+
return "#{name_to_verilog(self.name)}"
|
|
1253
|
+
end
|
|
1254
|
+
|
|
1255
|
+
# Used for instantiation (emergency procedure).
|
|
1256
|
+
def to_another_verilog
|
|
1257
|
+
return "_#{self.name.to_s}"
|
|
1258
|
+
end
|
|
1259
|
+
|
|
1260
|
+
def ancestor(my)
|
|
1261
|
+
if my.parent.parent.respond_to? (:mode) then
|
|
1262
|
+
return ancestor(my.parent)
|
|
1263
|
+
else
|
|
1264
|
+
return "#{my.parent.mode.to_s}#{my.mode.to_s}"
|
|
1265
|
+
end
|
|
1266
|
+
end
|
|
1267
|
+
end
|
|
1268
|
+
|
|
1269
|
+
# Used to convert an array.
|
|
1270
|
+
# Enhance RefIndex with generation of verilog code.
|
|
1271
|
+
class RefIndex
|
|
1272
|
+
# Converts the system to Verilog code.
|
|
1273
|
+
def to_verilog
|
|
1274
|
+
return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
|
|
1275
|
+
end
|
|
1276
|
+
end
|
|
1277
|
+
|
|
1278
|
+
|
|
1279
|
+
# Used to indicate the number of bits.
|
|
1280
|
+
# Enhance TypeVector with generation of verilog code.
|
|
1281
|
+
class TypeVector
|
|
1282
|
+
# Converts the system to Verilog code.
|
|
1283
|
+
def to_verilog
|
|
1284
|
+
if self.base.name.to_s != "bit"
|
|
1285
|
+
return " #{self.base.name.to_s}[#{self.range.first}:#{self.range.last}]"
|
|
1286
|
+
end
|
|
1287
|
+
return " [#{self.range.first}:#{self.range.last}]"
|
|
1288
|
+
end
|
|
1289
|
+
end
|
|
1290
|
+
|
|
1291
|
+
# Necessary for displaying bit width (eg, specify and assign).
|
|
1292
|
+
class RefRange
|
|
1293
|
+
# Converts the system to Verilog code.
|
|
1294
|
+
def to_verilog(unknown = false)
|
|
1295
|
+
return "#{self.ref.to_verilog}[#{self.range.first.to_getrange}:#{self.range.last.to_getrange}]"
|
|
1296
|
+
end
|
|
1297
|
+
end
|
|
1298
|
+
|
|
1299
|
+
# Used to output bitstring.
|
|
1300
|
+
# Enhance HDLRuby with generation of verilog code.
|
|
1301
|
+
class HDLRuby::BitString
|
|
1302
|
+
# Converts the system to Verilog code.
|
|
1303
|
+
def to_verilog
|
|
1304
|
+
return "#{self.to_s}"
|
|
1305
|
+
end
|
|
1306
|
+
end
|
|
1307
|
+
|
|
1308
|
+
# Used for connection using choice.
|
|
1309
|
+
# Enhance Select with generation of verilog code.
|
|
1310
|
+
class Select
|
|
1311
|
+
# Converts the system to Verilog code.
|
|
1312
|
+
def to_verilog
|
|
1313
|
+
# Outputs the first and second choices (choice (0) and choice (1)).
|
|
1314
|
+
return "#{self.select.to_verilog} == 1 #{self.operator} #{self.get_choice(0).to_verilog} : #{self.get_choice(1).to_verilog}"
|
|
1315
|
+
end
|
|
1316
|
+
end
|
|
1317
|
+
|
|
1318
|
+
# Used to output numbers.
|
|
1319
|
+
# Enhance Value with generation of verilog code.
|
|
1320
|
+
class Value
|
|
1321
|
+
# Converts the system to Verilog code.
|
|
1322
|
+
# If it is bit, it is b, and if it is int, it is represented by d. (Example: 4'b0000, 32'd1)
|
|
1323
|
+
def to_verilog(unknown = nil)
|
|
1324
|
+
if self.type.base.name.to_s == "bit"
|
|
1325
|
+
return "#{self.type.range.first + 1}'b#{self.content.to_verilog}"
|
|
1326
|
+
elsif self.type.name.to_s == "integer"
|
|
1327
|
+
return "#{self.type.range.first + 1}'d#{self.content.to_verilog}"
|
|
1328
|
+
end
|
|
1329
|
+
return "#{self.content.to_verilog}"
|
|
1330
|
+
end
|
|
1331
|
+
# How to use when simply obtaining the width
|
|
1332
|
+
def to_getrange
|
|
1333
|
+
return "#{self.content.to_verilog}"
|
|
1334
|
+
end
|
|
1335
|
+
end
|
|
1336
|
+
|
|
1337
|
+
# Used to transrate if.
|
|
1338
|
+
# Enhance If with generation of verilog code.
|
|
1339
|
+
class If
|
|
1340
|
+
# Converts the system to Verilog code.
|
|
1341
|
+
def to_verilog(mode = nil)
|
|
1342
|
+
|
|
1343
|
+
$blocking = false
|
|
1344
|
+
|
|
1345
|
+
if ($space_count == 0) then
|
|
1346
|
+
result = " " * ($space_count) # Indented based on space_count.
|
|
1347
|
+
else
|
|
1348
|
+
result = ""
|
|
1349
|
+
end
|
|
1350
|
+
$space_count += 1 # Add count to be used for indentation.
|
|
1351
|
+
|
|
1352
|
+
result << "if (#{self.condition.to_verilog}) begin\n"
|
|
1353
|
+
|
|
1354
|
+
|
|
1355
|
+
# Check if there is yes (if) and output yes or less.
|
|
1356
|
+
if self.respond_to? (:yes)
|
|
1357
|
+
self.yes.each_statement do |statement|
|
|
1358
|
+
result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
|
1359
|
+
end
|
|
1360
|
+
result << "#{" " * $space_count} end\n"
|
|
1361
|
+
end
|
|
1362
|
+
|
|
1363
|
+
# If noif (else if) exists, it outputs it.
|
|
1364
|
+
# Since noif is directly under, respond_to is unnecessary.
|
|
1365
|
+
self.each_noif do |condition, block|
|
|
1366
|
+
result << "#{" " * $space_count} else if (#{condition.to_verilog})\n"
|
|
1367
|
+
block.each_statement do |statement|
|
|
1368
|
+
result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
|
1369
|
+
end
|
|
1370
|
+
result << "#{" "* $space_count} end\n"
|
|
1371
|
+
end
|
|
1372
|
+
|
|
1373
|
+
# Check if there is no (else) and output no or less.
|
|
1374
|
+
if self.no.respond_to? (:mode)
|
|
1375
|
+
result << "#{" " * $space_count} else begin\n"
|
|
1376
|
+
self.no.each_statement do |statement|
|
|
1377
|
+
result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
|
1378
|
+
end
|
|
1379
|
+
result << "#{" " * $space_count} end\n"
|
|
1380
|
+
end
|
|
1381
|
+
|
|
1382
|
+
$space_count -= 1 # Since the output ends, reduce the count.
|
|
1383
|
+
return result
|
|
1384
|
+
end
|
|
1385
|
+
end
|
|
1386
|
+
|
|
1387
|
+
# Used to translate case
|
|
1388
|
+
class Case
|
|
1389
|
+
def to_verilog(mode = nil)
|
|
1390
|
+
|
|
1391
|
+
if ($space_count == 0) then
|
|
1392
|
+
result = " " * ($space_count) # Indented based on space_count.
|
|
1393
|
+
else
|
|
1394
|
+
result = ""
|
|
1395
|
+
end
|
|
1396
|
+
$space_count += 1 # Add count to be used for indentation.
|
|
1397
|
+
|
|
1398
|
+
result = ""
|
|
1399
|
+
result << "case(#{self.value.to_verilog})\n"
|
|
1400
|
+
|
|
1401
|
+
# n the case statement, each branch is partitioned by when. Process each time when.
|
|
1402
|
+
self.each_when do |whens|
|
|
1403
|
+
# Reads and stores the numbers and expressions stored in when.
|
|
1404
|
+
result << " " + " " *$space_count + "#{whens.match.to_verilog}: "
|
|
1405
|
+
if whens.statement.each_statement.count > 1 then
|
|
1406
|
+
result << "begin\n"
|
|
1407
|
+
whens.statement.each_statement do |statement|
|
|
1408
|
+
result << " "+ " " *$space_count +"#{statement.to_verilog}"
|
|
1409
|
+
end
|
|
1410
|
+
result << " " + " " *$space_count + "end\n"
|
|
1411
|
+
elsif whens.statement.each_statement.count == 1 then
|
|
1412
|
+
whens.statement.each_statement do |statement|
|
|
1413
|
+
result << "#{statement.to_verilog}"
|
|
1414
|
+
end
|
|
1415
|
+
end
|
|
1416
|
+
end
|
|
1417
|
+
# The default part is stored in default instead of when. Reads and processes in the same way as when.
|
|
1418
|
+
if self.default.each_statement.count > 1 then
|
|
1419
|
+
result << " " + " " *$space_count + "default: begin\n"
|
|
1420
|
+
self.default.each_statement do |statement|
|
|
1421
|
+
result << " " + " " *$space_count + "#{statement.to_verilog}"
|
|
1422
|
+
end
|
|
1423
|
+
result << " end\n"
|
|
1424
|
+
elsif self.default.each_statement.count == 1 then
|
|
1425
|
+
result << " " + " " *$space_count + "default: "
|
|
1426
|
+
self.default.each_statement do |statement|
|
|
1427
|
+
result << "#{statement.to_verilog}"
|
|
1428
|
+
end
|
|
1429
|
+
end
|
|
1430
|
+
result << " " + " " *$space_count + "endcase\n" # Conclusion.
|
|
1431
|
+
|
|
1432
|
+
$space_count -= 1 # Since the output ends, reduce the count.
|
|
1433
|
+
return result # Return case after translation.
|
|
1434
|
+
end
|
|
1435
|
+
end
|
|
1436
|
+
|
|
1437
|
+
# Translate expression of combination circuit.
|
|
1438
|
+
# Enhance Connection with generation of verilog code.
|
|
1439
|
+
class Connection
|
|
1440
|
+
# Converts the system to Verilog code.
|
|
1441
|
+
|
|
1442
|
+
# Method used for array.
|
|
1443
|
+
def array_connection(left,right)
|
|
1444
|
+
expression = right.each_expression.to_a
|
|
1445
|
+
result = ""
|
|
1446
|
+
expression[0..-2].each do |expression|
|
|
1447
|
+
result << " assign #{left.to_verilog}[#{expression.content.to_s}] = #{expression.to_verilog};\n"
|
|
1448
|
+
end
|
|
1449
|
+
result << " assign #{left.to_verilog}[#{expression.last.content.to_s}] = #{expression.last.to_verilog};\n"
|
|
1450
|
+
return result
|
|
1451
|
+
end
|
|
1452
|
+
|
|
1453
|
+
def to_verilog
|
|
1454
|
+
# Decide whether to assign to array by if.
|
|
1455
|
+
# NOTICE: Now array assignment is done trough constant initialization, will be treated later.
|
|
1456
|
+
# if self.right.respond_to? (:each_expression)
|
|
1457
|
+
# array_connection(self.left,self.right);
|
|
1458
|
+
# else
|
|
1459
|
+
cnt = 0 # Use count.
|
|
1460
|
+
bit = -2 # Used to determine the bit width. Since there are 0 and default, -2.
|
|
1461
|
+
|
|
1462
|
+
# Measure the number of choices on the right side (case statement if it is 3 or more).
|
|
1463
|
+
if self.right.respond_to? (:each_choice)
|
|
1464
|
+
choice = self.right.each_choice.to_a
|
|
1465
|
+
choice.each do |choice|
|
|
1466
|
+
bit += 1
|
|
1467
|
+
end
|
|
1468
|
+
end
|
|
1469
|
+
|
|
1470
|
+
# Three or more choices.
|
|
1471
|
+
if (bit > 2)
|
|
1472
|
+
# The bit width is obtained by converting the bit into a binary number and obtaining the size.
|
|
1473
|
+
bit = bit.to_s(2).size
|
|
1474
|
+
|
|
1475
|
+
# Create a case statement.
|
|
1476
|
+
result = " begin\n"
|
|
1477
|
+
result << " case(#{self.right.select.to_verilog})\n"
|
|
1478
|
+
# Output other than the last one in order.
|
|
1479
|
+
choice[0..-2].each do |choice|
|
|
1480
|
+
result << " #{bit}'#{cnt}: #{self.left.to_verilog} = #{choice.to_verilog}\n"
|
|
1481
|
+
cnt += 1
|
|
1482
|
+
end
|
|
1483
|
+
# At the end, it becomes default because it needs default.
|
|
1484
|
+
result << " default: #{self.left.to_verilog} = #{choice.last.to_verilog}\n"
|
|
1485
|
+
result << " endcase\n"
|
|
1486
|
+
result << " end\n"
|
|
1487
|
+
return result
|
|
1488
|
+
end
|
|
1489
|
+
|
|
1490
|
+
# It is not a case so call it normally.
|
|
1491
|
+
return " assign #{self.left.to_verilog} = #{self.right.to_verilog};\n"
|
|
1492
|
+
# end
|
|
1493
|
+
end
|
|
1494
|
+
end
|
|
1495
|
+
|
|
1496
|
+
# It could be used for instantiation.
|
|
1497
|
+
class RefThis
|
|
1498
|
+
def to_another_verilog
|
|
1499
|
+
return ""
|
|
1500
|
+
end
|
|
1501
|
+
end
|
|
1502
|
+
|
|
1503
|
+
# Used when using "~" for expressions.
|
|
1504
|
+
class Unary
|
|
1505
|
+
# Converts the system to Verilog code.
|
|
1506
|
+
def to_verilog
|
|
1507
|
+
return "#{self.operator}#{self.child.to_verilog}"
|
|
1508
|
+
end
|
|
1509
|
+
end
|
|
1510
|
+
|
|
1511
|
+
# For declaring variables.
|
|
1512
|
+
# Enhance SignalI with generation of verilog code.
|
|
1513
|
+
class SignalI
|
|
1514
|
+
# Converts the system to Verilog code.
|
|
1515
|
+
def to_verilog
|
|
1516
|
+
# Convert unusable characters and return them.
|
|
1517
|
+
return "#{name_to_verilog(self.name)}"
|
|
1518
|
+
end
|
|
1519
|
+
end
|
|
1520
|
+
|
|
1521
|
+
# If it is signed, it outputs signed.
|
|
1522
|
+
# Enhance Type with generation of verilog code.
|
|
1523
|
+
class Type
|
|
1524
|
+
# Converts the system to Verilog code.
|
|
1525
|
+
def to_verilog
|
|
1526
|
+
return self.name == :signed ? "#{self.name.to_s} " : ""
|
|
1527
|
+
end
|
|
1528
|
+
end
|
|
1529
|
+
|
|
1530
|
+
# Use it when collecting.
|
|
1531
|
+
class Concat
|
|
1532
|
+
def to_verilog
|
|
1533
|
+
expression = self.each_expression.to_a
|
|
1534
|
+
|
|
1535
|
+
result = "{"
|
|
1536
|
+
expression[0..-2].each do |expression|
|
|
1537
|
+
result << "#{expression.to_verilog},"
|
|
1538
|
+
end
|
|
1539
|
+
result << "#{expression.last.to_verilog}}"
|
|
1540
|
+
|
|
1541
|
+
return result
|
|
1542
|
+
end
|
|
1543
|
+
end
|
|
1544
|
+
|
|
1545
|
+
# Look at the unit of time, convert the time to ps and output it.
|
|
1546
|
+
# One of two people, TimeWait and Delay.
|
|
1547
|
+
class TimeWait
|
|
1548
|
+
def to_verilog(mode=nil)
|
|
1549
|
+
return self.delay.to_verilog
|
|
1550
|
+
end
|
|
1551
|
+
end
|
|
1552
|
+
class Delay
|
|
1553
|
+
def to_verilog
|
|
1554
|
+
time = self.value.to_s
|
|
1555
|
+
if(self.unit.to_s == "ps") then
|
|
1556
|
+
return "##{time}\n"
|
|
1557
|
+
elsif(self.unit.to_s == "ns")
|
|
1558
|
+
return "##{time}000\n"
|
|
1559
|
+
elsif(self.unit.to_s == "us")
|
|
1560
|
+
return "##{time}000000\n"
|
|
1561
|
+
elsif(self.unit.to_s == "ms")
|
|
1562
|
+
return "##{time}000000000\n"
|
|
1563
|
+
end
|
|
1564
|
+
end
|
|
1565
|
+
end
|
|
1566
|
+
|
|
1567
|
+
# Those who disappeared.
|
|
1568
|
+
#class SystemI
|
|
1569
|
+
#class TypeTuple
|
|
1570
|
+
#class Event
|
|
1571
|
+
|
|
1572
|
+
# Enhance SystemT with generation of verilog code.
|
|
1573
|
+
class SystemT
|
|
1574
|
+
|
|
1575
|
+
## Tells if an expression is a reference to port +systemI.signal+.
|
|
1576
|
+
def port_assign?(expr, systemI, signal)
|
|
1577
|
+
return expr.is_a?(RefName) && expr.name == signal.name &&
|
|
1578
|
+
expr.ref.is_a?(RefName) && expr.ref.name == systemI.name
|
|
1579
|
+
end
|
|
1580
|
+
|
|
1581
|
+
## Extracts the assignments to port +systemI.signal+ and returns
|
|
1582
|
+
# the resulting reference to a port wire.
|
|
1583
|
+
#
|
|
1584
|
+
# NOTE: assumes to_upper_space! and with_port! has been called.
|
|
1585
|
+
def extract_port_assign!(systemI,signal)
|
|
1586
|
+
# Extract the assignment.
|
|
1587
|
+
assign = nil
|
|
1588
|
+
self.each_connection.to_a.each do |connection|
|
|
1589
|
+
if self.port_assign?(connection.left,systemI,signal) then
|
|
1590
|
+
# The left is the port.
|
|
1591
|
+
# Delete the connection.
|
|
1592
|
+
self.scope.delete_connection!(connection)
|
|
1593
|
+
# And return a copy of the right.
|
|
1594
|
+
return connection.right.clone
|
|
1595
|
+
elsif self.port_assign?(connection.right,systemI,signal) then
|
|
1596
|
+
# The right is the port.
|
|
1597
|
+
# Delete the connection.
|
|
1598
|
+
self.scope.delete_connection!(connection)
|
|
1599
|
+
# And return a copy of the left.
|
|
1600
|
+
return connection.left.clone
|
|
1601
|
+
end
|
|
1602
|
+
end
|
|
1603
|
+
# No port found, nothing to do
|
|
1604
|
+
return nil
|
|
1605
|
+
end
|
|
1606
|
+
|
|
1607
|
+
|
|
1608
|
+
|
|
1609
|
+
# Converts the system to Verilog code.
|
|
1610
|
+
def to_verilog
|
|
1611
|
+
# Preprocessing
|
|
1612
|
+
# Detect the registers
|
|
1613
|
+
regs = []
|
|
1614
|
+
self.each_behavior do |behavior|
|
|
1615
|
+
behavior.block.each_statement do |statement|
|
|
1616
|
+
regs << statement.left.to_verilog if statement.is_a?(Transmit)
|
|
1617
|
+
end
|
|
1618
|
+
end
|
|
1619
|
+
|
|
1620
|
+
# Code generation
|
|
1621
|
+
inputs = 0
|
|
1622
|
+
outputs = 0
|
|
1623
|
+
inout = 0
|
|
1624
|
+
|
|
1625
|
+
inputs = self.each_input.to_a
|
|
1626
|
+
outputs = self.each_output.to_a
|
|
1627
|
+
inout = self.each_inout.to_a
|
|
1628
|
+
|
|
1629
|
+
# Spelling necessary for simulation.
|
|
1630
|
+
code = "`timescale 1ps/1ps\n\n"
|
|
1631
|
+
# Output the module name.
|
|
1632
|
+
code << "module #{name_to_verilog(self.name)}("
|
|
1633
|
+
|
|
1634
|
+
# Output the last two to the input.
|
|
1635
|
+
inputs[0..-2].each do |input|
|
|
1636
|
+
code << " #{input.to_verilog},"
|
|
1637
|
+
end
|
|
1638
|
+
# When only input is used, it is necessary to close (), so it branches with if.
|
|
1639
|
+
if outputs.empty? && inout.empty? then
|
|
1640
|
+
code << " #{inputs.last.to_verilog} ); \n" unless inputs.empty?
|
|
1641
|
+
else
|
|
1642
|
+
code << " #{inputs.last.to_verilog}," unless inputs.empty?
|
|
1643
|
+
end
|
|
1644
|
+
|
|
1645
|
+
# Output the last two to the output.
|
|
1646
|
+
outputs[0..-2].each do |output|
|
|
1647
|
+
code << " #{output.to_verilog},"
|
|
1648
|
+
end
|
|
1649
|
+
# When only input and output are used, it is necessary to close (), so it branches with if.
|
|
1650
|
+
if inout.empty? then
|
|
1651
|
+
code << " #{outputs.last.to_verilog} ); \n" unless outputs.empty?
|
|
1652
|
+
else
|
|
1653
|
+
code << " #{outputs.last.to_verilog}," unless outputs.empty?
|
|
1654
|
+
end
|
|
1655
|
+
|
|
1656
|
+
# Output the last two to the inout.
|
|
1657
|
+
inout[0..-2].each do |inout|
|
|
1658
|
+
code << " #{inout.to_verilog},"
|
|
1659
|
+
end
|
|
1660
|
+
# There is no comma as it is the last one
|
|
1661
|
+
code << " #{inout.last.to_verilog} ); \n" unless inout.empty?
|
|
1662
|
+
|
|
1663
|
+
# Declare "input"
|
|
1664
|
+
self.each_input do |input|
|
|
1665
|
+
if input.type.respond_to? (:each_type) then
|
|
1666
|
+
$vector_reg = "#{input.to_verilog}"
|
|
1667
|
+
$vector_cnt = 0
|
|
1668
|
+
input.type.each_type do |type|
|
|
1669
|
+
code << "input #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
|
|
1670
|
+
$vector_cnt += 1
|
|
1671
|
+
end
|
|
1672
|
+
else
|
|
1673
|
+
code << " input#{input.type.to_verilog} #{input.to_verilog};\n"
|
|
1674
|
+
end
|
|
1675
|
+
end
|
|
1676
|
+
|
|
1677
|
+
# Declare "output"
|
|
1678
|
+
self.each_output do |output|
|
|
1679
|
+
if output.type.respond_to? (:each_type) then
|
|
1680
|
+
$vector_reg = "#{output.to_verilog}"
|
|
1681
|
+
$vector_cnt = 0
|
|
1682
|
+
output.type.each_type do |type|
|
|
1683
|
+
if regs.include?(type.name) then
|
|
1684
|
+
code << " output reg"
|
|
1685
|
+
else
|
|
1686
|
+
code << " output"
|
|
1687
|
+
end
|
|
1688
|
+
code << "#{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
|
|
1689
|
+
$vector_cnt += 1
|
|
1690
|
+
end
|
|
1691
|
+
else
|
|
1692
|
+
if regs.include?(output.name) then
|
|
1693
|
+
code << " output reg"
|
|
1694
|
+
else
|
|
1695
|
+
code << " output"
|
|
1696
|
+
end
|
|
1697
|
+
code << "#{output.type.to_verilog} #{output.to_verilog};\n"
|
|
1698
|
+
end
|
|
1699
|
+
end
|
|
1700
|
+
|
|
1701
|
+
# Declare "inout"
|
|
1702
|
+
self.each_inout do |inout|
|
|
1703
|
+
if inout.type.respond_to? (:each_type) then
|
|
1704
|
+
$vector_reg = "#{inout.to_verilog}"
|
|
1705
|
+
$vector_cnt = 0
|
|
1706
|
+
inout.type.each_type do |type|
|
|
1707
|
+
code << "inout #{type.to_verilog} #{$vector_reg}:#{$vector_cnt};\n"
|
|
1708
|
+
$vector_cnt += 1
|
|
1709
|
+
end
|
|
1710
|
+
else
|
|
1711
|
+
code << " inout#{inout.type.to_verilog} #{inout.to_verilog};\n"
|
|
1712
|
+
end
|
|
1713
|
+
end
|
|
1714
|
+
|
|
1715
|
+
# Declare "inner".
|
|
1716
|
+
self.each_inner do |inner|
|
|
1717
|
+
if regs.include?(inner.name) then
|
|
1718
|
+
code << " reg"
|
|
1719
|
+
else
|
|
1720
|
+
code << " wire"
|
|
1721
|
+
end
|
|
1722
|
+
|
|
1723
|
+
if inner.type.base?
|
|
1724
|
+
if inner.type.base.base?
|
|
1725
|
+
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
|
1726
|
+
else
|
|
1727
|
+
code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
|
1728
|
+
end
|
|
1729
|
+
else
|
|
1730
|
+
code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
|
1731
|
+
end
|
|
1732
|
+
end
|
|
1733
|
+
|
|
1734
|
+
# If there is scope in scope, translate it.
|
|
1735
|
+
self.each_scope do |scope|
|
|
1736
|
+
scope.each_inner do |inner|
|
|
1737
|
+
if regs.include?(inner.name) then
|
|
1738
|
+
code << " reg "
|
|
1739
|
+
else
|
|
1740
|
+
code << " wire "
|
|
1741
|
+
end
|
|
1742
|
+
|
|
1743
|
+
if inner.type.respond_to? (:base)
|
|
1744
|
+
if inner.type.base.base?
|
|
1745
|
+
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
|
1746
|
+
else
|
|
1747
|
+
code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
|
1748
|
+
end
|
|
1749
|
+
else
|
|
1750
|
+
code << "inner #{inner.type.to_verilog} #{inner.to_verilog};\n"
|
|
1751
|
+
end
|
|
1752
|
+
end
|
|
1753
|
+
|
|
1754
|
+
scope.each_connection do |connection|
|
|
1755
|
+
code << "\n"
|
|
1756
|
+
code << "#{connection.to_verilog}"
|
|
1757
|
+
end
|
|
1758
|
+
end
|
|
1759
|
+
|
|
1760
|
+
code << "\n"
|
|
1761
|
+
|
|
1762
|
+
# transliation of the instantiation part.
|
|
1763
|
+
# Generate the instances connections.
|
|
1764
|
+
self.each_systemI do |systemI|
|
|
1765
|
+
# Its Declaration.
|
|
1766
|
+
code << " " * 3
|
|
1767
|
+
systemT = systemI.systemT
|
|
1768
|
+
code << name_to_verilog(systemT.name) << " "
|
|
1769
|
+
code << name_to_verilog(systemI.name) << "("
|
|
1770
|
+
# Its ports connections
|
|
1771
|
+
# Inputs
|
|
1772
|
+
systemT.each_input do |input|
|
|
1773
|
+
ref = self.extract_port_assign!(systemI,input)
|
|
1774
|
+
if ref then
|
|
1775
|
+
code << "." << name_to_verilog(input.name) << "("
|
|
1776
|
+
code << ref.to_verilog
|
|
1777
|
+
code << "),"
|
|
1778
|
+
end
|
|
1779
|
+
end
|
|
1780
|
+
# Outputs
|
|
1781
|
+
systemT.each_output do |output|
|
|
1782
|
+
ref = self.extract_port_assign!(systemI,output)
|
|
1783
|
+
if ref then
|
|
1784
|
+
code << "." << name_to_verilog(output.name) << "("
|
|
1785
|
+
code << ref.to_verilog
|
|
1786
|
+
code << "),"
|
|
1787
|
+
end
|
|
1788
|
+
end
|
|
1789
|
+
# Inouts
|
|
1790
|
+
systemT.each_inout do |inout|
|
|
1791
|
+
ref = self.extract_port_assign!(systemI,inout)
|
|
1792
|
+
if ref then
|
|
1793
|
+
code << "." << name_to_verilog(inout.name) << "("
|
|
1794
|
+
code << ref.to_vhdl(level)
|
|
1795
|
+
code << "),"
|
|
1796
|
+
end
|
|
1797
|
+
end
|
|
1798
|
+
# Remove the last "," for conforming with Verilog syntax.
|
|
1799
|
+
# and close the port connection.
|
|
1800
|
+
code[-1] = ");\n"
|
|
1801
|
+
end
|
|
1802
|
+
|
|
1803
|
+
|
|
1804
|
+
|
|
1805
|
+
# translation of the connection part (assigen).
|
|
1806
|
+
self.each_connection do |connection|
|
|
1807
|
+
code << "#{connection.to_verilog}\n"
|
|
1808
|
+
end
|
|
1809
|
+
|
|
1810
|
+
# Translation of behavior part (always).
|
|
1811
|
+
self.each_behavior do |behavior|
|
|
1812
|
+
code << " always @( "
|
|
1813
|
+
# If there is no "always" condition, it is always @("*").
|
|
1814
|
+
if behavior.each_event.to_a.empty? then
|
|
1815
|
+
code << "*"
|
|
1816
|
+
else
|
|
1817
|
+
event = behavior.each_event.to_a
|
|
1818
|
+
event[0..-2].each do |event|
|
|
1819
|
+
# If "posedge" or "negedge" does not exist, the variable is set to condition.
|
|
1820
|
+
if (event.type.to_s != "posedge" && event.type.to_s != "negedge") then
|
|
1821
|
+
code << "#{event.ref.to_verilog}, "
|
|
1822
|
+
else
|
|
1823
|
+
# Otherwise, it outputs "psoedge" or "negedge" as a condition.
|
|
1824
|
+
code << "#{event.type.to_s} #{event.ref.to_verilog}, "
|
|
1825
|
+
end
|
|
1826
|
+
end
|
|
1827
|
+
# Since no comma is necessary at the end, we try not to separate commas separately at the end.
|
|
1828
|
+
if (event.last.type.to_s != "posedge" && event.last.type.to_s != "negedge") then
|
|
1829
|
+
code << "#{event.last.ref.to_verilog}"
|
|
1830
|
+
else
|
|
1831
|
+
code << "#{event.last.type.to_s} #{event.last.ref.to_verilog}"
|
|
1832
|
+
end
|
|
1833
|
+
end
|
|
1834
|
+
code << " ) begin\n"
|
|
1835
|
+
|
|
1836
|
+
# Perform "scheduling" using the method "flatten".
|
|
1837
|
+
block = behavior.block.flatten(behavior.block.mode.to_s)
|
|
1838
|
+
|
|
1839
|
+
# Declaration of "inner" part within "always".
|
|
1840
|
+
block.each_inner do |inner|
|
|
1841
|
+
if regs.include?(inner.name) then
|
|
1842
|
+
code << " reg"
|
|
1843
|
+
else
|
|
1844
|
+
code << " wire"
|
|
1845
|
+
end
|
|
1846
|
+
|
|
1847
|
+
# Variable has "base", but if there is width etc, it is not in "base".
|
|
1848
|
+
# It is determined by an if.
|
|
1849
|
+
if inner.type.base?
|
|
1850
|
+
if inner.type.base.base?
|
|
1851
|
+
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
|
1852
|
+
else
|
|
1853
|
+
code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
|
1854
|
+
end
|
|
1855
|
+
else
|
|
1856
|
+
code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
|
1857
|
+
end
|
|
1858
|
+
end
|
|
1859
|
+
|
|
1860
|
+
# Translate the block that finished scheduling.
|
|
1861
|
+
block.each_statement do |statement|
|
|
1862
|
+
code << "\n #{statement.to_verilog(behavior.block.mode.to_s)}"
|
|
1863
|
+
end
|
|
1864
|
+
|
|
1865
|
+
$fm.fm_par.clear()
|
|
1866
|
+
|
|
1867
|
+
code << "\n end\n\n"
|
|
1868
|
+
end
|
|
1869
|
+
|
|
1870
|
+
# Conclusion.
|
|
1871
|
+
code << "endmodule"
|
|
1872
|
+
return code
|
|
1873
|
+
end
|
|
1874
|
+
end
|
|
1875
|
+
|
|
1876
|
+
end
|
|
1877
|
+
|
|
1878
|
+
|
|
1879
|
+
|
|
1880
|
+
## Extends the Numeric class with generation of verilog text.
|
|
1881
|
+
class ::Numeric
|
|
1882
|
+
|
|
1883
|
+
# Generates the text of the equivalent verilog code.
|
|
1884
|
+
# +level+ is the hierachical level of the object.
|
|
1885
|
+
def to_verilog(level = 0)
|
|
1886
|
+
return self.to_s
|
|
1887
|
+
end
|
|
1888
|
+
end
|