HDLRuby 2.4.21 → 2.4.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/HDLRuby/hdr_samples/rom.rb +4 -2
- data/lib/HDLRuby/hdr_samples/seqpar_bench.rb +59 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +1 -0
- data/lib/HDLRuby/hdrcc.rb +4 -0
- data/lib/HDLRuby/hruby_low.rb +11 -1
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +326 -0
- data/lib/HDLRuby/hruby_low_without_parinseq.rb +151 -0
- data/lib/HDLRuby/hruby_verilog.rb +308 -133
- data/lib/HDLRuby/std/channel.rb +59 -18
- data/lib/HDLRuby/std/linear.rb +0 -5
- data/lib/HDLRuby/std/memory.rb +68 -17
- data/lib/HDLRuby/version.rb +1 -1
- metadata +5 -2
@@ -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
|
@@ -11,6 +11,13 @@ include HDLRuby::Verilog
|
|
11
11
|
module HDLRuby::Low
|
12
12
|
|
13
13
|
|
14
|
+
# The list of base types used both in verilog and HDLRuby
|
15
|
+
VERILOG_BASE_TYPES = ["signed"]
|
16
|
+
|
17
|
+
# The list of signals that are actually verilog regs.
|
18
|
+
VERILOG_REGS = []
|
19
|
+
|
20
|
+
|
14
21
|
# Sample of very handy for programming.
|
15
22
|
# puts "class=#{self.yes.class}" # Confirm class of self.yes.
|
16
23
|
# puts "methods=#{self.right.methods}" # Confirm method of self.right.
|
@@ -21,7 +28,7 @@ module HDLRuby::Low
|
|
21
28
|
# end
|
22
29
|
|
23
30
|
# Global variable used for indentation and structure (temporary).
|
24
|
-
$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)
|
25
32
|
$vector_reg = "" # For storing signal type at structure declaration. (temporary)
|
26
33
|
$vector_cnt = 0 # For allocating numbers at structure declaration. (temporary)
|
27
34
|
|
@@ -97,9 +104,11 @@ end
|
|
97
104
|
# Enhance Transmit with generation of verilog code.
|
98
105
|
class Transmit
|
99
106
|
# Converts the system to Verilog code.
|
100
|
-
def to_verilog(mode = nil)
|
107
|
+
# def to_verilog(mode = nil)
|
108
|
+
def to_verilog(spc = 3)
|
101
109
|
# Determine blocking assignment or nonblocking substitution from mode and return it.
|
102
|
-
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};"
|
103
112
|
return code
|
104
113
|
end
|
105
114
|
end
|
@@ -107,12 +116,68 @@ end
|
|
107
116
|
# To scheduling to the Block.
|
108
117
|
# Enhance Block with generation of verilog code.
|
109
118
|
class Block
|
110
|
-
# Converts the system to Verilog code.
|
111
|
-
def to_verilog(mode = nil)
|
112
|
-
|
113
|
-
|
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
|
+
code << "\n" if block.each_inner.any?
|
131
|
+
# Declaration of "inner" part within "always".
|
132
|
+
block.each_inner do |inner|
|
133
|
+
# if regs.include?(inner.name) then
|
134
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
135
|
+
# code << " reg"
|
136
|
+
code << "#{" " * (spc+3)}reg"
|
137
|
+
else
|
138
|
+
code << "#{" " * (spc+3)}wire"
|
139
|
+
end
|
140
|
+
|
141
|
+
# Variable has "base", but if there is width etc, it is not in "base".
|
142
|
+
# It is determined by an if.
|
143
|
+
if inner.type.base?
|
144
|
+
if inner.type.base.base?
|
145
|
+
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
146
|
+
code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
147
|
+
else
|
148
|
+
# code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
149
|
+
code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
150
|
+
end
|
151
|
+
else
|
152
|
+
# code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
153
|
+
code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
154
|
+
end
|
155
|
+
if inner.value then
|
156
|
+
# There is an initial value.
|
157
|
+
code << " = #{inner.value.to_verilog}"
|
158
|
+
end
|
159
|
+
code << ";\n"
|
160
|
+
end
|
161
|
+
|
162
|
+
# Translate the block that finished scheduling.
|
163
|
+
block.each_statement do |statement|
|
164
|
+
#code << "\n #{statement.to_verilog(behavior.block.mode.to_s)}"
|
165
|
+
# code << "\n#{" "*spc}#{statement.to_verilog(behavior.block.mode.to_s)}"
|
166
|
+
if statement.is_a?(Block) then
|
167
|
+
code << "\n#{" " * (spc+3)}#{statement.to_verilog(spc+3)}"
|
168
|
+
else
|
169
|
+
code << "\n#{statement.to_verilog(spc+3)}"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
# Close the block."
|
173
|
+
code << "\n#{" "*spc}end"
|
174
|
+
return code
|
114
175
|
end
|
115
176
|
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
|
116
181
|
# Extract and convert to verilog the TimeRepeat statements.
|
117
182
|
# NOTE: work only on the current level of the block (should be called
|
118
183
|
# through each_block_deep).
|
@@ -132,7 +197,7 @@ class Block
|
|
132
197
|
# Declaration of "inner" part within "always".
|
133
198
|
block.each_inner do |inner|
|
134
199
|
# if regs.include?(inner.name) then
|
135
|
-
if
|
200
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
136
201
|
code << " reg"
|
137
202
|
else
|
138
203
|
code << " wire"
|
@@ -456,7 +521,10 @@ class Block
|
|
456
521
|
$fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right
|
457
522
|
end
|
458
523
|
new_block.add_statement(tmt.clone)
|
459
|
-
end
|
524
|
+
end
|
525
|
+
else
|
526
|
+
# Other statements are simply added as is.
|
527
|
+
new_block.add_statement(statement.clone)
|
460
528
|
end
|
461
529
|
end
|
462
530
|
|
@@ -1349,7 +1417,8 @@ end
|
|
1349
1417
|
class TypeVector
|
1350
1418
|
# Converts the system to Verilog code.
|
1351
1419
|
def to_verilog
|
1352
|
-
if self.base.name.to_s != "bit"
|
1420
|
+
# if self.base.name.to_s != "bit"
|
1421
|
+
if VERILOG_BASE_TYPES.include?(self.base.name.to_s)
|
1353
1422
|
return " #{self.base.name.to_s}[#{self.range.first}:#{self.range.last}]"
|
1354
1423
|
end
|
1355
1424
|
return " [#{self.range.first}:#{self.range.last}]"
|
@@ -1423,66 +1492,82 @@ class Value
|
|
1423
1492
|
end
|
1424
1493
|
end
|
1425
1494
|
|
1495
|
+
|
1426
1496
|
# Used to transrate if.
|
1427
1497
|
# Enhance If with generation of verilog code.
|
1428
1498
|
class If
|
1429
|
-
# Converts the system to Verilog code.
|
1430
|
-
def to_verilog(mode = nil)
|
1499
|
+
# # Converts the system to Verilog code.
|
1500
|
+
# def to_verilog(mode = nil)
|
1501
|
+
# Converts to Verilog code, checking adding 'spc' spaces at the begining
|
1502
|
+
# of each line.
|
1503
|
+
def to_verilog(spc = 3)
|
1431
1504
|
|
1432
1505
|
$blocking = false
|
1433
1506
|
|
1434
|
-
if ($space_count == 0) then
|
1435
|
-
|
1436
|
-
else
|
1437
|
-
|
1438
|
-
end
|
1439
|
-
$space_count += 1 # Add count to be used for indentation.
|
1507
|
+
# if ($space_count == 0) then
|
1508
|
+
# result = " " * ($space_count) # Indented based on space_count.
|
1509
|
+
# else
|
1510
|
+
# result = ""
|
1511
|
+
# end
|
1512
|
+
# $space_count += 1 # Add count to be used for indentation.
|
1513
|
+
result = " " * spc # Indented based on space_count.
|
1440
1514
|
|
1441
|
-
result << "if (#{self.condition.to_verilog}) begin\n"
|
1515
|
+
# result << "if (#{self.condition.to_verilog}) begin\n"
|
1516
|
+
result << "if (#{self.condition.to_verilog}) "
|
1442
1517
|
|
1443
1518
|
|
1444
1519
|
# Check if there is yes (if) and output yes or less.
|
1445
1520
|
if self.respond_to? (:yes)
|
1446
|
-
self.yes.each_statement do |statement|
|
1447
|
-
|
1448
|
-
end
|
1449
|
-
result << "#{" " * $space_count} end\n"
|
1521
|
+
# self.yes.each_statement do |statement|
|
1522
|
+
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1523
|
+
# end
|
1524
|
+
# result << "#{" " * $space_count} end\n"
|
1525
|
+
result << self.yes.to_verilog(spc)
|
1450
1526
|
end
|
1451
1527
|
|
1452
1528
|
# If noif (else if) exists, it outputs it.
|
1453
1529
|
# Since noif is directly under, respond_to is unnecessary.
|
1454
1530
|
self.each_noif do |condition, block|
|
1455
|
-
result << "#{" " * $space_count} else if (#{condition.to_verilog}) begin\n"
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1531
|
+
# result << "#{" " * $space_count} else if (#{condition.to_verilog}) begin\n"
|
1532
|
+
result << "\n#{" "*spc}else if (#{condition.to_verilog}) "
|
1533
|
+
# block.each_statement do |statement|
|
1534
|
+
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1535
|
+
# end
|
1536
|
+
# result << "#{" "* $space_count} end\n"
|
1537
|
+
result << block.to_verilog(spc)
|
1460
1538
|
end
|
1461
1539
|
|
1462
1540
|
# Check if there is no (else) and output no or less.
|
1463
|
-
if self.no.respond_to?
|
1464
|
-
result << "#{" " * $space_count} else begin\n"
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1541
|
+
if self.no.respond_to?(:mode)
|
1542
|
+
# result << "#{" " * $space_count} else begin\n"
|
1543
|
+
result << "\n#{" " * spc}else "
|
1544
|
+
# self.no.each_statement do |statement|
|
1545
|
+
# result << "#{" " * $space_count} #{statement.to_verilog(mode)}"
|
1546
|
+
# end
|
1547
|
+
# result << "#{" " * $space_count} end\n"
|
1548
|
+
result << self.no.to_verilog(spc)
|
1469
1549
|
end
|
1470
1550
|
|
1471
|
-
$space_count -= 1 # Since the output ends, reduce the count.
|
1551
|
+
# $space_count -= 1 # Since the output ends, reduce the count.
|
1472
1552
|
return result
|
1473
1553
|
end
|
1474
1554
|
end
|
1475
1555
|
|
1476
1556
|
# Used to translate case
|
1477
1557
|
class Case
|
1478
|
-
def to_verilog(mode = nil)
|
1558
|
+
# def to_verilog(mode = nil)
|
1559
|
+
#
|
1560
|
+
# Converts to Verilog code, checking if variables are register
|
1561
|
+
# or wire adding 'spc' spaces at the begining of each line.
|
1562
|
+
def to_verilog(spc = 3)
|
1479
1563
|
|
1480
|
-
if ($space_count == 0) then
|
1481
|
-
|
1482
|
-
else
|
1483
|
-
|
1484
|
-
end
|
1485
|
-
$space_count += 1 # Add count to be used for indentation.
|
1564
|
+
# if ($space_count == 0) then
|
1565
|
+
# result = " " * ($space_count) # Indented based on space_count.
|
1566
|
+
# else
|
1567
|
+
# result = ""
|
1568
|
+
# end
|
1569
|
+
# $space_count += 1 # Add count to be used for indentation.
|
1570
|
+
result = " " * spc # Indented based on space_count.
|
1486
1571
|
|
1487
1572
|
result = ""
|
1488
1573
|
result << "case(#{self.value.to_verilog})\n"
|
@@ -1490,40 +1575,55 @@ class Case
|
|
1490
1575
|
# n the case statement, each branch is partitioned by when. Process each time when.
|
1491
1576
|
self.each_when do |whens|
|
1492
1577
|
# Reads and stores the numbers and expressions stored in when.
|
1493
|
-
result << " " + " " *$space_count + "#{whens.match.to_verilog}: "
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1578
|
+
# result << " " + " " *$space_count + "#{whens.match.to_verilog}: "
|
1579
|
+
result << " " * (spc+3) + "#{whens.match.to_verilog}: "
|
1580
|
+
|
1581
|
+
# if whens.statement.each_statement.count > 1 then
|
1582
|
+
# result << "begin\n"
|
1583
|
+
# whens.statement.each_statement do |statement|
|
1584
|
+
# result << " "+ " " *$space_count +"#{statement.to_verilog}"
|
1585
|
+
# end
|
1586
|
+
# result << " " + " " *$space_count + "end\n"
|
1587
|
+
# elsif whens.statement.each_statement.count == 1 then
|
1588
|
+
# whens.statement.each_statement do |statement|
|
1589
|
+
# result << "#{statement.to_verilog}"
|
1590
|
+
# end
|
1591
|
+
# else
|
1592
|
+
# # Empty statement case.
|
1593
|
+
# result << "\n"
|
1594
|
+
# end
|
1595
|
+
if whens.statement.each_statement.count >= 1 then
|
1596
|
+
result << whens.statement.to_verilog(spc+3)
|
1504
1597
|
else
|
1505
|
-
# Empty statement case.
|
1506
1598
|
result << "\n"
|
1507
1599
|
end
|
1508
1600
|
end
|
1509
|
-
# The default part is stored in default instead of when. Reads and processes in the same way as when.
|
1601
|
+
# # The default part is stored in default instead of when. Reads and processes in the same way as when.
|
1602
|
+
# if self.default then
|
1603
|
+
# if self.default.each_statement.count > 1 then
|
1604
|
+
# result << " " + " " *$space_count + "default: begin\n"
|
1605
|
+
# self.default.each_statement do |statement|
|
1606
|
+
# result << " " + " " *$space_count + "#{statement.to_verilog}"
|
1607
|
+
# end
|
1608
|
+
# result << " end\n"
|
1609
|
+
# elsif self.default.each_statement.count == 1 then
|
1610
|
+
# result << " " + " " *$space_count + "default: "
|
1611
|
+
# self.default.each_statement do |statement|
|
1612
|
+
# result << "#{statement.to_verilog}"
|
1613
|
+
# end
|
1614
|
+
# end
|
1615
|
+
# end
|
1510
1616
|
if self.default then
|
1511
|
-
if self.default.each_statement.count
|
1512
|
-
result <<
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
result << " end\n"
|
1517
|
-
elsif self.default.each_statement.count == 1 then
|
1518
|
-
result << " " + " " *$space_count + "default: "
|
1519
|
-
self.default.each_statement do |statement|
|
1520
|
-
result << "#{statement.to_verilog}"
|
1521
|
-
end
|
1522
|
-
end
|
1617
|
+
if self.default.each_statement.count >= 1 then
|
1618
|
+
result << self.default.each_statement.to_verilog(spc+3)
|
1619
|
+
else
|
1620
|
+
result << "\n"
|
1621
|
+
end
|
1523
1622
|
end
|
1524
|
-
result << " " + " " *$space_count + "endcase\n" # Conclusion.
|
1623
|
+
# result << " " + " " *$space_count + "endcase\n" # Conclusion.
|
1624
|
+
result << " " * spc + "endcase\n" # Conclusion.
|
1525
1625
|
|
1526
|
-
$space_count -= 1 # Since the output ends, reduce the count.
|
1626
|
+
# $space_count -= 1 # Since the output ends, reduce the count.
|
1527
1627
|
return result # Return case after translation.
|
1528
1628
|
end
|
1529
1629
|
end
|
@@ -1598,7 +1698,7 @@ end
|
|
1598
1698
|
class Unary
|
1599
1699
|
# Converts the system to Verilog code.
|
1600
1700
|
def to_verilog
|
1601
|
-
return "#{self.operator}#{self.child.to_verilog}"
|
1701
|
+
return "#{self.operator[0]}#{self.child.to_verilog}"
|
1602
1702
|
end
|
1603
1703
|
end
|
1604
1704
|
|
@@ -1609,10 +1709,37 @@ class Cast
|
|
1609
1709
|
# by traditional verilog.
|
1610
1710
|
def to_verilog
|
1611
1711
|
# return "#{self.type.to_verilog}'(#{self.child.to_verilog})"
|
1712
|
+
if self.child.is_a?(Value) then
|
1713
|
+
return self.child.to_verilog
|
1714
|
+
end
|
1715
|
+
# Get the type widths, used for computing extensions or truncations.
|
1716
|
+
cw = self.child.type.width
|
1717
|
+
sw = self.type.width
|
1612
1718
|
if self.type.signed? then
|
1613
|
-
return "$signed(#{self.child.to_verilog})"
|
1719
|
+
# return "$signed(#{self.child.to_verilog})"
|
1720
|
+
if (sw>cw) then
|
1721
|
+
# Need to sign extend.
|
1722
|
+
return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," +
|
1723
|
+
"#{self.child.to_verilog}})"
|
1724
|
+
elsif (sw<cw) then
|
1725
|
+
# Need to truncate
|
1726
|
+
return "$signed(#{self.child.to_verilog}[#{sw-1}:0])"
|
1727
|
+
else
|
1728
|
+
# Only enforce signed.
|
1729
|
+
return "$signed(#{self.child.to_verilog})"
|
1730
|
+
end
|
1614
1731
|
else
|
1615
|
-
return "$unsigned(#{self.child.to_verilog})"
|
1732
|
+
# return "$unsigned(#{self.child.to_verilog})"
|
1733
|
+
if (sw>cw) then
|
1734
|
+
# Need to extend.
|
1735
|
+
return "$unsigned({{#{sw-cw}{1'b0}},#{self.child.to_verilog}})"
|
1736
|
+
elsif (sw<cw) then
|
1737
|
+
# Need to truncate
|
1738
|
+
return "$unsigned(#{self.child.to_verilog}[#{sw-1}:0])"
|
1739
|
+
else
|
1740
|
+
# Only enforce signed.
|
1741
|
+
return "$unsigned(#{self.child.to_verilog})"
|
1742
|
+
end
|
1616
1743
|
end
|
1617
1744
|
end
|
1618
1745
|
end
|
@@ -1662,23 +1789,24 @@ end
|
|
1662
1789
|
# Look at the unit of time, convert the time to ps and output it.
|
1663
1790
|
# One of two people, TimeWait and Delay.
|
1664
1791
|
class TimeWait
|
1665
|
-
def to_verilog(mode=nil)
|
1666
|
-
|
1792
|
+
# def to_verilog(mode=nil)
|
1793
|
+
def to_verilog(spc = 3)
|
1794
|
+
return (" " * spc) + self.delay.to_verilog + "\n"
|
1667
1795
|
end
|
1668
1796
|
end
|
1669
1797
|
class Delay
|
1670
1798
|
def to_verilog
|
1671
1799
|
time = self.value.to_s
|
1672
1800
|
if(self.unit.to_s == "ps") then
|
1673
|
-
return "##{time}"
|
1801
|
+
return "##{time};"
|
1674
1802
|
elsif(self.unit.to_s == "ns")
|
1675
|
-
return "##{time}000"
|
1803
|
+
return "##{time}000;"
|
1676
1804
|
elsif(self.unit.to_s == "us")
|
1677
|
-
return "##{time}000000"
|
1805
|
+
return "##{time}000000;"
|
1678
1806
|
elsif(self.unit.to_s == "ms")
|
1679
|
-
return "##{time}000000000"
|
1807
|
+
return "##{time}000000000;"
|
1680
1808
|
elsif(self.unit.to_s == "s")
|
1681
|
-
return "##{time}000000000000"
|
1809
|
+
return "##{time}000000000000;"
|
1682
1810
|
end
|
1683
1811
|
end
|
1684
1812
|
end
|
@@ -1690,6 +1818,20 @@ end
|
|
1690
1818
|
|
1691
1819
|
# Enhance SystemT with generation of verilog code.
|
1692
1820
|
class SystemT
|
1821
|
+
|
1822
|
+
## Tells if a connection is actually a port connection.
|
1823
|
+
def port_output_connection?(connection)
|
1824
|
+
return self.each_systemI.find do |systemI|
|
1825
|
+
if connection.right.is_a?(RefName) &&
|
1826
|
+
connection.right.ref.is_a?(RefName) &&
|
1827
|
+
systemI.name == connection.right.ref.name
|
1828
|
+
puts "port_connection for right=#{connection.right.name} and systemI=#{systemI.name}"
|
1829
|
+
true
|
1830
|
+
else
|
1831
|
+
false
|
1832
|
+
end
|
1833
|
+
end
|
1834
|
+
end
|
1693
1835
|
|
1694
1836
|
## Tells if an expression is a reference to port +systemI.signal+.
|
1695
1837
|
def port_assign?(expr, systemI, signal)
|
@@ -1727,9 +1869,9 @@ class SystemT
|
|
1727
1869
|
|
1728
1870
|
# Converts the system to Verilog code.
|
1729
1871
|
def to_verilog
|
1730
|
-
# Preprocessing
|
1731
1872
|
# Detect the registers
|
1732
|
-
regs = []
|
1873
|
+
# regs = []
|
1874
|
+
HDLRuby::Low::VERILOG_REGS.clear
|
1733
1875
|
# The left values.
|
1734
1876
|
self.each_behavior do |behavior|
|
1735
1877
|
# behavior.block.each_statement do |statement|
|
@@ -1737,23 +1879,46 @@ class SystemT
|
|
1737
1879
|
# end
|
1738
1880
|
behavior.each_block_deep do |block|
|
1739
1881
|
block.each_statement do |statement|
|
1740
|
-
|
1882
|
+
if statement.is_a?(Transmit)
|
1883
|
+
HDLRuby::Low::VERILOG_REGS << statement.left.to_verilog
|
1884
|
+
end
|
1741
1885
|
end
|
1742
1886
|
end
|
1743
1887
|
end
|
1888
|
+
# # puts "regs has clk?: #{regs.include?("clk")}"
|
1889
|
+
# # puts "for system #{self.name}"
|
1890
|
+
# # Remove the left values of connection, they do not count.
|
1891
|
+
# self.scope.each_connection do |connection|
|
1892
|
+
# # Skip port connections.
|
1893
|
+
# next if !self.port_output_connection?(connection)
|
1894
|
+
# # puts "Not counting left in connection: #{connection.to_verilog}"
|
1895
|
+
# # puts "i.e.: #{connection.left.to_verilog}"
|
1896
|
+
# regs.delete(connection.left.to_verilog)
|
1897
|
+
# end
|
1898
|
+
# # puts "Now regs has clk?: #{regs.include?("clk")}"
|
1744
1899
|
# And the initialized signals.
|
1745
1900
|
self.each_output do |output|
|
1746
|
-
regs << output.to_verilog if output.value
|
1901
|
+
# regs << output.to_verilog if output.value
|
1902
|
+
HDLRuby::Low::VERILOG_REGS << output.to_verilog if output.value
|
1747
1903
|
end
|
1748
1904
|
self.each_inner do |inner|
|
1749
|
-
regs << inner.to_verilog if inner.value
|
1905
|
+
# regs << inner.to_verilog if inner.value
|
1906
|
+
HDLRuby::Low::VERILOG_REGS << inner.to_verilog if inner.value
|
1750
1907
|
end
|
1751
1908
|
# And the array types signals.
|
1752
1909
|
self.each_signal do |sig|
|
1753
|
-
regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1910
|
+
# # regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1911
|
+
# regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1912
|
+
if sig.type.vector? && sig.type.base.vector? then
|
1913
|
+
HDLRuby::Low::VERILOG_REGS << sig.to_verilog
|
1914
|
+
end
|
1754
1915
|
end
|
1755
1916
|
self.each_inner do |sig|
|
1756
|
-
regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1917
|
+
# # regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1918
|
+
# regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1919
|
+
if sig.type.vector? && sig.type.base.vector? then
|
1920
|
+
HDLRuby::Low::VERILOG_REGS << sig.to_verilog
|
1921
|
+
end
|
1757
1922
|
end
|
1758
1923
|
|
1759
1924
|
# Code generation
|
@@ -1822,7 +1987,8 @@ class SystemT
|
|
1822
1987
|
$vector_reg = "#{output.to_verilog}"
|
1823
1988
|
$vector_cnt = 0
|
1824
1989
|
output.type.each_type do |type|
|
1825
|
-
if regs.include?(type.name) then
|
1990
|
+
# if regs.include?(type.name) then
|
1991
|
+
if HDLRuby::Low::VERILOG_REGS.include?(type.name) then
|
1826
1992
|
code << " output reg"
|
1827
1993
|
else
|
1828
1994
|
code << " output"
|
@@ -1838,7 +2004,8 @@ class SystemT
|
|
1838
2004
|
end
|
1839
2005
|
else
|
1840
2006
|
# if regs.include?(output.name) then
|
1841
|
-
if regs.include?(output.to_verilog) then
|
2007
|
+
# if regs.include?(output.to_verilog) then
|
2008
|
+
if HDLRuby::Low::VERILOG_REGS.include?(output.to_verilog) then
|
1842
2009
|
code << " output reg"
|
1843
2010
|
else
|
1844
2011
|
code << " output"
|
@@ -1869,8 +2036,9 @@ class SystemT
|
|
1869
2036
|
|
1870
2037
|
# Declare "inner".
|
1871
2038
|
self.each_inner do |inner|
|
1872
|
-
# if regs.include?(inner.name) then
|
1873
|
-
if regs.include?(inner.to_verilog) then
|
2039
|
+
# # if regs.include?(inner.name) then
|
2040
|
+
# if regs.include?(inner.to_verilog) then
|
2041
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
1874
2042
|
code << " reg"
|
1875
2043
|
else
|
1876
2044
|
code << " wire"
|
@@ -1898,8 +2066,9 @@ class SystemT
|
|
1898
2066
|
# If there is scope in scope, translate it.
|
1899
2067
|
self.each_scope do |scope|
|
1900
2068
|
scope.each_inner do |inner|
|
1901
|
-
# if regs.include?(inner.name) then
|
1902
|
-
if regs.include?(inner.to_verilog) then
|
2069
|
+
# # if regs.include?(inner.name) then
|
2070
|
+
# if regs.include?(inner.to_verilog) then
|
2071
|
+
if HDLRuby::Low::VERILOG_REGS.include?(inner.to_verilog) then
|
1903
2072
|
code << " reg "
|
1904
2073
|
else
|
1905
2074
|
code << " wire "
|
@@ -1932,9 +2101,11 @@ class SystemT
|
|
1932
2101
|
|
1933
2102
|
code << "\n"
|
1934
2103
|
|
2104
|
+
# puts "For system=#{self.name}"
|
1935
2105
|
# transliation of the instantiation part.
|
1936
2106
|
# Generate the instances connections.
|
1937
2107
|
self.each_systemI do |systemI|
|
2108
|
+
# puts "Processing systemI = #{systemI.name}"
|
1938
2109
|
# Its Declaration.
|
1939
2110
|
code << " " * 3
|
1940
2111
|
systemT = systemI.systemT
|
@@ -1988,7 +2159,8 @@ class SystemT
|
|
1988
2159
|
code << blk.repeat_to_verilog!
|
1989
2160
|
end
|
1990
2161
|
# And generate an initial block.
|
1991
|
-
code << " initial begin\n"
|
2162
|
+
# code << " initial begin\n"
|
2163
|
+
code << " initial "
|
1992
2164
|
else
|
1993
2165
|
# Generate a standard process.
|
1994
2166
|
code << " always @( "
|
@@ -2013,54 +2185,57 @@ class SystemT
|
|
2013
2185
|
code << "#{event.last.type.to_s} #{event.last.ref.to_verilog}"
|
2014
2186
|
end
|
2015
2187
|
end
|
2016
|
-
code << " ) begin\n"
|
2188
|
+
# code << " ) begin\n"
|
2189
|
+
code << " ) "
|
2017
2190
|
end
|
2018
2191
|
|
2019
|
-
# Perform "scheduling" using the method "flatten".
|
2020
|
-
block = behavior.block.flatten(behavior.block.mode.to_s)
|
2021
|
-
|
2022
|
-
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
end
|
2192
|
+
# # Perform "scheduling" using the method "flatten".
|
2193
|
+
# block = behavior.block.flatten(behavior.block.mode.to_s)
|
2194
|
+
# code << block.to_verilog(regs)
|
2195
|
+
code << behavior.block.to_verilog
|
2196
|
+
|
2197
|
+
# # Declaration of "inner" part within "always".
|
2198
|
+
# block.each_inner do |inner|
|
2199
|
+
# # if regs.include?(inner.name) then
|
2200
|
+
# if regs.include?(inner.to_verilog) then
|
2201
|
+
# code << " reg"
|
2202
|
+
# else
|
2203
|
+
# code << " wire"
|
2204
|
+
# end
|
2205
|
+
|
2206
|
+
# # Variable has "base", but if there is width etc, it is not in "base".
|
2207
|
+
# # It is determined by an if.
|
2208
|
+
# if inner.type.base?
|
2209
|
+
# if inner.type.base.base?
|
2210
|
+
# # code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog};\n"
|
2211
|
+
# code << "#{inner.type.base.to_verilog} #{inner.to_verilog} #{inner.type.to_verilog}"
|
2212
|
+
# else
|
2213
|
+
# # code << "#{inner.type.to_verilog} #{inner.to_verilog};\n"
|
2214
|
+
# code << "#{inner.type.to_verilog} #{inner.to_verilog}"
|
2215
|
+
# end
|
2216
|
+
# else
|
2217
|
+
# # code << " #{inner.type.to_verilog}#{inner.to_verilog};\n"
|
2218
|
+
# code << " #{inner.type.to_verilog}#{inner.to_verilog}"
|
2219
|
+
# end
|
2220
|
+
# if inner.value then
|
2221
|
+
# # There is an initial value.
|
2222
|
+
# code << " = #{inner.value.to_verilog}"
|
2223
|
+
# end
|
2224
|
+
# code << ";\n"
|
2225
|
+
# end
|
2051
2226
|
|
2052
|
-
# Translate the block that finished scheduling.
|
2053
|
-
block.each_statement do |statement|
|
2054
|
-
|
2055
|
-
end
|
2227
|
+
# # Translate the block that finished scheduling.
|
2228
|
+
# block.each_statement do |statement|
|
2229
|
+
# code << "\n #{statement.to_verilog(behavior.block.mode.to_s)}"
|
2230
|
+
# end
|
2056
2231
|
|
2057
|
-
$fm.fm_par.clear()
|
2232
|
+
# $fm.fm_par.clear()
|
2058
2233
|
|
2059
|
-
code << "\n end\n\n"
|
2234
|
+
# code << "\n end\n\n"
|
2060
2235
|
end
|
2061
2236
|
|
2062
2237
|
# Conclusion.
|
2063
|
-
code << "
|
2238
|
+
code << "\nendmodule"
|
2064
2239
|
return code
|
2065
2240
|
end
|
2066
2241
|
end
|