HDLRuby 2.4.21 → 2.4.28
Sign up to get free protection for your applications and to get access to all the features.
- 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
|