HDLRuby 2.11.5 → 2.11.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/hruby_sim/hruby_rcsim_build.c +84 -48
- data/ext/hruby_sim/hruby_sim.h +65 -1
- data/ext/hruby_sim/hruby_sim_calc.c +211 -28
- data/ext/hruby_sim/hruby_sim_core.c +58 -4
- data/ext/hruby_sim/hruby_sim_mute.c +65 -0
- data/ext/hruby_sim/hruby_sim_stack_calc.c +10 -0
- data/ext/hruby_sim/hruby_sim_tree_calc.c +36 -9
- data/ext/hruby_sim/hruby_sim_vcd.c +18 -14
- data/lib/HDLRuby/hdr_samples/arith_bench.rb +92 -0
- data/lib/HDLRuby/hdr_samples/constant_prop_bench.rb +58 -0
- data/lib/HDLRuby/hdrcc.rb +15 -6
- data/lib/HDLRuby/hruby_bstr.rb +15 -3
- data/lib/HDLRuby/hruby_high.rb +8 -4
- data/lib/HDLRuby/hruby_low.rb +14 -5
- data/lib/HDLRuby/hruby_low2c.rb +179 -68
- data/lib/HDLRuby/hruby_low_without_connection.rb +6 -2
- data/lib/HDLRuby/hruby_rcsim.rb +25 -15
- data/lib/HDLRuby/hruby_rsim.rb +63 -13
- data/lib/HDLRuby/hruby_rsim_mute.rb +35 -0
- data/lib/HDLRuby/hruby_rsim_vcd.rb +3 -3
- data/lib/HDLRuby/hruby_values.rb +19 -2
- data/lib/HDLRuby/hruby_verilog.rb +67 -17
- data/lib/HDLRuby/std/fsm.rb +3 -3
- data/lib/HDLRuby/version.rb +1 -1
- metadata +6 -2
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -4615,8 +4615,8 @@ module HDLRuby::Low
|
|
4615
4615
|
# Yes so it is also a left value if it is a sub ref.
|
4616
4616
|
if parent.respond_to?(:ref) then
|
4617
4617
|
# It might nor be a sub ref.
|
4618
|
-
# return parent.ref
|
4619
|
-
return parent.ref.
|
4618
|
+
# return parent.ref.eql?(self)
|
4619
|
+
return parent.ref.equal?(self)
|
4620
4620
|
else
|
4621
4621
|
# It is necessarily a sub ref (case of RefConcat for now).
|
4622
4622
|
return true
|
@@ -4624,8 +4624,8 @@ module HDLRuby::Low
|
|
4624
4624
|
end
|
4625
4625
|
# No, therefore maybe it is directly a left value.
|
4626
4626
|
return (parent.is_a?(Transmit) || parent.is_a?(Connection)) &&
|
4627
|
-
|
4628
|
-
parent.left.
|
4627
|
+
# parent.left.eql?(self)
|
4628
|
+
parent.left.equal?(self)
|
4629
4629
|
end
|
4630
4630
|
|
4631
4631
|
# Tells if the expression is a right value.
|
@@ -4715,9 +4715,18 @@ module HDLRuby::Low
|
|
4715
4715
|
# converted to BitString.
|
4716
4716
|
unless content.is_a?(Numeric) or
|
4717
4717
|
content.is_a?(HDLRuby::BitString)
|
4718
|
-
content = HDLRuby::BitString.new(content.to_s)
|
4718
|
+
# content = HDLRuby::BitString.new(content.to_s)
|
4719
|
+
content = content.to_s
|
4720
|
+
if self.type.unsigned? && content[0] != 0 then
|
4721
|
+
content = "0" + content.rjust(self.type.width,content[0])
|
4722
|
+
end
|
4723
|
+
content = HDLRuby::BitString.new(content)
|
4719
4724
|
end
|
4720
4725
|
@content = content
|
4726
|
+
if (@content.is_a?(Numeric) && self.type.unsigned?) then
|
4727
|
+
# Adjust the bits for unsigned.
|
4728
|
+
@content = @content & (2**self.type.width-1)
|
4729
|
+
end
|
4721
4730
|
end
|
4722
4731
|
end
|
4723
4732
|
|
data/lib/HDLRuby/hruby_low2c.rb
CHANGED
@@ -20,6 +20,7 @@ module HDLRuby::Low
|
|
20
20
|
# h files.
|
21
21
|
def self.includes(*names)
|
22
22
|
res = '#include <stdlib.h>' + "\n" +
|
23
|
+
'#include <string.h>' + "\n" +
|
23
24
|
'#include "hruby_sim.h"' + "\n"
|
24
25
|
names.each { |name| res << "#include \"#{name}\"\n" }
|
25
26
|
res << "\n"
|
@@ -687,6 +688,10 @@ module HDLRuby::Low
|
|
687
688
|
if time then
|
688
689
|
res << " " * (level+1)*3
|
689
690
|
res << "register_timed_behavior(behavior);\n"
|
691
|
+
else
|
692
|
+
# Otherwise register it as a behavior to initialize. */
|
693
|
+
res << " " * (level+1)*3
|
694
|
+
res << "register_init_behavior(behavior);\n"
|
690
695
|
end
|
691
696
|
|
692
697
|
# Set the owner if any.
|
@@ -724,12 +729,39 @@ module HDLRuby::Low
|
|
724
729
|
refs = self.block.each_node_deep.select do |node|
|
725
730
|
node.is_a?(RefName) && !node.leftvalue? &&
|
726
731
|
!node.parent.is_a?(RefName)
|
732
|
+
# node.is_a?(RefName) && !node.parent.is_a?(RefName)
|
727
733
|
end.to_a
|
728
734
|
# Keep only one ref per signal.
|
729
|
-
refs.uniq! { |
|
735
|
+
refs.uniq! { |ref| ref.full_name }
|
736
|
+
# # Remove the intermediate left values if sequential.
|
737
|
+
# self.each_block_deep do |blk|
|
738
|
+
# if blk.mode == :seq && !blk.parent.is_a?(Behavior) then
|
739
|
+
# blk.each_node_deep do |node|
|
740
|
+
# if node.is_a?(RefName) && node.leftvalue? &&
|
741
|
+
# !node.parent.is_a?(RefName) then
|
742
|
+
# puts "removing ref=#{node.full_name}"
|
743
|
+
# refs.delete_if {|ref| ref.full_name == node.full_name }
|
744
|
+
# end
|
745
|
+
# end
|
746
|
+
# end
|
747
|
+
# end
|
748
|
+
# # Remove left values.
|
749
|
+
# lefts = refs.select {|ref| ref.leftvalue? }.map do |ref|
|
750
|
+
# ref.full_name
|
751
|
+
# end
|
752
|
+
# puts "lefts=#{lefts}"
|
753
|
+
# puts "first refs.size=#{refs.size}"
|
754
|
+
# refs.delete_if { |ref| lefts.include?(ref.full_name) }
|
755
|
+
# puts "now refs.size=#{refs.size}"
|
756
|
+
# puts "refs=#{refs.map {|r| r.full_name}}"
|
730
757
|
# Remove the inner signals from the list.
|
731
|
-
self.block.each_inner do |inner|
|
732
|
-
|
758
|
+
# self.block.each_inner do |inner|
|
759
|
+
# refs.delete_if {|r| r.name == inner.name }
|
760
|
+
# end
|
761
|
+
self.each_block_deep do |blk|
|
762
|
+
blk.each_inner do |inner|
|
763
|
+
refs.delete_if {|r| r.name == inner.name }
|
764
|
+
end
|
733
765
|
end
|
734
766
|
# Generate the event.
|
735
767
|
events = refs.map {|ref| Event.new(:anyedge,ref.clone) }
|
@@ -923,9 +955,9 @@ module HDLRuby::Low
|
|
923
955
|
if self.value then
|
924
956
|
# There is an initial value.
|
925
957
|
res << " " * (level+1)*3
|
926
|
-
|
927
|
-
|
928
|
-
|
958
|
+
res << "copy_value("
|
959
|
+
self.value.to_c_expr(res,level+2)
|
960
|
+
res << ",signalI->c_value);\n"
|
929
961
|
res << "copy_value("
|
930
962
|
self.value.to_c_expr(res,level+2)
|
931
963
|
res << ",signalI->f_value);\n"
|
@@ -1725,26 +1757,49 @@ module HDLRuby::Low
|
|
1725
1757
|
res << "if (is_defined()) {\n"
|
1726
1758
|
# The condition is testable.
|
1727
1759
|
# Generate the case as a succession of if statements.
|
1728
|
-
self.each_when do |w|
|
1760
|
+
# self.each_when do |w|
|
1761
|
+
# res << " " * ((level+2)*3)
|
1762
|
+
# res << "dup();\n"
|
1763
|
+
# res << " " * ((level+2)*3)
|
1764
|
+
# w.match.to_c(res,level+2)
|
1765
|
+
# res << "if (to_integer() == to_integer()) { \n"
|
1766
|
+
# w.statement.to_c(res,level+3)
|
1767
|
+
# res << " " * (level+2)*3
|
1768
|
+
# res << "}\n"
|
1769
|
+
# end
|
1770
|
+
# if self.default then
|
1771
|
+
# res << " " * (level+2)*3
|
1772
|
+
# res << "else {\n"
|
1773
|
+
# self.default.to_c(res,level+3)
|
1774
|
+
# res << " " * (level+2)*3
|
1775
|
+
# res << "}\n"
|
1776
|
+
# end
|
1777
|
+
res << " " * ((level+2)*3)
|
1778
|
+
res << "int val=to_integer(), done=0;\n"
|
1779
|
+
self.each_when.with_index do |w,i|
|
1729
1780
|
res << " " * ((level+2)*3)
|
1730
|
-
res << "
|
1781
|
+
res << "if (!done) {\n" unless i == 0
|
1731
1782
|
res << " " * ((level+2)*3)
|
1732
1783
|
w.match.to_c(res,level+2)
|
1733
|
-
res << "if (
|
1784
|
+
res << "if (val == to_integer()) {\n"
|
1734
1785
|
w.statement.to_c(res,level+3)
|
1786
|
+
res << " " * (level+3)*3
|
1787
|
+
res << "done = 1;\n"
|
1735
1788
|
res << " " * (level+2)*3
|
1789
|
+
res << "}" unless i == 0
|
1736
1790
|
res << "}\n"
|
1737
1791
|
end
|
1738
1792
|
if self.default then
|
1739
1793
|
res << " " * (level+2)*3
|
1740
|
-
res << "
|
1794
|
+
res << "if(!done) {\n"
|
1741
1795
|
self.default.to_c(res,level+3)
|
1742
1796
|
res << " " * (level+2)*3
|
1743
1797
|
res << "}\n"
|
1744
1798
|
end
|
1799
|
+
|
1745
1800
|
# Close the case.
|
1746
1801
|
res << " " * (level+1)*3
|
1747
|
-
res << "pop();\n" # Remove the testing value.
|
1802
|
+
# res << "pop();\n" # Remove the testing value.
|
1748
1803
|
res << " " * (level+1)*3
|
1749
1804
|
res << "}\n"
|
1750
1805
|
res << " " * (level)*3
|
@@ -1832,7 +1887,7 @@ module HDLRuby::Low
|
|
1832
1887
|
def to_c(res,level = 0)
|
1833
1888
|
# The resulting string.
|
1834
1889
|
res << " " * level*3
|
1835
|
-
if (number < 0) then
|
1890
|
+
if (self.number < 0) then
|
1836
1891
|
# Generate an infinite loop executing the block and waiting.
|
1837
1892
|
res << "for(;;) {\n"
|
1838
1893
|
else
|
@@ -2058,8 +2113,6 @@ module HDLRuby::Low
|
|
2058
2113
|
## Generates the content of the h file.
|
2059
2114
|
# def to_ch
|
2060
2115
|
def to_ch(res)
|
2061
|
-
# res = ""
|
2062
|
-
# return "extern Value #{Low2C.make_name(self)}();"
|
2063
2116
|
res << "extern Value " << Low2C.make_name(self) << "();"
|
2064
2117
|
return res
|
2065
2118
|
end
|
@@ -2072,74 +2125,131 @@ module HDLRuby::Low
|
|
2072
2125
|
def to_c_make(res,level = 0)
|
2073
2126
|
# Check is the value maker is already present.
|
2074
2127
|
maker = Low2C.make_name(self);
|
2075
|
-
# return "" if @@made_values.include?(maker)
|
2076
2128
|
return res if @@made_values.include?(maker)
|
2077
2129
|
@@made_values.add(maker)
|
2078
2130
|
|
2079
|
-
# The resulting string.
|
2080
|
-
# res = ""
|
2081
|
-
|
2082
2131
|
# The header of the value generation.
|
2083
2132
|
res << " " * level*3
|
2084
|
-
# res << "Value " << Low2C.make_name(self) << "() {\n"
|
2085
2133
|
res << "Value " << maker << "() {\n"
|
2086
2134
|
|
2135
|
+
# # Declares the data.
|
2136
|
+
# # Create the bit string.
|
2137
|
+
# # str = self.content.is_a?(BitString) ?
|
2138
|
+
# # self.content.to_s : self.content.to_s(2).rjust(32,"0")
|
2139
|
+
# if self.content.is_a?(BitString) then
|
2140
|
+
# str = self.content.is_a?(BitString) ?
|
2141
|
+
# self.content.to_s : self.content.to_s(2).rjust(32,"0")
|
2142
|
+
# else
|
2143
|
+
# # sign = self.content>=0 ? "0" : "1"
|
2144
|
+
# # str = self.content.abs.to_s(2).rjust(width,sign).upcase
|
2145
|
+
# if self.content >= 0 then
|
2146
|
+
# str = self.content.to_s(2).rjust(width,"0").upcase
|
2147
|
+
# else
|
2148
|
+
# # Compute the extension to the next multiple
|
2149
|
+
# # of int_width
|
2150
|
+
# ext_width = (((width-1) / Low2C.int_width)+1)*Low2C.int_width
|
2151
|
+
# # Convert the string.
|
2152
|
+
# str = (2**ext_width+self.content).to_s(2).upcase
|
2153
|
+
# end
|
2154
|
+
# # puts "content=#{self.content} str=#{str}"
|
2155
|
+
# end
|
2156
|
+
# # Is it a fully defined number?
|
2157
|
+
# # NOTE: bignum values are not supported by the simulation engine
|
2158
|
+
# # yet, therefore numeric values are limited to 64 max.
|
2159
|
+
# if str =~ /^[01]+$/ && str.length <= 64 then
|
2160
|
+
# # Yes, generate a numeral value.
|
2161
|
+
# res << " " * (level+1)*3
|
2162
|
+
# res << "static unsigned int data[] = { "
|
2163
|
+
# res << str.scan(/.{1,#{Low2C.int_width}}/m).reverse.map do |sub|
|
2164
|
+
# sub.to_i(2).to_s # + "ULL"
|
2165
|
+
# end.join(",")
|
2166
|
+
# res << ", 0" if (str.length <= 32)
|
2167
|
+
# res << " };\n"
|
2168
|
+
# # Create the value.
|
2169
|
+
# res << " " * (level+1)*3
|
2170
|
+
# # puts "str=#{str} type width=#{self.type.width} signed? #{type.signed?}"
|
2171
|
+
# # res << "return make_set_value(#{self.type.to_c(level+1)},1," +
|
2172
|
+
# # "data);\n"
|
2173
|
+
# res << "return make_set_value("
|
2174
|
+
# self.type.to_c(res,level+1)
|
2175
|
+
# res << ",1,data);\n"
|
2176
|
+
# else
|
2177
|
+
# # No, generate a bit string value.
|
2178
|
+
# res << " " * (level+1)*3
|
2179
|
+
# # res << "static unsigned char data[] = \"#{str}\";\n"
|
2180
|
+
# res << "static unsigned char data[] = \"#{str.reverse}\";\n"
|
2181
|
+
# # Create the value.
|
2182
|
+
# res << " " * (level+1)*3
|
2183
|
+
# # res << "return make_set_value(#{self.type.to_c(level+1)},0," +
|
2184
|
+
# # "data);\n"
|
2185
|
+
# res << "return make_set_value("
|
2186
|
+
# self.type.to_c(res,level+1)
|
2187
|
+
# res << ",0,data);\n"
|
2188
|
+
# end
|
2189
|
+
|
2087
2190
|
# Declares the data.
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2191
|
+
if self.content.is_a?(::Integer) then
|
2192
|
+
if self.type.width <= 64 then
|
2193
|
+
res << " " * (level+1)*3
|
2194
|
+
res << "Value value = make_value("
|
2195
|
+
self.type.to_c(res,level+1)
|
2196
|
+
res << ",1);\n"
|
2197
|
+
# res << " " * (level+1)*3
|
2198
|
+
# res << "value->numeric = 1;\n"
|
2199
|
+
res << " " * (level+1)*3
|
2200
|
+
res << "value->capacity = 0;\n"
|
2201
|
+
res << " " * (level+1)*3
|
2202
|
+
res << "value->data_str = NULL;\n"
|
2203
|
+
res << " " * (level+1)*3
|
2204
|
+
if self.content.bit_length <= 63 then
|
2205
|
+
res << "value->data_int = #{self.content}LLU;\n"
|
2206
|
+
else
|
2207
|
+
res << "value->data_int = "
|
2208
|
+
res << "#{self.content & 0xFFFFFFFFFFFF}LLU;\n"
|
2209
|
+
end
|
2210
|
+
# Close the value.
|
2211
|
+
res << " " * (level+1)*3
|
2212
|
+
res << "return value;\n"
|
2213
|
+
res << " " * level*3
|
2214
|
+
res << "}\n\n"
|
2215
|
+
# Return the result.
|
2216
|
+
return res
|
2099
2217
|
else
|
2100
|
-
|
2101
|
-
#
|
2102
|
-
|
2103
|
-
#
|
2104
|
-
str =
|
2218
|
+
str = self.content.to_s(2)
|
2219
|
+
# if str[-1] == "-" then
|
2220
|
+
# str[-1] = "1"
|
2221
|
+
# elsif str[-1] == "1" then
|
2222
|
+
# str = "0" + str
|
2223
|
+
# end
|
2224
|
+
if self.content < 0 then
|
2225
|
+
str = (2**self.type.width + self.content).to_s(2)
|
2226
|
+
str = "1" * (self.type.width-str.length) + str
|
2227
|
+
else
|
2228
|
+
str = self.content.to_s(2)
|
2229
|
+
str = "0" * (self.type.width-str.length) + str
|
2230
|
+
end
|
2231
|
+
str.reverse!
|
2105
2232
|
end
|
2106
|
-
# puts "content=#{self.content} str=#{str}"
|
2107
|
-
end
|
2108
|
-
# Is it a fully defined number?
|
2109
|
-
# NOTE: bignum values are not supported by the simulation engine
|
2110
|
-
# yet, therefore numeric values are limited to 64 max.
|
2111
|
-
if str =~ /^[01]+$/ && str.length <= 64 then
|
2112
|
-
# Yes, generate a numeral value.
|
2113
|
-
res << " " * (level+1)*3
|
2114
|
-
res << "static unsigned int data[] = { "
|
2115
|
-
res << str.scan(/.{1,#{Low2C.int_width}}/m).reverse.map do |sub|
|
2116
|
-
sub.to_i(2).to_s # + "ULL"
|
2117
|
-
end.join(",")
|
2118
|
-
res << ", 0" if (str.length <= 32)
|
2119
|
-
res << " };\n"
|
2120
|
-
# Create the value.
|
2121
|
-
res << " " * (level+1)*3
|
2122
|
-
# puts "str=#{str} type width=#{self.type.width} signed? #{type.signed?}"
|
2123
|
-
# res << "return make_set_value(#{self.type.to_c(level+1)},1," +
|
2124
|
-
# "data);\n"
|
2125
|
-
res << "return make_set_value("
|
2126
|
-
self.type.to_c(res,level+1)
|
2127
|
-
res << ",1,data);\n"
|
2128
2233
|
else
|
2129
|
-
|
2130
|
-
res << " " * (level+1)*3
|
2131
|
-
# res << "static unsigned char data[] = \"#{str}\";\n"
|
2132
|
-
res << "static unsigned char data[] = \"#{str.reverse}\";\n"
|
2133
|
-
# Create the value.
|
2134
|
-
res << " " * (level+1)*3
|
2135
|
-
# res << "return make_set_value(#{self.type.to_c(level+1)},0," +
|
2136
|
-
# "data);\n"
|
2137
|
-
res << "return make_set_value("
|
2138
|
-
self.type.to_c(res,level+1)
|
2139
|
-
res << ",0,data);\n"
|
2234
|
+
str = content.to_s.reverse
|
2140
2235
|
end
|
2236
|
+
str = str.ljust(self.type.width,str[-1])
|
2237
|
+
res << " " * (level+1)*3
|
2238
|
+
res << "Value value = make_value("
|
2239
|
+
self.type.to_c(res,level+1)
|
2240
|
+
res << ",1);\n"
|
2241
|
+
res << " " * (level+1)*3
|
2242
|
+
res << "value->numeric = 0;\n"
|
2243
|
+
res << " " * (level+1)*3
|
2244
|
+
res << "value->capacity = #{str.length+1};"
|
2245
|
+
res << " " * (level+1)*3
|
2246
|
+
res << "value->data_str = calloc(value->capacity,sizeof(char));\n"
|
2247
|
+
res << " " * (level+1)*3
|
2248
|
+
res << "strcpy(value->data_str,\"#{str}\");\n"
|
2141
2249
|
|
2142
2250
|
# Close the value.
|
2251
|
+
res << " " * (level+1)*3
|
2252
|
+
res << "return value;\n"
|
2143
2253
|
res << " " * level*3
|
2144
2254
|
res << "}\n\n"
|
2145
2255
|
# Return the result.
|
@@ -2147,6 +2257,7 @@ module HDLRuby::Low
|
|
2147
2257
|
end
|
2148
2258
|
end
|
2149
2259
|
|
2260
|
+
|
2150
2261
|
## Extends the Cast class with generation of C text.
|
2151
2262
|
class Cast
|
2152
2263
|
|
@@ -29,7 +29,9 @@ module HDLRuby::Low
|
|
29
29
|
if scope.each_connection.to_a.any? then
|
30
30
|
inputs_blk = Block.new(:par)
|
31
31
|
outputs_blk = Block.new(:par)
|
32
|
-
|
32
|
+
# Timed block is not necessary anymore for initialization.
|
33
|
+
# timed_blk = TimeBlock.new(:seq)
|
34
|
+
timed_blk = Block.new(:seq)
|
33
35
|
scope.each_connection do |connection|
|
34
36
|
# puts "For connection: #{connection}"
|
35
37
|
# Check the left and right of the connection
|
@@ -134,7 +136,9 @@ module HDLRuby::Low
|
|
134
136
|
scope.add_behavior(Behavior.new(outputs_blk))
|
135
137
|
end
|
136
138
|
if timed_blk.each_statement.any? then
|
137
|
-
|
139
|
+
# No more required to be timed.
|
140
|
+
# scope.add_behavior(TimeBehavior.new(timed_blk))
|
141
|
+
scope.add_behavior(Behavior.new(timed_blk))
|
138
142
|
end
|
139
143
|
end
|
140
144
|
end
|
data/lib/HDLRuby/hruby_rcsim.rb
CHANGED
@@ -78,11 +78,13 @@ module HDLRuby::High
|
|
78
78
|
|
79
79
|
|
80
80
|
## Starts the simulation for top system +top+.
|
81
|
-
# NOTE: +name+ is the name of the simulation
|
82
|
-
# the
|
83
|
-
#
|
84
|
-
|
85
|
-
|
81
|
+
# NOTE: +name+ is the name of the simulation, +outpath+ is the path where
|
82
|
+
# the output is to save, and +outmode+ is the output mode as follows:
|
83
|
+
# 0: standard
|
84
|
+
# 1: mute
|
85
|
+
# 2: vcd
|
86
|
+
def self.rcsim(top,name,outpath,outmode)
|
87
|
+
RCSim.rcsim_main(top.rcsystemT,outpath +"/" + name,outmode)
|
86
88
|
end
|
87
89
|
|
88
90
|
|
@@ -741,7 +743,7 @@ module HDLRuby::High
|
|
741
743
|
# Create and add the events.
|
742
744
|
rcevs = []
|
743
745
|
self.right.each_node_deep do |node|
|
744
|
-
if node.is_a?(RefObject) then
|
746
|
+
if node.is_a?(RefObject) && !node.parent.is_a?(RefObject) then
|
745
747
|
ev = RCSim.rcsim_make_event(:anyedge,node.to_rcsim)
|
746
748
|
RCSim.rcsim_set_owner(ev,@rcbehavior)
|
747
749
|
rcevs << ev
|
@@ -786,16 +788,24 @@ module HDLRuby::High
|
|
786
788
|
def to_rcsim
|
787
789
|
# Create the value C object.
|
788
790
|
if self.content.is_a?(::Integer) then
|
789
|
-
|
790
|
-
|
791
|
-
|
791
|
+
# puts "self.type.width=#{self.type.width} and content=#{self.content}" ; $stdout.flush
|
792
|
+
if self.type.width <= 64 then
|
793
|
+
if self.content.bit_length <= 63 then
|
794
|
+
return RCSim.rcsim_make_value_numeric(self.type.to_rcsim,
|
795
|
+
self.content)
|
796
|
+
else
|
797
|
+
return RCSim.rcsim_make_value_numeric(self.type.to_rcsim,
|
798
|
+
self.content & 0xFFFFFFFFFFFF)
|
799
|
+
end
|
792
800
|
else
|
793
|
-
|
794
|
-
|
795
|
-
str
|
796
|
-
|
797
|
-
str =
|
801
|
+
if self.content < 0 then
|
802
|
+
str = (2**self.type.width + self.content).to_s(2)
|
803
|
+
str = "1" * (self.type.width-str.length) + str
|
804
|
+
else
|
805
|
+
str = self.content.to_s(2)
|
806
|
+
str = "0" * (self.type.width-str.length) + str
|
798
807
|
end
|
808
|
+
# puts "now str=#{str} (#{str.length})" ; $stdout.flush
|
799
809
|
return RCSim.rcsim_make_value_bitstring(self.type.to_rcsim,
|
800
810
|
str.reverse)
|
801
811
|
end
|
@@ -945,7 +955,7 @@ module HDLRuby::High
|
|
945
955
|
# RCSim.rcsim_add_refConcat_ref(rcref,ref.to_rcsim)
|
946
956
|
# end
|
947
957
|
if self.each_ref.any? then
|
948
|
-
RCSim.rcsim_add_refConcat_refs(rcref,self.each_ref(&:to_rcsim))
|
958
|
+
RCSim.rcsim_add_refConcat_refs(rcref,self.each_ref.map(&:to_rcsim))
|
949
959
|
end
|
950
960
|
|
951
961
|
return rcref
|
data/lib/HDLRuby/hruby_rsim.rb
CHANGED
@@ -19,6 +19,11 @@ module HDLRuby::High
|
|
19
19
|
# Tell if the simulation is in multithread mode or not.
|
20
20
|
attr_reader :multithread
|
21
21
|
|
22
|
+
## Add untimed objet +obj+
|
23
|
+
def add_untimed(obj)
|
24
|
+
@untimeds << obj
|
25
|
+
end
|
26
|
+
|
22
27
|
## Add timed behavior +beh+.
|
23
28
|
# Returns the id of the timed behavior.
|
24
29
|
def add_timed_behavior(beh)
|
@@ -41,21 +46,32 @@ module HDLRuby::High
|
|
41
46
|
|
42
47
|
## Advance the global simulator.
|
43
48
|
def advance
|
44
|
-
# Display the time
|
45
|
-
self.show_time
|
49
|
+
# # Display the time
|
50
|
+
# self.show_time
|
46
51
|
shown_values = {}
|
47
52
|
# Get the behaviors waiting on activated signals.
|
48
53
|
until @sig_active.empty? do
|
49
|
-
# # Update the signals.
|
50
|
-
# @sig_active.each { |sig| sig.c_value = sig.f_value }
|
51
54
|
# puts "sig_active.size=#{@sig_active.size}"
|
55
|
+
# puts "sig_active=#{@sig_active.map {|sig| sig.fullname}}"
|
52
56
|
# Look for the behavior sensitive to the signals.
|
57
|
+
# @sig_active.each do |sig|
|
58
|
+
# sig.each_anyedge { |beh| @sig_exec << beh }
|
59
|
+
# if (sig.c_value.zero? && !sig.f_value.zero?) then
|
60
|
+
# # puts "sig.c_value=#{sig.c_value.content}"
|
61
|
+
# sig.each_posedge { |beh| @sig_exec << beh }
|
62
|
+
# elsif (!sig.c_value.zero? && sig.f_value.zero?) then
|
63
|
+
# sig.each_negedge { |beh| @sig_exec << beh }
|
64
|
+
# end
|
65
|
+
# end
|
53
66
|
@sig_active.each do |sig|
|
67
|
+
next if (sig.c_value.eql?(sig.f_value))
|
68
|
+
# next if (sig.c_value.to_vstr == sig.f_value.to_vstr)
|
69
|
+
# puts "sig.c_value: #{sig.c_value.to_vstr}, sig.f_value=#{sig.f_value.to_vstr}"
|
54
70
|
sig.each_anyedge { |beh| @sig_exec << beh }
|
55
|
-
if (sig.c_value.zero?
|
71
|
+
if (sig.c_value.zero?) then
|
56
72
|
# puts "sig.c_value=#{sig.c_value.content}"
|
57
73
|
sig.each_posedge { |beh| @sig_exec << beh }
|
58
|
-
elsif (!sig.c_value.zero?
|
74
|
+
elsif (!sig.c_value.zero?) then
|
59
75
|
sig.each_negedge { |beh| @sig_exec << beh }
|
60
76
|
end
|
61
77
|
end
|
@@ -81,6 +97,8 @@ module HDLRuby::High
|
|
81
97
|
# Advance time.
|
82
98
|
@time = (@timed_behaviors.min {|b0,b1| b0.time <=> b1.time }).time
|
83
99
|
end
|
100
|
+
# Display the time
|
101
|
+
self.show_time
|
84
102
|
end
|
85
103
|
|
86
104
|
## Run the simulation from the current systemT and outputs the resuts
|
@@ -95,6 +113,8 @@ module HDLRuby::High
|
|
95
113
|
# Initializes the time and signals execution buffers.
|
96
114
|
@tim_exec = []
|
97
115
|
@sig_exec = []
|
116
|
+
# Initilize the list of untimed objects.
|
117
|
+
@untimeds = []
|
98
118
|
# Initialize the list of currently exisiting timed behavior.
|
99
119
|
@timed_behaviors = []
|
100
120
|
# Initialize the list of activated signals.
|
@@ -107,6 +127,10 @@ module HDLRuby::High
|
|
107
127
|
# Initialize the displayer.
|
108
128
|
self.show_init(simout)
|
109
129
|
|
130
|
+
# Initialize the untimed objects.
|
131
|
+
self.init_untimeds
|
132
|
+
# puts "End of init_untimed."
|
133
|
+
|
110
134
|
# Is there more than one timed behavior.
|
111
135
|
if @total_timed_behaviors <= 1 then
|
112
136
|
# No, no need of multithreading.
|
@@ -205,6 +229,17 @@ module HDLRuby::High
|
|
205
229
|
# Recure on the scope.
|
206
230
|
self.scope.init_sim(systemT)
|
207
231
|
end
|
232
|
+
|
233
|
+
## Initialize the untimed objects.
|
234
|
+
def init_untimeds
|
235
|
+
@untimeds.each do |obj|
|
236
|
+
if obj.is_a?(Behavior) then
|
237
|
+
obj.block.execute(:seq)
|
238
|
+
else
|
239
|
+
obj.execute(:seq)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
208
243
|
|
209
244
|
## Initialize run for executing +ruby_block+
|
210
245
|
def run_init(&ruby_block)
|
@@ -337,6 +372,8 @@ module HDLRuby::High
|
|
337
372
|
|
338
373
|
## Initialize the simulation for system +systemT+.
|
339
374
|
def init_sim(systemT)
|
375
|
+
# Add the behavior to the list of untimed objects.
|
376
|
+
systemT.add_untimed(self)
|
340
377
|
# Process the sensitivity list.
|
341
378
|
# Is it a clocked behavior?
|
342
379
|
events = self.each_event.to_a
|
@@ -351,6 +388,7 @@ module HDLRuby::High
|
|
351
388
|
end.to_a
|
352
389
|
# Keep only one ref per signal.
|
353
390
|
refs.uniq! { |node| node.fullname }
|
391
|
+
# puts "refs=#{refs.map {|node| node.fullname}}"
|
354
392
|
# Remove the inner signals from the list.
|
355
393
|
self.block.each_inner do |inner|
|
356
394
|
refs.delete_if {|r| r.name == inner.name }
|
@@ -516,8 +554,8 @@ module HDLRuby::High
|
|
516
554
|
@f_value = value
|
517
555
|
# Set the mode.
|
518
556
|
@mode = mode
|
519
|
-
# puts "assign #{value.content} (#{value.content.class}) with self.type.width=#{self.type.width} while value.type.width=#{value.type.width}" if self.name.to_s.include?("
|
520
|
-
|
557
|
+
# puts "assign #{value.content} (#{value.content.class}) with self.type.width=#{self.type.width} while value.type.width=#{value.type.width}" if self.name.to_s.include?("xnor")
|
558
|
+
@f_value = value.cast(self.type) # Cast not always inserted by HDLRuby normally
|
521
559
|
end
|
522
560
|
|
523
561
|
## Assigns +value+ at +index+ (integer or range).
|
@@ -667,7 +705,7 @@ module HDLRuby::High
|
|
667
705
|
## Initialize the simulation for system +systemT+.
|
668
706
|
def init_sim(systemT)
|
669
707
|
self.each_when { |wh| wh.init_sim(systemT) }
|
670
|
-
self.default.init_sim(systemT)
|
708
|
+
self.default.init_sim(systemT) if self.default
|
671
709
|
end
|
672
710
|
|
673
711
|
## Executes the statement.
|
@@ -678,7 +716,7 @@ module HDLRuby::High
|
|
678
716
|
return
|
679
717
|
end
|
680
718
|
end
|
681
|
-
|
719
|
+
self.default.execute(mode) if self.default
|
682
720
|
end
|
683
721
|
end
|
684
722
|
end
|
@@ -849,6 +887,8 @@ module HDLRuby::High
|
|
849
887
|
|
850
888
|
## Initialize the simulation for system +systemT+.
|
851
889
|
def init_sim(systemT)
|
890
|
+
# Add the connection to the list of untimed objets.
|
891
|
+
systemT.add_untimed(self)
|
852
892
|
# Recurse on the left.
|
853
893
|
self.left.init_sim(systemT)
|
854
894
|
# Process the sensitivity list.
|
@@ -861,6 +901,8 @@ module HDLRuby::High
|
|
861
901
|
end.to_a
|
862
902
|
# Keep only one ref per signal.
|
863
903
|
refs.uniq! { |node| node.fullname }
|
904
|
+
# puts "connection input: #{self.left.fullname}"
|
905
|
+
# puts "connection refs=#{refs.map {|node| node.fullname}}"
|
864
906
|
# # Generate the event.
|
865
907
|
# events = refs.map {|ref| Event.new(:anyedge,ref) }
|
866
908
|
# # Add them to the behavior for further processing.
|
@@ -872,7 +914,7 @@ module HDLRuby::High
|
|
872
914
|
|
873
915
|
## Executes the statement.
|
874
916
|
def execute(mode)
|
875
|
-
# puts "connection = #{self}"
|
917
|
+
# puts "connection = #{self}" if self.left.is_a?(RefObject) && self.left.object.name.to_s.include?("xnor")
|
876
918
|
self.left.assign(mode,self.right.execute(mode))
|
877
919
|
end
|
878
920
|
end
|
@@ -972,10 +1014,18 @@ module HDLRuby::High
|
|
972
1014
|
class Select
|
973
1015
|
## Execute the expression.
|
974
1016
|
def execute(mode)
|
1017
|
+
unless @mask then
|
1018
|
+
# Need to initialize the execution of the select.
|
1019
|
+
width = (@choices.size-1).width
|
1020
|
+
width = 1 if width == 0
|
1021
|
+
@mask = 2**width - 1
|
1022
|
+
@choices.concat([@choices[-1]] * (2**width-@choices.size))
|
1023
|
+
end
|
975
1024
|
# Recurse on the select.
|
976
|
-
tmps = self.select.execute(mode)
|
1025
|
+
tmps = self.select.execute(mode).to_i & @mask
|
1026
|
+
# puts "select tmps=#{tmps}, @choices.size=#{@choices.size}"
|
977
1027
|
# Recurse on the selection result.
|
978
|
-
return @choices[tmps
|
1028
|
+
return @choices[tmps].execute(mode)
|
979
1029
|
end
|
980
1030
|
end
|
981
1031
|
|