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