HDLRuby 2.4.26 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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/dff_properties.rb +19 -0
- data/lib/HDLRuby/hdr_samples/dff_unit.rb +54 -0
- data/lib/HDLRuby/hdr_samples/seqpar_bench.rb +59 -0
- data/lib/HDLRuby/hdrcc.rb +104 -22
- data/lib/HDLRuby/hruby_decorator.rb +248 -0
- data/lib/HDLRuby/hruby_high.rb +256 -67
- data/lib/HDLRuby/hruby_low.rb +511 -0
- data/lib/HDLRuby/hruby_low2c.rb +67 -0
- data/lib/HDLRuby/hruby_low_without_parinseq.rb +151 -0
- data/lib/HDLRuby/hruby_unit.rb +43 -0
- data/lib/HDLRuby/hruby_verilog.rb +260 -130
- data/lib/HDLRuby/std/linear.rb +5 -11
- data/lib/HDLRuby/template_expander.rb +61 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +11 -2
data/lib/HDLRuby/hruby_low2c.rb
CHANGED
@@ -178,6 +178,7 @@ module HDLRuby::Low
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
self.scope.each_block_deep do |block|
|
181
|
+
# puts "treating for block=#{Low2C.obj_name(block)} with=#{block.each_inner.count} inners"
|
181
182
|
block.each_inner do |signal|
|
182
183
|
# res << signal.value.to_c_make(level) if signal.value
|
183
184
|
signal.value.each_node_deep do |node|
|
@@ -837,6 +838,7 @@ module HDLRuby::Low
|
|
837
838
|
## Generates the content of the h file.
|
838
839
|
def to_ch
|
839
840
|
res = ""
|
841
|
+
# puts "to_ch for SignalI: #{self.to_c_signal()}"
|
840
842
|
# Declare the global variable holding the signal.
|
841
843
|
res << "extern SignalI #{self.to_c_signal()};\n\n"
|
842
844
|
|
@@ -1050,6 +1052,12 @@ module HDLRuby::Low
|
|
1050
1052
|
raise AnyError, "Internal error: to_c should be implemented in class :#{self.class}"
|
1051
1053
|
end
|
1052
1054
|
|
1055
|
+
## Generates the content of the h file.
|
1056
|
+
def to_ch
|
1057
|
+
# By default nothing to generate.
|
1058
|
+
return ""
|
1059
|
+
end
|
1060
|
+
|
1053
1061
|
# Adds the c code of the blocks to +res+ at +level+
|
1054
1062
|
def add_blocks_code(res,level)
|
1055
1063
|
if self.respond_to?(:each_node) then
|
@@ -1060,6 +1068,17 @@ module HDLRuby::Low
|
|
1060
1068
|
end
|
1061
1069
|
end
|
1062
1070
|
end
|
1071
|
+
|
1072
|
+
# Adds the creation of the blocks to +res+ at +level+.
|
1073
|
+
def add_make_block(res,level)
|
1074
|
+
if self.respond_to?(:each_node) then
|
1075
|
+
self.each_node do |node|
|
1076
|
+
if node.respond_to?(:add_blocks_code) then
|
1077
|
+
node.add_make_block(res,level)
|
1078
|
+
end
|
1079
|
+
end
|
1080
|
+
end
|
1081
|
+
end
|
1063
1082
|
end
|
1064
1083
|
|
1065
1084
|
## Extends the Transmit class with generation of HDLRuby::High text.
|
@@ -1143,6 +1162,18 @@ module HDLRuby::Low
|
|
1143
1162
|
# Return the result.
|
1144
1163
|
return res
|
1145
1164
|
end
|
1165
|
+
|
1166
|
+
## Generates the content of the h file.
|
1167
|
+
def to_ch
|
1168
|
+
res = ""
|
1169
|
+
# Recurse on the sub statements.
|
1170
|
+
res << self.yes.to_ch
|
1171
|
+
self.each_noif do |cond,stmnt|
|
1172
|
+
res << stmnt.to_ch
|
1173
|
+
end
|
1174
|
+
res << self.no.to_ch if self.no
|
1175
|
+
return res
|
1176
|
+
end
|
1146
1177
|
end
|
1147
1178
|
|
1148
1179
|
## Extends the When class with generation of HDLRuby::High text.
|
@@ -1164,10 +1195,20 @@ module HDLRuby::Low
|
|
1164
1195
|
return res
|
1165
1196
|
end
|
1166
1197
|
|
1198
|
+
## Generates the content of the h file.
|
1199
|
+
def to_ch
|
1200
|
+
return self.statement.to_ch
|
1201
|
+
end
|
1202
|
+
|
1167
1203
|
# Adds the c code of the blocks to +res+ at +level+
|
1168
1204
|
def add_blocks_code(res,level)
|
1169
1205
|
self.statement.add_blocks_code(res,level)
|
1170
1206
|
end
|
1207
|
+
|
1208
|
+
# Adds the creation of the blocks to +res+ at +level+.
|
1209
|
+
def add_make_block(res,level)
|
1210
|
+
self.statement.add_make_block(res,level)
|
1211
|
+
end
|
1171
1212
|
end
|
1172
1213
|
|
1173
1214
|
## Extends the Case class with generation of HDLRuby::High text.
|
@@ -1215,6 +1256,16 @@ module HDLRuby::Low
|
|
1215
1256
|
# Return the resulting string.
|
1216
1257
|
return res
|
1217
1258
|
end
|
1259
|
+
|
1260
|
+
## Generates the content of the h file.
|
1261
|
+
def to_ch
|
1262
|
+
res = ""
|
1263
|
+
# Recurse on the whens.
|
1264
|
+
self.each_when {|w| res << w.to_ch }
|
1265
|
+
# Recurse on the default statement.
|
1266
|
+
res << self.default.to_ch if self.default
|
1267
|
+
return res
|
1268
|
+
end
|
1218
1269
|
end
|
1219
1270
|
|
1220
1271
|
|
@@ -1272,6 +1323,12 @@ module HDLRuby::Low
|
|
1272
1323
|
res << self.to_c_code(level)
|
1273
1324
|
end
|
1274
1325
|
|
1326
|
+
# Adds the creation of the blocks to +res+ at +level+.
|
1327
|
+
def add_make_block(res,level)
|
1328
|
+
res << " " * level*3
|
1329
|
+
res << "#{Low2C.make_name(self)}();\n"
|
1330
|
+
end
|
1331
|
+
|
1275
1332
|
# Generates the C text of the equivalent HDLRuby::High code.
|
1276
1333
|
# +level+ is the hierachical level of the object.
|
1277
1334
|
def to_c_code(level = 0)
|
@@ -1351,6 +1408,11 @@ module HDLRuby::Low
|
|
1351
1408
|
res << " " * (level+1)*3
|
1352
1409
|
res << "block->function = &#{Low2C.code_name(self)};\n"
|
1353
1410
|
|
1411
|
+
# Generate creation of the sub blocks.
|
1412
|
+
self.each_statement do |stmnt|
|
1413
|
+
stmnt.add_make_block(res,level+1)
|
1414
|
+
end
|
1415
|
+
|
1354
1416
|
# Generate the Returns of the result.
|
1355
1417
|
res << "\n"
|
1356
1418
|
res << " " * (level+1)*3
|
@@ -1373,6 +1435,7 @@ module HDLRuby::Low
|
|
1373
1435
|
|
1374
1436
|
## Generates the content of the h file.
|
1375
1437
|
def to_ch
|
1438
|
+
# puts "to_ch for block=#{Low2C.obj_name(self)} with=#{self.each_inner.count} inners"
|
1376
1439
|
res = ""
|
1377
1440
|
# Declare the global variable holding the block.
|
1378
1441
|
res << "extern Block #{Low2C.obj_name(self)};\n\n"
|
@@ -1383,6 +1446,10 @@ module HDLRuby::Low
|
|
1383
1446
|
# Generate the accesses to the ports.
|
1384
1447
|
self.each_inner { |inner| res << inner.to_ch }
|
1385
1448
|
|
1449
|
+
# Recurse on the statements.
|
1450
|
+
self.each_statement { |stmnt| res << stmnt.to_ch }
|
1451
|
+
|
1452
|
+
|
1386
1453
|
return res
|
1387
1454
|
end
|
1388
1455
|
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'HDLRuby'
|
2
|
+
require 'HDLRuby/hruby_tools'
|
3
|
+
require 'HDLRuby/hruby_low_mutable'
|
4
|
+
|
5
|
+
|
6
|
+
module HDLRuby::Low
|
7
|
+
|
8
|
+
|
9
|
+
##
|
10
|
+
# Converts par blocks within seq blocks to seq blocks.
|
11
|
+
# For matching the executing model of Verilog.
|
12
|
+
#
|
13
|
+
########################################################################
|
14
|
+
|
15
|
+
|
16
|
+
## Extends the SystemT class with functionality for converting par blocks
|
17
|
+
# within seq blocks to seq blocks.
|
18
|
+
class SystemT
|
19
|
+
|
20
|
+
# Converts par blocks within seq blocks to seq blocks.
|
21
|
+
def par_in_seq2seq!
|
22
|
+
self.scope.par_in_seq2seq!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
## Extends the Scope class with functionality for breaking assingments
|
27
|
+
# to concats.
|
28
|
+
class Scope
|
29
|
+
# Converts par blocks within seq blocks to seq blocks.
|
30
|
+
def par_in_seq2seq!
|
31
|
+
# Recruse on the sub scopes.
|
32
|
+
self.each_scope(&:par_in_seq2seq!)
|
33
|
+
# Recurse on the block.
|
34
|
+
self.each_behavior do |behavior|
|
35
|
+
behavior.block.par_in_seq2seq!
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
## Extends the Statement class with functionality for breaking assingments
|
42
|
+
# to concats.
|
43
|
+
class Statement
|
44
|
+
# Converts par blocks within seq blocks to seq blocks.
|
45
|
+
def par_in_seq2seq!
|
46
|
+
# By default nothing to do.
|
47
|
+
return self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Convert the block to seq.
|
51
|
+
def to_seq!
|
52
|
+
# By default nothing to do.
|
53
|
+
return self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
## Extends the If class with functionality for breaking assingments
|
59
|
+
# to concats.
|
60
|
+
class If
|
61
|
+
# Converts par blocks within seq blocks to seq blocks.
|
62
|
+
def par_in_seq2seq!
|
63
|
+
self.yes.par_in_seq2seq!
|
64
|
+
self.each_noif do |cond,blk|
|
65
|
+
blk.par_in_seq2seq!
|
66
|
+
end
|
67
|
+
self.no.par_in_seq2seq! if self.no
|
68
|
+
end
|
69
|
+
|
70
|
+
# Convert the block to seq.
|
71
|
+
def to_seq!
|
72
|
+
self.to_seq!
|
73
|
+
self.each_noif do |cond,blk|
|
74
|
+
blk.to_seq!
|
75
|
+
end
|
76
|
+
self.no.to_seq! if self.no
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
## Extends the Case class with functionality for breaking assingments
|
82
|
+
# to concats.
|
83
|
+
class Case
|
84
|
+
# Converts par blocks within seq blocks to seq blocks.
|
85
|
+
def par_in_seq2seq!
|
86
|
+
self.each_when do |w|
|
87
|
+
w.statement.par_in_seq2seq!
|
88
|
+
end
|
89
|
+
self.default.par_in_seq2seq! if self.default
|
90
|
+
end
|
91
|
+
|
92
|
+
# Convert the block to seq.
|
93
|
+
def to_seq!
|
94
|
+
self.each_when do |w|
|
95
|
+
w.statement.to_seq!
|
96
|
+
end
|
97
|
+
self.default.to_seq! if self.default
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
## Extends the Block class with functionality for breaking assingments
|
103
|
+
# to concats.
|
104
|
+
class Block
|
105
|
+
# Converts par blocks within seq blocks to seq blocks.
|
106
|
+
def par_in_seq2seq!
|
107
|
+
# Recurse on the sub blocks.
|
108
|
+
self.each_statement(&:par_in_seq2seq!)
|
109
|
+
# Is the current block a seq block?
|
110
|
+
if self.mode == :seq then
|
111
|
+
# Yes, convert its inner par blocks to seq blocks.
|
112
|
+
self.each_statement do |statement|
|
113
|
+
if (statement.is_a?(Block)) then
|
114
|
+
statement.to_seq! if statement.mode == :par
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
return self
|
119
|
+
end
|
120
|
+
|
121
|
+
# Convert the block to seq.
|
122
|
+
def to_seq!
|
123
|
+
if self.mode == :par then
|
124
|
+
# Need to convert.
|
125
|
+
# First recurse on the sub blocks.
|
126
|
+
self.each_statement(&:to_seq!)
|
127
|
+
# Now replace each left value by a new signal for
|
128
|
+
# differed assingment in seq.
|
129
|
+
differeds = []
|
130
|
+
self.each_statement do |statement|
|
131
|
+
left = statement.left
|
132
|
+
if statement.is_a?(Transmit) then
|
133
|
+
sig = SignalI.new(HDLRuby.uniq_name,left.type)
|
134
|
+
self.add_inner(sig)
|
135
|
+
diff = RefName.new(left.type,RefThis.new,sig.name)
|
136
|
+
differeds << [left,diff]
|
137
|
+
statement.set_left!(diff)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
# Adds the differed assignments.
|
141
|
+
differeds.each do |left,diff|
|
142
|
+
self.add_statement(Transmit.new(left.clone,diff.clone))
|
143
|
+
end
|
144
|
+
# Change the mode.
|
145
|
+
self.set_mode!(:seq)
|
146
|
+
end
|
147
|
+
return self
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "HDLRuby/hruby_high"
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
##
|
6
|
+
# Library for building unit test systems.
|
7
|
+
#
|
8
|
+
########################################################################
|
9
|
+
module HDLRuby::Unit
|
10
|
+
|
11
|
+
## The HDLRuby unit test error class.
|
12
|
+
class UnitError < ::StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
# The set of the unit systems by name.
|
16
|
+
@@unit_systems = {}
|
17
|
+
|
18
|
+
# Declares system +name+ for unit testing.
|
19
|
+
# The system is built by executing +ruby_block+.
|
20
|
+
#
|
21
|
+
# NOTE: the name of the system is not registered within the HDLRuby
|
22
|
+
# namespace since it is not meant to be used directly.
|
23
|
+
def self.system(name,&ruby_block)
|
24
|
+
# Ensure name is a symbol.
|
25
|
+
name = name.to_s.to_sym
|
26
|
+
# Check if the name is already used or not.
|
27
|
+
if @@unit_systems.key?(name) then
|
28
|
+
raise UnitError, "Unit test system #{name} already declared."
|
29
|
+
end
|
30
|
+
@@unit_systems[name] = HDLRuby::High.system(&ruby_block)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# Create a system named +test_name+ executing all the unit tests.
|
35
|
+
def self.test(test_name = "test")
|
36
|
+
# Declare the system.
|
37
|
+
HDLRuby::High.system test_name do
|
38
|
+
@@unit_systems.each do |name,sys|
|
39
|
+
sys.instantiate(name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -14,6 +14,9 @@ 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
|
+
|
17
20
|
|
18
21
|
# Sample of very handy for programming.
|
19
22
|
# puts "class=#{self.yes.class}" # Confirm class of self.yes.
|
@@ -25,7 +28,7 @@ module HDLRuby::Low
|
|
25
28
|
# end
|
26
29
|
|
27
30
|
# Global variable used for indentation and structure (temporary).
|
28
|
-
$space_count = 0 # Count used for increasing indent by if statement. (temporary)
|
31
|
+
# $space_count = 0 # Count used for increasing indent by if statement. (temporary)
|
29
32
|
$vector_reg = "" # For storing signal type at structure declaration. (temporary)
|
30
33
|
$vector_cnt = 0 # For allocating numbers at structure declaration. (temporary)
|
31
34
|
|
@@ -101,9 +104,11 @@ end
|
|
101
104
|
# Enhance Transmit with generation of verilog code.
|
102
105
|
class Transmit
|
103
106
|
# Converts the system to Verilog code.
|
104
|
-
def to_verilog(mode = nil)
|
107
|
+
# def to_verilog(mode = nil)
|
108
|
+
def to_verilog(spc = 3)
|
105
109
|
# Determine blocking assignment or nonblocking substitution from mode and return it.
|
106
|
-
code = "#{self.left.to_verilog} #{mode == "seq" ? "=" : "<="} #{self.right.to_verilog};\n"
|
110
|
+
# code = "#{self.left.to_verilog} #{mode == "seq" ? "=" : "<="} #{self.right.to_verilog};\n"
|
111
|
+
code = "#{" " * spc}#{self.left.to_verilog} #{self.block.mode == :seq ? "=" : "<="} #{self.right.to_verilog};"
|
107
112
|
return code
|
108
113
|
end
|
109
114
|
end
|
@@ -111,12 +116,73 @@ end
|
|
111
116
|
# To scheduling to the Block.
|
112
117
|
# Enhance Block with generation of verilog code.
|
113
118
|
class Block
|
114
|
-
# Converts the system to Verilog code.
|
115
|
-
def to_verilog(mode = nil)
|
116
|
-
|
117
|
-
|
119
|
+
# # Converts the system to Verilog code.
|
120
|
+
# def to_verilog(mode = nil)
|
121
|
+
# # No translation is done in this class.
|
122
|
+
# puts "Block to_verilog not found" # For debugging
|
123
|
+
# end
|
124
|
+
|
125
|
+
# Converts the system to Verilog code adding 'spc' spaces at the begining
|
126
|
+
# of each line.
|
127
|
+
def to_verilog(spc = 3)
|
128
|
+
code = "begin"
|
129
|
+
# code << " : #{name_to_verilog(self.name)}" if self.name && !self.name.empty?
|
130
|
+
if self.name && !self.name.empty? then
|
131
|
+
vname = name_to_verilog(self.name)
|
132
|
+
code << " : #{vname}"
|
133
|
+
self.properties[:verilog_name] = vname
|
134
|
+
end
|
135
|
+
code << "\n" if block.each_inner.any?
|
136
|
+
# Declaration of "inner" part within "always".
|
137
|
+
block.each_inner do |inner|
|
138
|
+
# if regs.include?(inner.name) then
|
139
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
140
|
+
# code << " reg"
|
141
|
+
code << "#{" " * (spc+3)}reg"
|
142
|
+
else
|
143
|
+
code << "#{" " * (spc+3)}wire"
|
144
|
+
end
|
145
|
+
|
146
|
+
# Variable has "base", but if there is width etc, it is not in "base".
|
147
|
+
# It is determined by an if.
|
148
|
+
if inner.type.base?
|
149
|
+
if inner.type.base.base?
|
150
|
+
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
151
|
+
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
152
|
+
else
|
153
|
+
# code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
154
|
+
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
155
|
+
end
|
156
|
+
else
|
157
|
+
# code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
158
|
+
code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
159
|
+
end
|
160
|
+
if inner.value then
|
161
|
+
# There is an initial value.
|
162
|
+
code << " = #{inner.value.to_verilog}"
|
163
|
+
end
|
164
|
+
code << ";\n"
|
165
|
+
end
|
166
|
+
|
167
|
+
# Translate the block that finished scheduling.
|
168
|
+
block.each_statement do |statement|
|
169
|
+
#code << "\n #{statement.to_verilog(behavior.block.mode.to_s)}"
|
170
|
+
# code << "\n#{" "*spc}#{statement.to_verilog(behavior.block.mode.to_s)}"
|
171
|
+
if statement.is_a?(Block) then
|
172
|
+
code << "\n#{" " * (spc+3)}#{statement.to_verilog(spc+3)}"
|
173
|
+
else
|
174
|
+
code << "\n#{statement.to_verilog(spc+3)}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
# Close the block."
|
178
|
+
code << "\n#{" "*spc}end"
|
179
|
+
return code
|
118
180
|
end
|
119
181
|
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
|
120
186
|
# Extract and convert to verilog the TimeRepeat statements.
|
121
187
|
# NOTE: work only on the current level of the block (should be called
|
122
188
|
# through each_block_deep).
|
@@ -136,7 +202,7 @@ class Block
|
|
136
202
|
# Declaration of "inner" part within "always".
|
137
203
|
block.each_inner do |inner|
|
138
204
|
# if regs.include?(inner.name) then
|
139
|
-
if
|
205
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
140
206
|
code << " reg"
|
141
207
|
else
|
142
208
|
code << " wire"
|
@@ -1323,8 +1389,10 @@ end
|
|
1323
1389
|
class RefName
|
1324
1390
|
# Converts the system to Verilog code using +renamer+ for producing Verilog-compatible names.
|
1325
1391
|
def to_verilog
|
1326
|
-
# return "#{self.name
|
1327
|
-
|
1392
|
+
# return "#{name_to_verilog(self.name)}"
|
1393
|
+
vname = name_to_verilog(self.name)
|
1394
|
+
self.properties[:verilog_name] = vname
|
1395
|
+
return "#{vname}"
|
1328
1396
|
end
|
1329
1397
|
|
1330
1398
|
# Used for instantiation (emergency procedure).
|
@@ -1431,66 +1499,82 @@ class Value
|
|
1431
1499
|
end
|
1432
1500
|
end
|
1433
1501
|
|
1502
|
+
|
1434
1503
|
# Used to transrate if.
|
1435
1504
|
# Enhance If with generation of verilog code.
|
1436
1505
|
class If
|
1437
|
-
# Converts the system to Verilog code.
|
1438
|
-
def to_verilog(mode = nil)
|
1506
|
+
# # Converts the system to Verilog code.
|
1507
|
+
# def to_verilog(mode = nil)
|
1508
|
+
# Converts to Verilog code, checking adding 'spc' spaces at the begining
|
1509
|
+
# of each line.
|
1510
|
+
def to_verilog(spc = 3)
|
1439
1511
|
|
1440
1512
|
$blocking = false
|
1441
1513
|
|
1442
|
-
if ($space_count == 0) then
|
1443
|
-
|
1444
|
-
else
|
1445
|
-
|
1446
|
-
end
|
1447
|
-
$space_count += 1 # Add count to be used for indentation.
|
1514
|
+
# if ($space_count == 0) then
|
1515
|
+
# result = " " * ($space_count) # Indented based on space_count.
|
1516
|
+
# else
|
1517
|
+
# result = ""
|
1518
|
+
# end
|
1519
|
+
# $space_count += 1 # Add count to be used for indentation.
|
1520
|
+
result = " " * spc # Indented based on space_count.
|
1448
1521
|
|
1449
|
-
result << "if (#{self.condition.to_verilog}) begin\n"
|
1522
|
+
# result << "if (#{self.condition.to_verilog}) begin\n"
|
1523
|
+
result << "if (#{self.condition.to_verilog}) "
|
1450
1524
|
|
1451
1525
|
|
1452
1526
|
# Check if there is yes (if) and output yes or less.
|
1453
1527
|
if self.respond_to? (:yes)
|
1454
|
-
self.yes.each_statement do |statement|
|
1455
|
-
|
1456
|
-
end
|
1457
|
-
result << "#{" " * $space_count} end\n"
|
1528
|
+
# self.yes.each_statement do |statement|
|
1529
|
+
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1530
|
+
# end
|
1531
|
+
# result << "#{" " * $space_count} end\n"
|
1532
|
+
result << self.yes.to_verilog(spc)
|
1458
1533
|
end
|
1459
1534
|
|
1460
1535
|
# If noif (else if) exists, it outputs it.
|
1461
1536
|
# Since noif is directly under, respond_to is unnecessary.
|
1462
1537
|
self.each_noif do |condition, block|
|
1463
|
-
result << "#{" " * $space_count} else if (#{condition.to_verilog}) begin\n"
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1538
|
+
# result << "#{" " * $space_count} else if (#{condition.to_verilog}) begin\n"
|
1539
|
+
result << "\n#{" "*spc}else if (#{condition.to_verilog}) "
|
1540
|
+
# block.each_statement do |statement|
|
1541
|
+
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1542
|
+
# end
|
1543
|
+
# result << "#{" "* $space_count} end\n"
|
1544
|
+
result << block.to_verilog(spc)
|
1468
1545
|
end
|
1469
1546
|
|
1470
1547
|
# Check if there is no (else) and output no or less.
|
1471
|
-
if self.no.respond_to?
|
1472
|
-
result << "#{" " * $space_count} else begin\n"
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1548
|
+
if self.no.respond_to?(:mode)
|
1549
|
+
# result << "#{" " * $space_count} else begin\n"
|
1550
|
+
result << "\n#{" " * spc}else "
|
1551
|
+
# self.no.each_statement do |statement|
|
1552
|
+
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1553
|
+
# end
|
1554
|
+
# result << "#{" " * $space_count} end\n"
|
1555
|
+
result << self.no.to_verilog(spc)
|
1477
1556
|
end
|
1478
1557
|
|
1479
|
-
$space_count -= 1 # Since the output ends, reduce the count.
|
1558
|
+
# $space_count -= 1 # Since the output ends, reduce the count.
|
1480
1559
|
return result
|
1481
1560
|
end
|
1482
1561
|
end
|
1483
1562
|
|
1484
1563
|
# Used to translate case
|
1485
1564
|
class Case
|
1486
|
-
def to_verilog(mode = nil)
|
1565
|
+
# def to_verilog(mode = nil)
|
1566
|
+
#
|
1567
|
+
# Converts to Verilog code, checking if variables are register
|
1568
|
+
# or wire adding 'spc' spaces at the begining of each line.
|
1569
|
+
def to_verilog(spc = 3)
|
1487
1570
|
|
1488
|
-
if ($space_count == 0) then
|
1489
|
-
|
1490
|
-
else
|
1491
|
-
|
1492
|
-
end
|
1493
|
-
$space_count += 1 # Add count to be used for indentation.
|
1571
|
+
# if ($space_count == 0) then
|
1572
|
+
# result = " " * ($space_count) # Indented based on space_count.
|
1573
|
+
# else
|
1574
|
+
# result = ""
|
1575
|
+
# end
|
1576
|
+
# $space_count += 1 # Add count to be used for indentation.
|
1577
|
+
result = " " * spc # Indented based on space_count.
|
1494
1578
|
|
1495
1579
|
result = ""
|
1496
1580
|
result << "case(#{self.value.to_verilog})\n"
|
@@ -1498,40 +1582,55 @@ class Case
|
|
1498
1582
|
# n the case statement, each branch is partitioned by when. Process each time when.
|
1499
1583
|
self.each_when do |whens|
|
1500
1584
|
# Reads and stores the numbers and expressions stored in when.
|
1501
|
-
result << " " + " " *$space_count + "#{whens.match.to_verilog}: "
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1585
|
+
# result << " " + " " *$space_count + "#{whens.match.to_verilog}: "
|
1586
|
+
result << " " * (spc+3) + "#{whens.match.to_verilog}: "
|
1587
|
+
|
1588
|
+
# if whens.statement.each_statement.count > 1 then
|
1589
|
+
# result << "begin\n"
|
1590
|
+
# whens.statement.each_statement do |statement|
|
1591
|
+
# result << " "+ " " *$space_count +"#{statement.to_verilog}"
|
1592
|
+
# end
|
1593
|
+
# result << " " + " " *$space_count + "end\n"
|
1594
|
+
# elsif whens.statement.each_statement.count == 1 then
|
1595
|
+
# whens.statement.each_statement do |statement|
|
1596
|
+
# result << "#{statement.to_verilog}"
|
1597
|
+
# end
|
1598
|
+
# else
|
1599
|
+
# # Empty statement case.
|
1600
|
+
# result << "\n"
|
1601
|
+
# end
|
1602
|
+
if whens.statement.each_statement.count >= 1 then
|
1603
|
+
result << whens.statement.to_verilog(spc+3)
|
1512
1604
|
else
|
1513
|
-
# Empty statement case.
|
1514
1605
|
result << "\n"
|
1515
1606
|
end
|
1516
1607
|
end
|
1517
|
-
# The default part is stored in default instead of when. Reads and processes in the same way as when.
|
1608
|
+
# # The default part is stored in default instead of when. Reads and processes in the same way as when.
|
1609
|
+
# if self.default then
|
1610
|
+
# if self.default.each_statement.count > 1 then
|
1611
|
+
# result << " " + " " *$space_count + "default: begin\n"
|
1612
|
+
# self.default.each_statement do |statement|
|
1613
|
+
# result << " " + " " *$space_count + "#{statement.to_verilog}"
|
1614
|
+
# end
|
1615
|
+
# result << " end\n"
|
1616
|
+
# elsif self.default.each_statement.count == 1 then
|
1617
|
+
# result << " " + " " *$space_count + "default: "
|
1618
|
+
# self.default.each_statement do |statement|
|
1619
|
+
# result << "#{statement.to_verilog}"
|
1620
|
+
# end
|
1621
|
+
# end
|
1622
|
+
# end
|
1518
1623
|
if self.default then
|
1519
|
-
if self.default.each_statement.count
|
1520
|
-
result <<
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
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}"
|
1529
|
-
end
|
1530
|
-
end
|
1624
|
+
if self.default.each_statement.count >= 1 then
|
1625
|
+
result << self.default.each_statement.to_verilog(spc+3)
|
1626
|
+
else
|
1627
|
+
result << "\n"
|
1628
|
+
end
|
1531
1629
|
end
|
1532
|
-
result << " " + " " *$space_count + "endcase\n" # Conclusion.
|
1630
|
+
# result << " " + " " *$space_count + "endcase\n" # Conclusion.
|
1631
|
+
result << " " * spc + "endcase\n" # Conclusion.
|
1533
1632
|
|
1534
|
-
$space_count -= 1 # Since the output ends, reduce the count.
|
1633
|
+
# $space_count -= 1 # Since the output ends, reduce the count.
|
1535
1634
|
return result # Return case after translation.
|
1536
1635
|
end
|
1537
1636
|
end
|
@@ -1658,7 +1757,10 @@ class SignalI
|
|
1658
1757
|
# Converts the system to Verilog code.
|
1659
1758
|
def to_verilog
|
1660
1759
|
# Convert unusable characters and return them.
|
1661
|
-
return "#{name_to_verilog(self.name)}"
|
1760
|
+
# return "#{name_to_verilog(self.name)}"
|
1761
|
+
vname = name_to_verilog(self.name)
|
1762
|
+
self.properties[:verilog_name] = vname
|
1763
|
+
return "#{vname}"
|
1662
1764
|
end
|
1663
1765
|
end
|
1664
1766
|
|
@@ -1697,8 +1799,9 @@ end
|
|
1697
1799
|
# Look at the unit of time, convert the time to ps and output it.
|
1698
1800
|
# One of two people, TimeWait and Delay.
|
1699
1801
|
class TimeWait
|
1700
|
-
def to_verilog(mode=nil)
|
1701
|
-
|
1802
|
+
# def to_verilog(mode=nil)
|
1803
|
+
def to_verilog(spc = 3)
|
1804
|
+
return (" " * spc) + self.delay.to_verilog + "\n"
|
1702
1805
|
end
|
1703
1806
|
end
|
1704
1807
|
class Delay
|
@@ -1776,9 +1879,9 @@ class SystemT
|
|
1776
1879
|
|
1777
1880
|
# Converts the system to Verilog code.
|
1778
1881
|
def to_verilog
|
1779
|
-
# Preprocessing
|
1780
1882
|
# Detect the registers
|
1781
|
-
regs = []
|
1883
|
+
# regs = []
|
1884
|
+
HDLRuby::Low::VERILOG_REGS.clear
|
1782
1885
|
# The left values.
|
1783
1886
|
self.each_behavior do |behavior|
|
1784
1887
|
# behavior.block.each_statement do |statement|
|
@@ -1786,7 +1889,9 @@ class SystemT
|
|
1786
1889
|
# end
|
1787
1890
|
behavior.each_block_deep do |block|
|
1788
1891
|
block.each_statement do |statement|
|
1789
|
-
|
1892
|
+
if statement.is_a?(Transmit)
|
1893
|
+
HDLRuby::Low::VERILOG_REGS << statement.left.to_verilog
|
1894
|
+
end
|
1790
1895
|
end
|
1791
1896
|
end
|
1792
1897
|
end
|
@@ -1803,19 +1908,27 @@ class SystemT
|
|
1803
1908
|
# # puts "Now regs has clk?: #{regs.include?("clk")}"
|
1804
1909
|
# And the initialized signals.
|
1805
1910
|
self.each_output do |output|
|
1806
|
-
regs << output.to_verilog if output.value
|
1911
|
+
# regs << output.to_verilog if output.value
|
1912
|
+
HDLRuby::Low::VERILOG_REGS << output.to_verilog if output.value
|
1807
1913
|
end
|
1808
1914
|
self.each_inner do |inner|
|
1809
|
-
regs << inner.to_verilog if inner.value
|
1915
|
+
# regs << inner.to_verilog if inner.value
|
1916
|
+
HDLRuby::Low::VERILOG_REGS << inner.to_verilog if inner.value
|
1810
1917
|
end
|
1811
1918
|
# And the array types signals.
|
1812
1919
|
self.each_signal do |sig|
|
1813
|
-
# regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1814
|
-
regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1920
|
+
# # regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1921
|
+
# regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1922
|
+
if sig.type.vector? && sig.type.base.vector? then
|
1923
|
+
HDLRuby::Low::VERILOG_REGS << sig.to_verilog
|
1924
|
+
end
|
1815
1925
|
end
|
1816
1926
|
self.each_inner do |sig|
|
1817
|
-
# regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1818
|
-
regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1927
|
+
# # regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1928
|
+
# regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1929
|
+
if sig.type.vector? && sig.type.base.vector? then
|
1930
|
+
HDLRuby::Low::VERILOG_REGS << sig.to_verilog
|
1931
|
+
end
|
1819
1932
|
end
|
1820
1933
|
|
1821
1934
|
# Code generation
|
@@ -1829,8 +1942,14 @@ class SystemT
|
|
1829
1942
|
|
1830
1943
|
# Spelling necessary for simulation.
|
1831
1944
|
code = "`timescale 1ps/1ps\n\n"
|
1945
|
+
|
1946
|
+
# # Output the module name.
|
1947
|
+
# code << "module #{name_to_verilog(self.name)}("
|
1948
|
+
|
1949
|
+
vname = name_to_verilog(self.name)
|
1950
|
+
self.properties[:verilog_name] = vname
|
1832
1951
|
# Output the module name.
|
1833
|
-
code << "module #{
|
1952
|
+
code << "module #{vname}("
|
1834
1953
|
|
1835
1954
|
# Output the last two to the input.
|
1836
1955
|
inputs[0..-2].each do |input|
|
@@ -1884,7 +2003,8 @@ class SystemT
|
|
1884
2003
|
$vector_reg = "#{output.to_verilog}"
|
1885
2004
|
$vector_cnt = 0
|
1886
2005
|
output.type.each_type do |type|
|
1887
|
-
if regs.include?(type.name) then
|
2006
|
+
# if regs.include?(type.name) then
|
2007
|
+
if HDLRuby::Low::VERILOG_REGS.include?(type.name) then
|
1888
2008
|
code << " output reg"
|
1889
2009
|
else
|
1890
2010
|
code << " output"
|
@@ -1900,7 +2020,8 @@ class SystemT
|
|
1900
2020
|
end
|
1901
2021
|
else
|
1902
2022
|
# if regs.include?(output.name) then
|
1903
|
-
if regs.include?(output.to_verilog) then
|
2023
|
+
# if regs.include?(output.to_verilog) then
|
2024
|
+
if HDLRuby::Low::VERILOG_REGS.include?(output.to_verilog) then
|
1904
2025
|
code << " output reg"
|
1905
2026
|
else
|
1906
2027
|
code << " output"
|
@@ -1931,8 +2052,9 @@ class SystemT
|
|
1931
2052
|
|
1932
2053
|
# Declare "inner".
|
1933
2054
|
self.each_inner do |inner|
|
1934
|
-
# if regs.include?(inner.name) then
|
1935
|
-
if regs.include?(inner.to_verilog) then
|
2055
|
+
# # if regs.include?(inner.name) then
|
2056
|
+
# if regs.include?(inner.to_verilog) then
|
2057
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
1936
2058
|
code << " reg"
|
1937
2059
|
else
|
1938
2060
|
code << " wire"
|
@@ -1960,8 +2082,9 @@ class SystemT
|
|
1960
2082
|
# If there is scope in scope, translate it.
|
1961
2083
|
self.each_scope do |scope|
|
1962
2084
|
scope.each_inner do |inner|
|
1963
|
-
# if regs.include?(inner.name) then
|
1964
|
-
if regs.include?(inner.to_verilog) then
|
2085
|
+
# # if regs.include?(inner.name) then
|
2086
|
+
# if regs.include?(inner.to_verilog) then
|
2087
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
1965
2088
|
code << " reg "
|
1966
2089
|
else
|
1967
2090
|
code << " wire "
|
@@ -2003,7 +2126,10 @@ class SystemT
|
|
2003
2126
|
code << " " * 3
|
2004
2127
|
systemT = systemI.systemT
|
2005
2128
|
code << name_to_verilog(systemT.name) << " "
|
2006
|
-
code << name_to_verilog(systemI.name) << "("
|
2129
|
+
# code << name_to_verilog(systemI.name) << "("
|
2130
|
+
vname = name_to_verilog(systemI.name)
|
2131
|
+
systemI.properties[:verilog_name] = vname
|
2132
|
+
code << vname << "("
|
2007
2133
|
# Its ports connections
|
2008
2134
|
# Inputs
|
2009
2135
|
systemT.each_input do |input|
|
@@ -2052,7 +2178,8 @@ class SystemT
|
|
2052
2178
|
code << blk.repeat_to_verilog!
|
2053
2179
|
end
|
2054
2180
|
# And generate an initial block.
|
2055
|
-
code << " initial begin\n"
|
2181
|
+
# code << " initial begin\n"
|
2182
|
+
code << " initial "
|
2056
2183
|
else
|
2057
2184
|
# Generate a standard process.
|
2058
2185
|
code << " always @( "
|
@@ -2077,54 +2204,57 @@ class SystemT
|
|
2077
2204
|
code << "#{event.last.type.to_s} #{event.last.ref.to_verilog}"
|
2078
2205
|
end
|
2079
2206
|
end
|
2080
|
-
code << " ) begin\n"
|
2207
|
+
# code << " ) begin\n"
|
2208
|
+
code << " ) "
|
2081
2209
|
end
|
2082
2210
|
|
2083
|
-
# Perform "scheduling" using the method "flatten".
|
2084
|
-
block = behavior.block.flatten(behavior.block.mode.to_s)
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
end
|
2211
|
+
# # Perform "scheduling" using the method "flatten".
|
2212
|
+
# block = behavior.block.flatten(behavior.block.mode.to_s)
|
2213
|
+
# code << block.to_verilog(regs)
|
2214
|
+
code << behavior.block.to_verilog
|
2215
|
+
|
2216
|
+
# # Declaration of "inner" part within "always".
|
2217
|
+
# block.each_inner do |inner|
|
2218
|
+
# # if regs.include?(inner.name) then
|
2219
|
+
# if regs.include?(inner.to_verilog) then
|
2220
|
+
# code << " reg"
|
2221
|
+
# else
|
2222
|
+
# code << " wire"
|
2223
|
+
# end
|
2224
|
+
|
2225
|
+
# # Variable has "base", but if there is width etc, it is not in "base".
|
2226
|
+
# # It is determined by an if.
|
2227
|
+
# if inner.type.base?
|
2228
|
+
# if inner.type.base.base?
|
2229
|
+
# # code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
2230
|
+
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
2231
|
+
# else
|
2232
|
+
# # code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
2233
|
+
# code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
2234
|
+
# end
|
2235
|
+
# else
|
2236
|
+
# # code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
2237
|
+
# code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
2238
|
+
# end
|
2239
|
+
# if inner.value then
|
2240
|
+
# # There is an initial value.
|
2241
|
+
# code << " = #{inner.value.to_verilog}"
|
2242
|
+
# end
|
2243
|
+
# code << ";\n"
|
2244
|
+
# end
|
2115
2245
|
|
2116
|
-
# Translate the block that finished scheduling.
|
2117
|
-
block.each_statement do |statement|
|
2118
|
-
|
2119
|
-
end
|
2246
|
+
# # Translate the block that finished scheduling.
|
2247
|
+
# block.each_statement do |statement|
|
2248
|
+
# code << "\n #{statement.to_verilog(behavior.block.mode.to_s)}"
|
2249
|
+
# end
|
2120
2250
|
|
2121
|
-
$fm.fm_par.clear()
|
2251
|
+
# $fm.fm_par.clear()
|
2122
2252
|
|
2123
|
-
code << "\n end\n\n"
|
2253
|
+
# code << "\n end\n\n"
|
2124
2254
|
end
|
2125
2255
|
|
2126
2256
|
# Conclusion.
|
2127
|
-
code << "
|
2257
|
+
code << "\nendmodule"
|
2128
2258
|
return code
|
2129
2259
|
end
|
2130
2260
|
end
|