HDLRuby 2.2.3 → 2.2.5
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/hruby_high.rb +2 -2
- data/lib/HDLRuby/hruby_low.rb +1 -1
- data/lib/HDLRuby/hruby_low2c.rb +11 -5
- data/lib/HDLRuby/hruby_low2vhd.rb +49 -5
- data/lib/HDLRuby/hruby_low_bool2select.rb +11 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1 -1
- data/lib/HDLRuby/hruby_low_without_select.rb +14 -0
- data/lib/HDLRuby/hruby_verilog.rb +74 -6
- data/lib/HDLRuby/sim/hruby_sim.h +7 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +80 -17
- data/lib/HDLRuby/sim/hruby_sim_core.c +1 -1
- data/lib/HDLRuby/std/channel.rb +3 -1
- data/lib/HDLRuby/std/memory.rb +18 -15
- data/lib/HDLRuby/test_hruby_high.rb +13 -10
- data/lib/HDLRuby/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 970d857a0599c47d617e6a3d4be7720134a33adc009a3c069332fa198ef05a3f
|
4
|
+
data.tar.gz: a81688812f9a76bf80a56d2d3aabb59caf507dd3cd4897d37ced83c3f2319f03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b2e23d1c84cb1a7e4e3bcb16b90f409caaa6ded6855b85590ee10de2d378976f44f35612b955b710ed4dc7bd7b316b0a3c2e1a1d1a1b8a74a34051e49b3459b
|
7
|
+
data.tar.gz: 92c75812d649592042da377556762c64aa43d2c2ceca6515f3424cec41c0e79ed2c81880f7e566cb6ea5ffdbb9c6d3f1106ae8c1750b38fe4283e4c5c4f0648b
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -2045,11 +2045,11 @@ module HDLRuby::High
|
|
2045
2045
|
# return If.new(condition) { self }
|
2046
2046
|
# Remove self from the current block.
|
2047
2047
|
obj = self
|
2048
|
-
High.cur_block.delete_statement!(obj)
|
2048
|
+
::HDLRuby::High.cur_block.delete_statement!(obj)
|
2049
2049
|
# Creates the if statement.
|
2050
2050
|
stmnt = If.new(condition) { add_statement(obj) }
|
2051
2051
|
# Add it to the current block.
|
2052
|
-
High.cur_block.add_statement(stmnt)
|
2052
|
+
::HDLRuby::High.cur_block.add_statement(stmnt)
|
2053
2053
|
# Returns the result.
|
2054
2054
|
return stmnt
|
2055
2055
|
end
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -3340,7 +3340,7 @@ module HDLRuby::Low
|
|
3340
3340
|
|
3341
3341
|
# Clones the TimeRepeat (deeply)
|
3342
3342
|
def clone
|
3343
|
-
return TimeRepeat(@statement.clone,@delay.clone)
|
3343
|
+
return TimeRepeat.new(@statement.clone,@delay.clone)
|
3344
3344
|
end
|
3345
3345
|
|
3346
3346
|
# Iterates over the expression children if any.
|
data/lib/HDLRuby/hruby_low2c.rb
CHANGED
@@ -620,8 +620,9 @@ module HDLRuby::Low
|
|
620
620
|
|
621
621
|
# Is it a clocked behavior?
|
622
622
|
events = self.each_event.to_a
|
623
|
-
if events.empty? then
|
623
|
+
if events.empty? && !self.is_a?(TimeBehavior) then
|
624
624
|
# No events, this is not a clock behavior.
|
625
|
+
# And it is not a time behavior neigther.
|
625
626
|
# Generate the events list from the right values.
|
626
627
|
# First get the references.
|
627
628
|
refs = self.block.each_node_deep.select do |node|
|
@@ -1429,10 +1430,15 @@ module HDLRuby::Low
|
|
1429
1430
|
|
1430
1431
|
# Declares the data.
|
1431
1432
|
# Create the bit string.
|
1432
|
-
str = self.content.is_a?(BitString) ?
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1433
|
+
# str = self.content.is_a?(BitString) ?
|
1434
|
+
# self.content.to_s : self.content.to_s(2).rjust(32,"0")
|
1435
|
+
if self.content.is_a?(BitString) then
|
1436
|
+
str = self.content.is_a?(BitString) ?
|
1437
|
+
self.content.to_s : self.content.to_s(2).rjust(32,"0")
|
1438
|
+
else
|
1439
|
+
sign = self.content>=0 ? "0" : "1"
|
1440
|
+
str = self.content.abs.to_s(2).rjust(width,sign).upcase
|
1441
|
+
end
|
1436
1442
|
# Is it a fully defined number?
|
1437
1443
|
if str =~ /^[01]+$/ then
|
1438
1444
|
# Yes, generate a numeral value.
|
@@ -727,11 +727,20 @@ module HDLRuby::Low
|
|
727
727
|
# It is assumed that the inners are all in declared in the
|
728
728
|
# direct sub block and that they represent variables, i.e.,
|
729
729
|
# Low::to_upper_space! and Low::with_var! has been called.
|
730
|
-
vars = self.block.each_inner.to_a
|
730
|
+
vars = self.block.each_inner.to_a
|
731
731
|
|
732
732
|
# The resulting string.
|
733
|
-
res = "
|
733
|
+
res = ""
|
734
|
+
|
735
|
+
# Generate the TimeRepeat as different processes if any.
|
736
|
+
self.block.each_statement_deep do |stmnt|
|
737
|
+
if stmnt.is_a?(TimeRepeat) then
|
738
|
+
res << stmnt.process_to_vhdl(vars,level)
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
734
742
|
# Generate the header.
|
743
|
+
res << " " * (level*3)
|
735
744
|
unless self.block.name.empty? then
|
736
745
|
res << Low2VHDL.vhdl_name(self.block.name) << ": "
|
737
746
|
end
|
@@ -797,6 +806,11 @@ module HDLRuby::Low
|
|
797
806
|
# Generate the body directly.
|
798
807
|
res << self.block.to_vhdl(vars,level+1)
|
799
808
|
end
|
809
|
+
# Insert an infinite wait is the top block is a timed block.
|
810
|
+
if self.block.is_a?(TimeBlock) then
|
811
|
+
res << " " * ((level+1)*3)
|
812
|
+
res << "wait;\n"
|
813
|
+
end
|
800
814
|
# Close the process.
|
801
815
|
res << " " * (level*3)
|
802
816
|
res << "end process;\n\n"
|
@@ -990,12 +1004,41 @@ module HDLRuby::Low
|
|
990
1004
|
|
991
1005
|
## Extends the TimeRepeat class with generation of HDLRuby::High text.
|
992
1006
|
class TimeRepeat
|
993
|
-
|
994
1007
|
# Generates the text of the equivalent HDLRuby::High code.
|
995
1008
|
# +vars+ is the list of the variables and
|
996
1009
|
# +level+ is the hierachical level of the object.
|
997
1010
|
def to_vhdl(vars,level = 0)
|
998
|
-
|
1011
|
+
# Nothing to do, see process_to_vhdl
|
1012
|
+
return ""
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
# Generates the text of the equivalent HDLRuby::High code as a new
|
1016
|
+
# process.
|
1017
|
+
# +vars+ is the list of the variables and
|
1018
|
+
# +level+ is the hierachical level of the object.
|
1019
|
+
def process_to_vhdl(vars,level = 0)
|
1020
|
+
# Generate a separate process for the repeated statement with
|
1021
|
+
# a wait.
|
1022
|
+
# The resulting string.
|
1023
|
+
res = " " * (level*3)
|
1024
|
+
# Generate the header.
|
1025
|
+
unless self.block.name.empty? then
|
1026
|
+
res << Low2VHDL.vhdl_name(self.block.name) << ": "
|
1027
|
+
end
|
1028
|
+
res << "process \n"
|
1029
|
+
# Generate the content.
|
1030
|
+
res << " " * (level*3)
|
1031
|
+
res << "begin\n"
|
1032
|
+
# Adds the wait.
|
1033
|
+
res << " " * ((level+1)*3)
|
1034
|
+
res << "wait for " << self.delay.to_vhdl(level) << ";\n"
|
1035
|
+
# Generate the remaining of the body.
|
1036
|
+
res << self.statement.to_vhdl(vars,level+1)
|
1037
|
+
# Close the process.
|
1038
|
+
res << " " * (level*3)
|
1039
|
+
res << "end process;\n\n"
|
1040
|
+
# Return the result.
|
1041
|
+
return res
|
999
1042
|
end
|
1000
1043
|
end
|
1001
1044
|
|
@@ -1107,7 +1150,8 @@ module HDLRuby::Low
|
|
1107
1150
|
/[01]/ =~ self.content[-1] ? "0" : self.content[-1]
|
1108
1151
|
return '"' + self.content.to_s.rjust(width,sign).upcase + '"'
|
1109
1152
|
else
|
1110
|
-
sign = self.type.signed? ? (self.content>=0 ? "0" : "1") : "0"
|
1153
|
+
# sign = self.type.signed? ? (self.content>=0 ? "0" : "1") : "0"
|
1154
|
+
sign = self.content>=0 ? "0" : "1"
|
1111
1155
|
return '"' + self.content.abs.to_s(2).rjust(width,sign).upcase + '"'
|
1112
1156
|
end
|
1113
1157
|
end
|
@@ -129,6 +129,17 @@ module HDLRuby::Low
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
+
## Extends the TimeRepeat class with functionality for converting booleans
|
133
|
+
# in assignments to setlect operators.
|
134
|
+
class TimeRepeat
|
135
|
+
# Converts booleans in assignments to select operators.
|
136
|
+
def boolean_in_assign2select!
|
137
|
+
# Simply recurse on the stamtement.
|
138
|
+
self.statement.boolean_in_assign2select!
|
139
|
+
return self
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
132
143
|
|
133
144
|
## Extends the Block class with functionality for converting booleans
|
134
145
|
# in assignments to select operators.
|
@@ -108,6 +108,20 @@ module HDLRuby::Low
|
|
108
108
|
end
|
109
109
|
|
110
110
|
|
111
|
+
## Extends the TimeRepeat class with functionality for converting booleans
|
112
|
+
# in assignments to select operators.
|
113
|
+
class TimeRepeat
|
114
|
+
# Extract the Select expressions.
|
115
|
+
def extract_selects!
|
116
|
+
# Simply recruse on the statement.
|
117
|
+
if self.statement.is_a?(Block) then
|
118
|
+
return []
|
119
|
+
else
|
120
|
+
return self.statement.extract_selects!
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
111
125
|
|
112
126
|
## Extends the Block class with functionality for converting select
|
113
127
|
# expressions to case statements.
|
@@ -113,6 +113,65 @@ class Block
|
|
113
113
|
puts "Block to_verilog not found" # For debugging
|
114
114
|
end
|
115
115
|
|
116
|
+
# Extract and convert to verilog the TimeRepeat statements.
|
117
|
+
# NOTE: work only on the current level of the block (should be called
|
118
|
+
# through each_block_deep).
|
119
|
+
def repeat_to_verilog!
|
120
|
+
code = ""
|
121
|
+
# Gather the TimeRepeat statements.
|
122
|
+
repeats = self.each_statement.find_all { |st| st.is_a?(TimeRepeat) }
|
123
|
+
# Remove them from the block.
|
124
|
+
repeats.each { |st| self.delete_statement!(st) }
|
125
|
+
# Generate them separately in timed always processes.
|
126
|
+
repeats.each do |st|
|
127
|
+
code << " always #{st.delay.to_verilog} begin\n"
|
128
|
+
|
129
|
+
# Perform "scheduling" using the method "flatten".
|
130
|
+
block = st.statement.flatten(st.statement.mode.to_s)
|
131
|
+
|
132
|
+
# Declaration of "inner" part within "always".
|
133
|
+
block.each_inner do |inner|
|
134
|
+
# if regs.include?(inner.name) then
|
135
|
+
if regs.include?(inner.to_verilog) then
|
136
|
+
code << " reg"
|
137
|
+
else
|
138
|
+
code << " 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(block.mode.to_s)}"
|
165
|
+
end
|
166
|
+
|
167
|
+
$fm.fm_par.clear()
|
168
|
+
|
169
|
+
code << "\n end\n\n"
|
170
|
+
end
|
171
|
+
return code
|
172
|
+
end
|
173
|
+
|
174
|
+
|
116
175
|
# Process top layer of Block.
|
117
176
|
# Determine whether there is a block under block and convert it.
|
118
177
|
def flatten(mode = nil)
|
@@ -1587,20 +1646,20 @@ end
|
|
1587
1646
|
# One of two people, TimeWait and Delay.
|
1588
1647
|
class TimeWait
|
1589
1648
|
def to_verilog(mode=nil)
|
1590
|
-
return self.delay.to_verilog
|
1649
|
+
return self.delay.to_verilog + "\n"
|
1591
1650
|
end
|
1592
1651
|
end
|
1593
1652
|
class Delay
|
1594
1653
|
def to_verilog
|
1595
1654
|
time = self.value.to_s
|
1596
1655
|
if(self.unit.to_s == "ps") then
|
1597
|
-
return "##{time}
|
1656
|
+
return "##{time}"
|
1598
1657
|
elsif(self.unit.to_s == "ns")
|
1599
|
-
return "##{time}000
|
1658
|
+
return "##{time}000"
|
1600
1659
|
elsif(self.unit.to_s == "us")
|
1601
|
-
return "##{time}000000
|
1660
|
+
return "##{time}000000"
|
1602
1661
|
elsif(self.unit.to_s == "ms")
|
1603
|
-
return "##{time}000000000
|
1662
|
+
return "##{time}000000000"
|
1604
1663
|
end
|
1605
1664
|
end
|
1606
1665
|
end
|
@@ -1691,7 +1750,10 @@ class SystemT
|
|
1691
1750
|
end
|
1692
1751
|
# When only input is used, it is necessary to close (), so it branches with if.
|
1693
1752
|
if outputs.empty? && inout.empty? then
|
1694
|
-
code << " #{inputs.last.to_verilog} ); \n" unless inputs.empty?
|
1753
|
+
# code << " #{inputs.last.to_verilog} ); \n" unless inputs.empty?
|
1754
|
+
if (inputs.empty?)
|
1755
|
+
code << " ); \n"
|
1756
|
+
end
|
1695
1757
|
else
|
1696
1758
|
code << " #{inputs.last.to_verilog}," unless inputs.empty?
|
1697
1759
|
end
|
@@ -1896,8 +1958,14 @@ class SystemT
|
|
1896
1958
|
# Translation of behavior part (always).
|
1897
1959
|
self.each_behavior do |behavior|
|
1898
1960
|
if behavior.block.is_a?(TimeBlock) then
|
1961
|
+
# Extract and translate the TimeRepeat separately.
|
1962
|
+
behavior.each_block_deep do |blk|
|
1963
|
+
code << blk.repeat_to_verilog!
|
1964
|
+
end
|
1965
|
+
# And generate an initial block.
|
1899
1966
|
code << " initial begin\n"
|
1900
1967
|
else
|
1968
|
+
# Generate a standard process.
|
1901
1969
|
code << " always @( "
|
1902
1970
|
# If there is no "always" condition, it is always @("*").
|
1903
1971
|
if behavior.each_event.to_a.empty? then
|
data/lib/HDLRuby/sim/hruby_sim.h
CHANGED
@@ -143,6 +143,13 @@ extern Value add_value(Value src0, Value src1, Value dst);
|
|
143
143
|
* @return dst */
|
144
144
|
extern Value sub_value(Value src0, Value src1, Value dst);
|
145
145
|
|
146
|
+
/** Computes the multiplication of two general values.
|
147
|
+
* @param src0 the first source value of the addition
|
148
|
+
* @param src1 the second source value of the addition
|
149
|
+
* @param dst the destination value
|
150
|
+
* @return dst */
|
151
|
+
extern Value mul_value(Value src0, Value src1, Value dst);
|
152
|
+
|
146
153
|
/** Computes the not of a value.
|
147
154
|
* @param src the source value of the not
|
148
155
|
* @param dst the destination value
|
@@ -238,9 +238,9 @@ void resize_value(Value value, int size) {
|
|
238
238
|
* @param data the source data */
|
239
239
|
void set_value(Value value, int numeric, void* data) {
|
240
240
|
value->numeric = numeric;
|
241
|
-
if (numeric)
|
241
|
+
if (numeric) {
|
242
242
|
value->data_int = *((unsigned long long*)data);
|
243
|
-
else {
|
243
|
+
} else {
|
244
244
|
memcpy(value->data_str,data,type_width(value->type)*sizeof(char));
|
245
245
|
}
|
246
246
|
}
|
@@ -359,7 +359,7 @@ static Value set_bitstring_value(Value src, Value dst) {
|
|
359
359
|
unsigned long long i;
|
360
360
|
/* Resize dst to match the width. */
|
361
361
|
resize_value(dst,width);
|
362
|
-
/*
|
362
|
+
/* Set the type and size of the destination from the type of the source.*/
|
363
363
|
dst->type = src->type;
|
364
364
|
dst->numeric = 0;
|
365
365
|
|
@@ -379,6 +379,29 @@ static Value set_bitstring_value(Value src, Value dst) {
|
|
379
379
|
}
|
380
380
|
|
381
381
|
|
382
|
+
/** Sets a value to undefined.
|
383
|
+
* @param dst the destination value
|
384
|
+
* @return the destination value */
|
385
|
+
static Value set_undefined_bitstring(Value dst) {
|
386
|
+
/* Compute the width of the result in bits. */
|
387
|
+
unsigned long long width = type_width(dst->type);
|
388
|
+
|
389
|
+
/* set the type and size of the destination. */
|
390
|
+
dst->numeric = 0;
|
391
|
+
|
392
|
+
/* Get access to the destination data. */
|
393
|
+
char* dst_data = dst->data_str;
|
394
|
+
|
395
|
+
/* undefine the destination. */
|
396
|
+
unsigned long long count;
|
397
|
+
for(count = 0; count < width; ++count) {
|
398
|
+
dst_data[count] = 'x';
|
399
|
+
}
|
400
|
+
/* Return the destination. */
|
401
|
+
return dst;
|
402
|
+
}
|
403
|
+
|
404
|
+
|
382
405
|
/** Computes the neg of a bitstring value.
|
383
406
|
* @param src the source value of the not
|
384
407
|
* @param dst the destination value
|
@@ -389,7 +412,7 @@ static Value neg_value_bitstring(Value src, Value dst) {
|
|
389
412
|
|
390
413
|
/* Update the destination capacity if required. */
|
391
414
|
resize_value(dst,width);
|
392
|
-
/*
|
415
|
+
/* Set the type and size of the destination from the type of the source.*/
|
393
416
|
dst->type = src->type;
|
394
417
|
dst->numeric = 0;
|
395
418
|
|
@@ -434,7 +457,7 @@ static Value add_value_bitstring(Value src0, Value src1, Value dst) {
|
|
434
457
|
|
435
458
|
/* Update the destination capacity if required. */
|
436
459
|
resize_value(dst,width0);
|
437
|
-
/*
|
460
|
+
/* Set the type and size of the destination from the type of the source.*/
|
438
461
|
dst->type = src0->type;
|
439
462
|
dst->numeric = 0;
|
440
463
|
|
@@ -503,7 +526,7 @@ static Value sub_value_bitstring(Value src0, Value src1, Value dst) {
|
|
503
526
|
|
504
527
|
/* Update the destination capacity if required. */
|
505
528
|
resize_value(dst,width0);
|
506
|
-
/*
|
529
|
+
/* Set the type and size of the destination from the type of the source.*/
|
507
530
|
dst->type = src0->type;
|
508
531
|
dst->numeric = 0;
|
509
532
|
|
@@ -572,7 +595,7 @@ static Value not_value_bitstring(Value src, Value dst) {
|
|
572
595
|
|
573
596
|
/* Update the destination capacity if required. */
|
574
597
|
resize_value(dst,width);
|
575
|
-
/*
|
598
|
+
/* Set the type and size of the destination from the type of the source.*/
|
576
599
|
dst->type = src->type;
|
577
600
|
dst->numeric = 0;
|
578
601
|
|
@@ -611,7 +634,7 @@ static Value and_value_bitstring(Value src0, Value src1, Value dst) {
|
|
611
634
|
|
612
635
|
/* Update the destination capacity if required. */
|
613
636
|
resize_value(dst,width0);
|
614
|
-
/*
|
637
|
+
/* Set the type and size of the destination from the type of the source.*/
|
615
638
|
dst->type = src0->type;
|
616
639
|
dst->numeric = 0;
|
617
640
|
|
@@ -680,7 +703,7 @@ static Value or_value_bitstring(Value src0, Value src1, Value dst) {
|
|
680
703
|
|
681
704
|
/* Update the destination capacity if required. */
|
682
705
|
resize_value(dst,width0);
|
683
|
-
/*
|
706
|
+
/* Set the type and size of the destination from the type of the source.*/
|
684
707
|
dst->type = src0->type;
|
685
708
|
dst->numeric = 0;
|
686
709
|
|
@@ -749,7 +772,7 @@ static Value xor_value_bitstring(Value src0, Value src1, Value dst) {
|
|
749
772
|
|
750
773
|
/* Update the destination capacity if required. */
|
751
774
|
resize_value(dst,width0);
|
752
|
-
/*
|
775
|
+
/* Set the type and size of the destination from the type of the source.*/
|
753
776
|
dst->type = src0->type;
|
754
777
|
dst->numeric = 0;
|
755
778
|
|
@@ -953,7 +976,7 @@ static Value equal_value_bitstring(Value src0, Value src1, Value dst) {
|
|
953
976
|
|
954
977
|
/* Update the destination capacity if required. */
|
955
978
|
resize_value(dst,width0);
|
956
|
-
/*
|
979
|
+
/* Set the type and size of the destination from the type of the source.*/
|
957
980
|
dst->type = src0->type;
|
958
981
|
dst->numeric = 0;
|
959
982
|
|
@@ -1026,7 +1049,7 @@ static Value select_value_bitstring(Value cond, Value dst, unsigned int num,
|
|
1026
1049
|
|
1027
1050
|
/* Update the destination capacity if required. */
|
1028
1051
|
resize_value(dst,width);
|
1029
|
-
/*
|
1052
|
+
/* Set the type and size of the destination from the type of the source.*/
|
1030
1053
|
dst->type = src->type;
|
1031
1054
|
dst->numeric = 0;
|
1032
1055
|
char *dst_data = dst->data_str;
|
@@ -1098,7 +1121,7 @@ static Value cast_value_bitstring(Value src, Type type, Value dst) {
|
|
1098
1121
|
|
1099
1122
|
/* Update the destination capacity if required. */
|
1100
1123
|
resize_value(dst,width);
|
1101
|
-
/*
|
1124
|
+
/* Set the type and size of the destination from the type of the source.*/
|
1102
1125
|
dst->type = type;
|
1103
1126
|
dst->numeric = 0;
|
1104
1127
|
|
@@ -1221,7 +1244,7 @@ Value read_range_bitstring(Value src, long long first, long long last,
|
|
1221
1244
|
|
1222
1245
|
/* Update the destination capacity if required. */
|
1223
1246
|
resize_value(dst,length);
|
1224
|
-
/*
|
1247
|
+
/* Set the type and size of the destination from the type of the source.*/
|
1225
1248
|
dst->type = make_type_vector(get_type_bit(),length);
|
1226
1249
|
dst->numeric = 0;
|
1227
1250
|
|
@@ -1249,6 +1272,7 @@ Value write_range_bitstring(Value src, long long first, long long last,
|
|
1249
1272
|
last = first;
|
1250
1273
|
first = tmp;
|
1251
1274
|
}
|
1275
|
+
// printf("Initially first=%lld, last=%lld\n",first,last);
|
1252
1276
|
/* Get the widths of the source and the desintation. */
|
1253
1277
|
unsigned long long src_width = type_width(src->type);
|
1254
1278
|
unsigned long long dst_width = type_width(dst->type);
|
@@ -1256,6 +1280,8 @@ Value write_range_bitstring(Value src, long long first, long long last,
|
|
1256
1280
|
unsigned long long bw = dst->type->base;
|
1257
1281
|
first *= bw;
|
1258
1282
|
last *= bw;
|
1283
|
+
last += bw-1;
|
1284
|
+
// printf("bw=%lld, first=%lld, last=%lld\n",bw,first,last);
|
1259
1285
|
/* Access the source and destination bitstring data. */
|
1260
1286
|
char* dst_data = dst->data_str;
|
1261
1287
|
char* src_data = src->data_str;
|
@@ -1354,6 +1380,22 @@ static Value sub_value_numeric(Value src0, Value src1, Value dst) {
|
|
1354
1380
|
}
|
1355
1381
|
|
1356
1382
|
|
1383
|
+
/** Computes the multiplication of two numeric values.
|
1384
|
+
* @param src0 the first source value of the addition
|
1385
|
+
* @param src1 the second source value of the addition
|
1386
|
+
* @param dst the destination value
|
1387
|
+
* @return dst */
|
1388
|
+
static Value mul_value_numeric(Value src0, Value src1, Value dst) {
|
1389
|
+
/* Sets state of the destination using the first source. */
|
1390
|
+
dst->type = src0->type;
|
1391
|
+
dst->numeric = 1;
|
1392
|
+
|
1393
|
+
/* Perform the addition. */
|
1394
|
+
dst->data_int = src0->data_int * src1->data_int;
|
1395
|
+
return dst;
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
|
1357
1399
|
/** Computes the NOT of a numeric value.
|
1358
1400
|
* @param src the source value of the not
|
1359
1401
|
* @param dst the destination value
|
@@ -1605,7 +1647,7 @@ Value read_range_numeric(Value value, long long first, long long last,
|
|
1605
1647
|
length *= bw;
|
1606
1648
|
// printf("first=%lld last=%lld bw=%llu length=%lld\n",first,last,bw,length);
|
1607
1649
|
|
1608
|
-
/*
|
1650
|
+
/* Set the type and size of the destination from the type of the source.*/
|
1609
1651
|
dst->type = make_type_vector(get_type_bit(),length);
|
1610
1652
|
dst->numeric = 1;
|
1611
1653
|
|
@@ -1748,6 +1790,27 @@ Value sub_value(Value src0, Value src1, Value dst) {
|
|
1748
1790
|
}
|
1749
1791
|
|
1750
1792
|
|
1793
|
+
/** Computes the multiplication of two general values.
|
1794
|
+
* @param src0 the first source value of the addition
|
1795
|
+
* @param src1 the second source value of the addition
|
1796
|
+
* @param dst the destination value
|
1797
|
+
* @return dst */
|
1798
|
+
Value mul_value(Value src0, Value src1, Value dst) {
|
1799
|
+
/* Might allocate a new value so save the current pool state. */
|
1800
|
+
unsigned int pos = get_value_pos();
|
1801
|
+
/* Do a numeric computation if possible, otherwise fallback to bitstring
|
1802
|
+
* computation. */
|
1803
|
+
if (src0->numeric && src1->numeric) {
|
1804
|
+
/* Both sources are numeric. */
|
1805
|
+
return mul_value_numeric(src0,src1,dst);
|
1806
|
+
} else {
|
1807
|
+
/* Cannot compute (for now), simply undefines the destination. */
|
1808
|
+
set_undefined_bitstring(dst);
|
1809
|
+
}
|
1810
|
+
return dst;
|
1811
|
+
}
|
1812
|
+
|
1813
|
+
|
1751
1814
|
/** Computes the NOT of a general value.
|
1752
1815
|
* @param src the source value of the not
|
1753
1816
|
* @param dst the destination value
|
@@ -2199,14 +2262,14 @@ RefRangeS make_ref_rangeS(SignalI signal, unsigned long long first,
|
|
2199
2262
|
* @param value the value to convert
|
2200
2263
|
* @return the resulting int. */
|
2201
2264
|
unsigned long long value2integer(Value value) {
|
2265
|
+
unsigned long long width = type_width(value->type);
|
2202
2266
|
/* If the value is numeric, just return its data as is. */
|
2203
2267
|
if (value->numeric) {
|
2204
|
-
return value->data_int;
|
2268
|
+
return value->data_int & ~((unsigned long long)(-1LL) << width);
|
2205
2269
|
}
|
2206
2270
|
/* Otherwise convert the bitstring to an integer if possible,
|
2207
2271
|
* but return 0 in case of failure. */
|
2208
2272
|
/* Gets the width of the value. */
|
2209
|
-
unsigned long long width = type_width(value->type);
|
2210
2273
|
unsigned long long res = 0;
|
2211
2274
|
unsigned long long i;
|
2212
2275
|
char bit;
|
@@ -496,7 +496,7 @@ void transmit_to_signal_range(Value value, RefRangeS ref) {
|
|
496
496
|
SignalI signal = ref.signal;
|
497
497
|
unsigned long long first = ref.first;
|
498
498
|
unsigned long long last = ref.last;
|
499
|
-
// printf("Tansmit to signal range: %s(%p)\n",signal->name,signal);
|
499
|
+
// printf("Tansmit to signal range: %s(%p) [%lld:%lld]\n",signal->name,signal,first,last);
|
500
500
|
/* Can transmit, copy the content. */
|
501
501
|
if (signal->fading)
|
502
502
|
signal->f_value = write_range(value,first,last,signal->f_value);
|
data/lib/HDLRuby/std/channel.rb
CHANGED
data/lib/HDLRuby/std/memory.rb
CHANGED
@@ -47,7 +47,7 @@ HDLRuby::High::Std.channel(:mem_sync) do |n,typ,size,clk_e,rst,br_rsts = []|
|
|
47
47
|
inner :"rwb_#{p}" # Read/!Write
|
48
48
|
end
|
49
49
|
# Declare the memory content.
|
50
|
-
typ[
|
50
|
+
typ[-size].inner :mem
|
51
51
|
|
52
52
|
# Defines the ports of the memory as branchs of the channel.
|
53
53
|
n.times do |p|
|
@@ -241,7 +241,7 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
241
241
|
[awidth].inner :abus_r_reg
|
242
242
|
|
243
243
|
# Declare the memory content.
|
244
|
-
typ[
|
244
|
+
typ[-size].inner :mem
|
245
245
|
|
246
246
|
# Processes handling the memory access.
|
247
247
|
par(clk.posedge) do
|
@@ -339,9 +339,14 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
339
339
|
# using +target+ as target of access result.
|
340
340
|
reader do |blk,target|
|
341
341
|
# By default the read trigger is 0.
|
342
|
-
top_block.unshift { trig_r <= 0 }
|
343
|
-
# The read procedure.
|
344
342
|
rst = send(rst_name)
|
343
|
+
top_block.unshift do
|
344
|
+
# Initialize the address so that the next access is at address 0.
|
345
|
+
hif(rst==1) { abus_r <= -1 }
|
346
|
+
# Reset so switch of the access trigger.
|
347
|
+
trig_r <= 0
|
348
|
+
end
|
349
|
+
# The read procedure.
|
345
350
|
par do
|
346
351
|
hif(rst == 0) do
|
347
352
|
# No reset, so can perform the read.
|
@@ -354,10 +359,6 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
354
359
|
abus_r <= abus_r + 1
|
355
360
|
trig_r <= 1
|
356
361
|
end
|
357
|
-
helse do
|
358
|
-
# Initialize the address to -1
|
359
|
-
abus_r <= -1
|
360
|
-
end
|
361
362
|
end
|
362
363
|
end
|
363
364
|
end
|
@@ -378,24 +379,26 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
|
|
378
379
|
# using +target+ as target of access result.
|
379
380
|
writer do |blk,target|
|
380
381
|
# By default the read trigger is 0.
|
381
|
-
top_block.unshift { trig_w <= 0 }
|
382
|
-
# The write procedure.
|
383
382
|
rst = send(rst_name)
|
383
|
+
top_block.unshift do
|
384
|
+
# Initialize the address so that the next access is at address 0.
|
385
|
+
hif(rst == 1) { abus_w <= -1 }
|
386
|
+
# Reset so switch of the access trigger.
|
387
|
+
trig_w <= 0
|
388
|
+
end
|
389
|
+
# The write procedure.
|
384
390
|
par do
|
385
391
|
hif(rst == 0) do
|
386
392
|
# No reset, so can perform the write.
|
387
393
|
hif(trig_w == 1) do
|
388
394
|
# The trigger was previously set, write ok.
|
389
|
-
blk.call
|
390
|
-
end
|
395
|
+
blk.call
|
396
|
+
end if blk
|
391
397
|
# Prepare the write.
|
392
398
|
abus_w <= abus_w + 1
|
393
399
|
trig_w <= 1
|
394
400
|
dbus_w <= target
|
395
401
|
end
|
396
|
-
helse do
|
397
|
-
abus_w <= -1
|
398
|
-
end
|
399
402
|
end
|
400
403
|
end
|
401
404
|
end
|
@@ -273,20 +273,23 @@ begin
|
|
273
273
|
if systemI1Statements.size != 4 then
|
274
274
|
puts "Error: invalid number of statements, got #{systemI1Statements.size} but expecting 4."
|
275
275
|
success = false
|
276
|
-
elsif !systemI1Statements[0].is_a?(
|
277
|
-
puts "Error: invalid first statement, got #{systemI1Statements[0].class} but expecting
|
276
|
+
elsif !systemI1Statements[0].is_a?(If) then
|
277
|
+
puts "Error: invalid first statement, got #{systemI1Statements[0].class} but expecting If."
|
278
278
|
success = false
|
279
|
-
elsif systemI1Statements[0].
|
280
|
-
puts "Error: invalid first statement
|
279
|
+
elsif !systemI1Statements[0].yes.last_statement.is_a?(Transmit) then
|
280
|
+
puts "Error: invalid content of first if statement, got #{systemI1Statements[0].yes.class} but expecting Transmit."
|
281
281
|
success = false
|
282
|
-
elsif systemI1Statements[0].
|
283
|
-
puts "Error: invalid first statement
|
282
|
+
elsif systemI1Statements[0].yes.last_statement.left.object.name != :o1 then
|
283
|
+
puts "Error: invalid content of first if statement left, got #{systemI1Statements[0].left.object.name} but expecting o1."
|
284
284
|
success = false
|
285
|
-
elsif systemI1Statements[0].
|
286
|
-
puts "Error: invalid first statement right
|
285
|
+
elsif systemI1Statements[0].yes.last_statement.right.operator != :* then
|
286
|
+
puts "Error: invalid content of first if statement right operator, got #{systemI1Statements[0].right.operator} but expecting *."
|
287
287
|
success = false
|
288
|
-
elsif systemI1Statements[0].
|
289
|
-
puts "Error: invalid first statement right
|
288
|
+
elsif systemI1Statements[0].yes.last_statement.right.left.object.name != :i0 then
|
289
|
+
puts "Error: invalid content of first first if statement right left, got #{systemI1Statements[0].right.left.object.name} but expecting i0."
|
290
|
+
success = false
|
291
|
+
elsif systemI1Statements[0].yes.last_statement.right.right.object.name != :i1 then
|
292
|
+
puts "Error: invalid content of first if statement right right, got #{systemI1Statements[0].right.left.object.name} but expecting i1."
|
290
293
|
success = false
|
291
294
|
elsif !systemI1Statements[2].is_a?(If) then
|
292
295
|
puts "Error: invalid third statement, got #{systemI1Statements[2].class} but expecting If."
|
data/lib/HDLRuby/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HDLRuby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|