HDLRuby 2.4.26 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/HDLRuby/drivers/xcd.rb +79 -0
- data/lib/HDLRuby/drivers/xcd/dummy.xcd +4 -0
- data/lib/HDLRuby/hdr_samples/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
|