HDLRuby 2.7.11 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +22 -0
- data/lib/HDLRuby/hdr_samples/adder_gen_gen.rb +40 -0
- data/lib/HDLRuby/hdr_samples/dff_unit.rb +1 -1
- data/lib/HDLRuby/hdr_samples/with_def.rb +29 -0
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +75 -67
- data/lib/HDLRuby/hdr_samples/with_terminate.rb +32 -0
- data/lib/HDLRuby/hdrcc.rb +8 -1
- data/lib/HDLRuby/hruby_high.rb +91 -2
- data/lib/HDLRuby/hruby_low.rb +206 -3
- data/lib/HDLRuby/hruby_low2c.rb +97 -8
- data/lib/HDLRuby/hruby_low2vhd.rb +12 -0
- data/lib/HDLRuby/hruby_low_bool2select.rb +12 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +20 -1
- data/lib/HDLRuby/hruby_low_resolve.rb +1 -1
- data/lib/HDLRuby/hruby_low_without_select.rb +11 -1
- data/lib/HDLRuby/hruby_verilog.rb +9 -1
- data/lib/HDLRuby/sim/hruby_sim.h +23 -1
- data/lib/HDLRuby/sim/hruby_sim_core.c +60 -6
- data/lib/HDLRuby/sim/hruby_sim_vcd.c +1 -1
- data/lib/HDLRuby/std/reconf.rb +3 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90d139cd510b6600a32249a2e27969f6c415a49d9b26ba51ed84d20dcc82f2ba
|
4
|
+
data.tar.gz: b064d08cfbd46ae6fa4dffc7536a2dece4aed9c1c7588118502df79dd288c5bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40ced20f6723ff46f4c02a033c1d194e5ce267c75e7f2c22e6c70dd6f51ae9b530ebdc7dc7150970f3fefbf2ec4663c965a3a3fddf1c1b2369d6dac42317ba0c
|
7
|
+
data.tar.gz: 7782898ea6de9b5e42015f84dc56929ecd038baf42337c1f69f96bc644f0692ddd00ada0db0f9910b8ae7d93d2516ed4b3819c9f8735268d0a952f72b56bb37e
|
@@ -5,3 +5,25 @@ system :adder do |w|
|
|
5
5
|
|
6
6
|
s <= x.as(bit[w+1]) + y
|
7
7
|
end
|
8
|
+
|
9
|
+
|
10
|
+
# Testing the generic adder.
|
11
|
+
system :adder_bench do
|
12
|
+
width = 4
|
13
|
+
[width].inner :x,:y
|
14
|
+
[width+1].inner :z
|
15
|
+
|
16
|
+
adder(width).(:my_adder).(x,y,z)
|
17
|
+
|
18
|
+
timed do
|
19
|
+
x <= 0
|
20
|
+
y <= 0
|
21
|
+
!10.ns
|
22
|
+
x <= 1
|
23
|
+
!10.ns
|
24
|
+
y <= 1
|
25
|
+
!10.ns
|
26
|
+
x <= 15
|
27
|
+
!10.ns
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# A simple generic adder
|
2
|
+
system :adder do |w|
|
3
|
+
[(w-1)..0].input :i,:j
|
4
|
+
[w..0].output :k
|
5
|
+
|
6
|
+
k <= i.as(bit[w+1]) + j
|
7
|
+
end
|
8
|
+
|
9
|
+
# A module embedding two generic adders.
|
10
|
+
system :two_adders do |w|
|
11
|
+
[w*2].input :x, :y
|
12
|
+
[(w+1)*2].output :z
|
13
|
+
|
14
|
+
adder(w).(:adderI0).(x[(w-1)..0],y[(w-1)..0],z[w..0])
|
15
|
+
adder(w).(:adderI1).(x[(w*2-1)..w],y[(w*2-1)..w],z[(w*2+1)..(w+1)])
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Testing the generic adder.
|
20
|
+
system :adder_bench do
|
21
|
+
width = 4
|
22
|
+
[width*2].inner :a,:b
|
23
|
+
[(width+1)*2].inner :c
|
24
|
+
|
25
|
+
two_adders(width).(:my_adders).(a,b,c)
|
26
|
+
|
27
|
+
timed do
|
28
|
+
a <= 0
|
29
|
+
b <= 0
|
30
|
+
!10.ns
|
31
|
+
a <= 1
|
32
|
+
!10.ns
|
33
|
+
b <= 1
|
34
|
+
!10.ns
|
35
|
+
a <= 255
|
36
|
+
!10.ns
|
37
|
+
b <= 128
|
38
|
+
!10.ns
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# A test of def.
|
2
|
+
def lut84(content,addr)
|
3
|
+
bit[8][-4].inner tbl? => content.to_a
|
4
|
+
tbl![addr]
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
# A benchmark for testing the initialization of signals.
|
9
|
+
system :def_bench do
|
10
|
+
|
11
|
+
[2].inner :addr
|
12
|
+
[8].inner :val0, :val1
|
13
|
+
|
14
|
+
par do
|
15
|
+
val0 <= lut84([0,1,4,9],addr)
|
16
|
+
val1 <= lut84([0,1,4,9],3-addr)
|
17
|
+
end
|
18
|
+
|
19
|
+
timed do
|
20
|
+
addr <= 0
|
21
|
+
!10.ns
|
22
|
+
addr <= 1
|
23
|
+
!10.ns
|
24
|
+
addr <= 2
|
25
|
+
!10.ns
|
26
|
+
addr <= 3
|
27
|
+
!10.ns
|
28
|
+
end
|
29
|
+
end
|
@@ -4,60 +4,16 @@ include HDLRuby::High::Std
|
|
4
4
|
|
5
5
|
|
6
6
|
|
7
|
-
|
8
|
-
# Implementation of a vivado partial reconfiguration system.
|
9
|
-
reconf(:vivado_reconf) do |clk,rst|
|
10
|
-
|
11
|
-
# Get access to the interface of the reconfigurable component.
|
12
|
-
inputs = each_input
|
13
|
-
outputs = each_output
|
14
|
-
inouts = each_inout
|
15
|
-
|
16
|
-
# Create the main system with the interface and a channel for
|
17
|
-
# handling the reconfiguration.
|
18
|
-
main = system do
|
19
|
-
# Declares the inputs.
|
20
|
-
inputs.each do |i|
|
21
|
-
i.type.input(i.name)
|
22
|
-
end
|
23
|
-
# Declares the outputs.
|
24
|
-
outputs.each do |o|
|
25
|
-
o.type.output(o.name)
|
26
|
-
end
|
27
|
-
# Declares the inouts.
|
28
|
-
inouts.each do |io|
|
29
|
-
io.type.inout(io.name)
|
30
|
-
end
|
31
|
-
# An that's all: in vivado the main system is to be a black-box.
|
32
|
-
end
|
33
|
-
|
34
|
-
# And set it as the main system.
|
35
|
-
set_main(main)
|
36
|
-
|
37
|
-
# The switching circuit.
|
38
|
-
# reconfer = vivado_reconfigurer :do_reconf # Will be that later
|
39
|
-
# reconfer.clk <= clk
|
40
|
-
# reconfer.rst <= rst
|
41
|
-
reconfer = proc do |idx|
|
42
|
-
puts "Instantiating reconfiguration circuits with #{idx}"
|
43
|
-
end
|
44
|
-
|
45
|
-
# Defines the reconfiguring procedure: switch to system idx.
|
46
|
-
switcher do |idx,ruby_block|
|
47
|
-
reconfer.call(idx)
|
48
|
-
ruby_block.call
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
# Some system that can be used for recponfiguration.
|
7
|
+
# Some system that can be used for reconfiguration.
|
55
8
|
system :sys0 do
|
56
9
|
input :clk,:rst
|
57
10
|
input :d
|
58
11
|
output :q
|
59
12
|
|
60
|
-
|
13
|
+
par(clk.posedge) do
|
14
|
+
hprint("sys0\n")
|
15
|
+
q <= d & ~rst
|
16
|
+
end
|
61
17
|
end
|
62
18
|
|
63
19
|
system :sys1 do
|
@@ -65,7 +21,10 @@ system :sys1 do
|
|
65
21
|
input :d
|
66
22
|
output :q
|
67
23
|
|
68
|
-
(
|
24
|
+
par(clk.posedge, rst.posedge) do
|
25
|
+
hprint("sys1\n")
|
26
|
+
q <= d & ~rst
|
27
|
+
end
|
69
28
|
end
|
70
29
|
|
71
30
|
system :sys2 do
|
@@ -73,7 +32,10 @@ system :sys2 do
|
|
73
32
|
input :d
|
74
33
|
output :q
|
75
34
|
|
76
|
-
(
|
35
|
+
par(clk.posedge, rst.negedge) do
|
36
|
+
hprint("sys2\n")
|
37
|
+
q <= d & ~rst
|
38
|
+
end
|
77
39
|
end
|
78
40
|
|
79
41
|
# A system with a reconfifurable part.
|
@@ -81,23 +43,69 @@ system :with_reconf do
|
|
81
43
|
input :clk,:rst
|
82
44
|
input :d
|
83
45
|
output :q
|
84
|
-
[2].input :conf # The configuration number
|
85
|
-
|
86
|
-
inner :wait_reconf
|
87
46
|
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
47
|
+
# Instantiate the default configuration.
|
48
|
+
sys0(:my_dff).(clk,rst,d,q)
|
49
|
+
|
50
|
+
# Adds the additional configuration.
|
51
|
+
my_dff.choice(conf1: sys1, conf2: sys2)
|
52
|
+
|
53
|
+
timed do
|
54
|
+
clk <= 0
|
55
|
+
rst <= 0
|
56
|
+
d <= 0
|
57
|
+
!10.ns
|
58
|
+
clk <= 1
|
59
|
+
!10.ns
|
60
|
+
clk <= 0
|
61
|
+
rst <= 1
|
62
|
+
!10.ns
|
63
|
+
clk <= 1
|
64
|
+
!10.ns
|
65
|
+
clk <= 0
|
66
|
+
rst <= 0
|
67
|
+
!10.ns
|
68
|
+
3.times do |i|
|
69
|
+
clk <= 1
|
70
|
+
!10.ns
|
71
|
+
clk <= 0
|
72
|
+
d <= 1
|
73
|
+
!10.ns
|
74
|
+
clk <= 1
|
75
|
+
!10.ns
|
76
|
+
clk <= 0
|
77
|
+
d <= 0
|
78
|
+
!10.ns
|
79
|
+
clk <= 1
|
80
|
+
my_dff.configure((i+1)%3)
|
81
|
+
!10.ns
|
82
|
+
clk <= 0
|
83
|
+
!10.ns
|
101
84
|
end
|
85
|
+
clk <= 1
|
86
|
+
!10.ns
|
87
|
+
clk <= 0
|
88
|
+
d <= 1
|
89
|
+
!10.ns
|
90
|
+
clk <= 1
|
91
|
+
my_dff.configure(:conf1)
|
92
|
+
!10.ns
|
93
|
+
clk <= 0
|
94
|
+
d <= 0
|
95
|
+
!10.ns
|
96
|
+
clk <= 1
|
97
|
+
my_dff.configure(:conf2)
|
98
|
+
!10.ns
|
99
|
+
clk <= 0
|
100
|
+
d <= 1
|
101
|
+
!10.ns
|
102
|
+
clk <= 1
|
103
|
+
my_dff.configure(:my_dff)
|
104
|
+
!10.ns
|
105
|
+
clk <= 0
|
106
|
+
d <= 0
|
107
|
+
!10.ns
|
108
|
+
clk <= 1
|
109
|
+
!10.ns
|
102
110
|
end
|
103
111
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
# A benchmark for testing the terminate statement.
|
3
|
+
system :with_terminate do
|
4
|
+
[8].constant cst0: 127
|
5
|
+
constant cst1: _1
|
6
|
+
[8].inner sig0: _10000000
|
7
|
+
inner sig1: _1
|
8
|
+
[8].inner :sig2
|
9
|
+
[8].inner count: 0
|
10
|
+
|
11
|
+
timed do
|
12
|
+
!20.ns
|
13
|
+
100.times do
|
14
|
+
count <= count + 1
|
15
|
+
!20.ns
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
timed do
|
20
|
+
!10.ns
|
21
|
+
sig2 <= cst0 + cst1
|
22
|
+
sig0 <= sig0 + sig1
|
23
|
+
!10.ns
|
24
|
+
sig2 <= sig2 + sig1
|
25
|
+
!10.ns
|
26
|
+
terminate
|
27
|
+
sig0 <= sig0 + sig0
|
28
|
+
!10.ns
|
29
|
+
sig0 <= sig0 + sig0
|
30
|
+
!10.ns
|
31
|
+
end
|
32
|
+
end
|
data/lib/HDLRuby/hdrcc.rb
CHANGED
@@ -647,12 +647,19 @@ elsif $options[:clang] then
|
|
647
647
|
init_visualizer = $options[:vcd] ? "init_vcd_visualizer" :
|
648
648
|
"init_default_visualizer"
|
649
649
|
|
650
|
+
# Gather the system to generate and sort them in the right order
|
651
|
+
# to ensure references are generated before being used.
|
652
|
+
# Base: reverse order of the tree.
|
653
|
+
# Then, multiple configuration of a system instance must be
|
654
|
+
# reverversed so that the base configuration is generated first.
|
655
|
+
c_systems = $top_system.each_systemT_deep_ref
|
650
656
|
# Generate the code of the main function.
|
651
657
|
# HDLRuby start code
|
652
658
|
$main << HDLRuby::Low::Low2C.main("hruby_simulator",
|
653
659
|
init_visualizer,
|
654
660
|
$top_system,
|
655
|
-
|
661
|
+
c_systems,
|
662
|
+
$hnames)
|
656
663
|
$main.close
|
657
664
|
|
658
665
|
$top_system.each_systemT_deep do |systemT|
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -2119,6 +2119,54 @@ module HDLRuby::High
|
|
2119
2119
|
self.eigen_extend(@systemT.public_namespace)
|
2120
2120
|
end
|
2121
2121
|
|
2122
|
+
# Adds alternative system +systemT+
|
2123
|
+
def choice(configuration = {})
|
2124
|
+
# Process the argument.
|
2125
|
+
configuration.each do |k,v|
|
2126
|
+
k = k.to_sym
|
2127
|
+
unless v.is_a?(SystemT) then
|
2128
|
+
raise "Invalid class for a system type: #{v.class}"
|
2129
|
+
end
|
2130
|
+
# Create an eigen system.
|
2131
|
+
eigen = v.instantiate(HDLRuby.uniq_name(self.name)).systemT
|
2132
|
+
# Ensure its interface corresponds.
|
2133
|
+
my_signals = self.each_signal.to_a
|
2134
|
+
if (eigen.each_signal.with_index.find { |sig,i|
|
2135
|
+
!sig.eql?(my_signals[i])
|
2136
|
+
}) then
|
2137
|
+
raise "Invalid system for configuration: #{systemT.name}."
|
2138
|
+
end
|
2139
|
+
# Add it.
|
2140
|
+
# At the HDLRuby::High level
|
2141
|
+
@choices = { self.name => self.systemT } unless @choices
|
2142
|
+
@choices[k] = eigen
|
2143
|
+
# At the HDLRuby::Low level
|
2144
|
+
self.add_systemT(eigen)
|
2145
|
+
end
|
2146
|
+
end
|
2147
|
+
|
2148
|
+
# (Re)Configuration of system instance to systemT designated by +sys+.
|
2149
|
+
# +sys+ may be the index or the name of the configuration, the first
|
2150
|
+
# configuration being named by the systemI name.
|
2151
|
+
def configure(sys)
|
2152
|
+
if sys.respond_to?(:to_i) then
|
2153
|
+
# The argument is an index.
|
2154
|
+
# Create the (re)configuration node.
|
2155
|
+
High.top_user.add_statement(
|
2156
|
+
Configure.new(RefObject.new(RefThis.new,self),sys.to_i))
|
2157
|
+
else
|
2158
|
+
# The argument is a name (should be).
|
2159
|
+
# Get the index corresponding to the name.
|
2160
|
+
num = @choices.find_index { |k,_| k == sys.to_sym }
|
2161
|
+
unless num then
|
2162
|
+
raise "Invalid name for configuration: #{sys.to_s}"
|
2163
|
+
end
|
2164
|
+
# Create the (re)configuration node.
|
2165
|
+
High.top_user.add_statement(
|
2166
|
+
Configure.new(RefObject.new(RefThis.new,self),num))
|
2167
|
+
end
|
2168
|
+
end
|
2169
|
+
|
2122
2170
|
# include Hmissing
|
2123
2171
|
|
2124
2172
|
# Missing methods are looked for in the public namespace of the
|
@@ -2155,8 +2203,11 @@ module HDLRuby::High
|
|
2155
2203
|
# systemIL.properties[:low2high] = self.hdr_id
|
2156
2204
|
# self.properties[:high2low] = systemIL
|
2157
2205
|
# Adds the other systemTs.
|
2158
|
-
self.each_systemT do |
|
2159
|
-
|
2206
|
+
self.each_systemT do |systemTc|
|
2207
|
+
if systemTc != self.systemT
|
2208
|
+
systemTcL = systemTc.to_low
|
2209
|
+
systemIL.add_systemT(systemTcL)
|
2210
|
+
end
|
2160
2211
|
end
|
2161
2212
|
return systemIL
|
2162
2213
|
end
|
@@ -2433,6 +2484,18 @@ module HDLRuby::High
|
|
2433
2484
|
end
|
2434
2485
|
end
|
2435
2486
|
|
2487
|
+
##
|
2488
|
+
# Describes a timed terminate statement: not synthesizable!
|
2489
|
+
class TimeTerminate < Low::TimeTerminate
|
2490
|
+
include HStatement
|
2491
|
+
|
2492
|
+
# Converts the repeat statement to HDLRuby::Low.
|
2493
|
+
def to_low
|
2494
|
+
return HDLRuby::Low::TimeTerminate.new
|
2495
|
+
end
|
2496
|
+
end
|
2497
|
+
|
2498
|
+
|
2436
2499
|
|
2437
2500
|
##
|
2438
2501
|
# Module giving high-level expression properties
|
@@ -3369,6 +3432,27 @@ module HDLRuby::High
|
|
3369
3432
|
end
|
3370
3433
|
|
3371
3434
|
|
3435
|
+
##
|
3436
|
+
# Describes a systemI (re)configure statement: not synthesizable!
|
3437
|
+
class Configure < Low::Configure
|
3438
|
+
High = HDLRuby::High
|
3439
|
+
|
3440
|
+
include HStatement
|
3441
|
+
|
3442
|
+
# Creates a new (re)configure statement for system instance refered
|
3443
|
+
# by +ref+ with system number +num+.
|
3444
|
+
def initialize(ref,num)
|
3445
|
+
super(ref,num)
|
3446
|
+
end
|
3447
|
+
|
3448
|
+
# Converts the connection to HDLRuby::Low.
|
3449
|
+
def to_low
|
3450
|
+
return HDLRuby::Low::Configure.new(self.ref.to_low, self.index)
|
3451
|
+
end
|
3452
|
+
|
3453
|
+
end
|
3454
|
+
|
3455
|
+
|
3372
3456
|
##
|
3373
3457
|
# Describes a connection.
|
3374
3458
|
class Connection < Low::Connection
|
@@ -3802,6 +3886,11 @@ module HDLRuby::High
|
|
3802
3886
|
def hprint(*args)
|
3803
3887
|
self.add_statement(Print.new(*args))
|
3804
3888
|
end
|
3889
|
+
|
3890
|
+
# Terminate the simulation.
|
3891
|
+
def terminate
|
3892
|
+
self.add_statement(TimeTerminate.new)
|
3893
|
+
end
|
3805
3894
|
end
|
3806
3895
|
|
3807
3896
|
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -165,6 +165,22 @@ module HDLRuby::Low
|
|
165
165
|
|
166
166
|
|
167
167
|
|
168
|
+
# Handling the (re)configuration.
|
169
|
+
|
170
|
+
# Gets the configuration wrapper if any.
|
171
|
+
def wrapper
|
172
|
+
return defined? @wrapper ? @wrapper : nil
|
173
|
+
end
|
174
|
+
|
175
|
+
# Sets the configuration wrapper to +systemT+.
|
176
|
+
def wrapper=(systemT)
|
177
|
+
unless systemT.is_a?(SystemT) then
|
178
|
+
raise "Invalid class for a wrapper system type: #{systemT}."
|
179
|
+
end
|
180
|
+
@wrapper = systemT
|
181
|
+
end
|
182
|
+
|
183
|
+
|
168
184
|
# Handling the signals.
|
169
185
|
|
170
186
|
# Adds input +signal+.
|
@@ -432,6 +448,27 @@ module HDLRuby::Low
|
|
432
448
|
end
|
433
449
|
end
|
434
450
|
end
|
451
|
+
|
452
|
+
# Iterates over the systemT deeply if any in order of reference
|
453
|
+
# to ensure the refered elements are processed first.
|
454
|
+
#
|
455
|
+
# Returns an enumerator if no ruby block is given.
|
456
|
+
def each_systemT_deep_ref(&ruby_block)
|
457
|
+
# No ruby block? Return an enumerator.
|
458
|
+
return to_enum(:each_systemT_deep_ref) unless ruby_block
|
459
|
+
# A ruby block?
|
460
|
+
# Recurse on the systemT accessible through the instances.
|
461
|
+
self.scope.each_scope_deep do |scope|
|
462
|
+
scope.each_systemI do |systemI|
|
463
|
+
# systemI.systemT.each_systemT_deep(&ruby_block)
|
464
|
+
systemI.each_systemT do |systemT|
|
465
|
+
systemT.each_systemT_deep_ref(&ruby_block)
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
# Finally apply it to current.
|
470
|
+
ruby_block.call(self)
|
471
|
+
end
|
435
472
|
end
|
436
473
|
|
437
474
|
|
@@ -2500,8 +2537,8 @@ module HDLRuby::Low
|
|
2500
2537
|
# NOTE: an instance can actually represented muliple layers
|
2501
2538
|
# of systems, the first one being the one actually instantiated
|
2502
2539
|
# in the final RTL code.
|
2503
|
-
# This
|
2504
|
-
#
|
2540
|
+
# This layering can be used for describing software or partial
|
2541
|
+
# (re)configuration.
|
2505
2542
|
class SystemI
|
2506
2543
|
|
2507
2544
|
include Hparent
|
@@ -2564,13 +2601,16 @@ module HDLRuby::Low
|
|
2564
2601
|
@name = name.to_sym
|
2565
2602
|
end
|
2566
2603
|
|
2567
|
-
## Adds a system
|
2604
|
+
## Adds a system configuration.
|
2568
2605
|
def add_systemT(systemT)
|
2569
2606
|
# puts "add_systemT #{systemT.name} to systemI #{self.name}"
|
2570
2607
|
# Check and add the systemT.
|
2571
2608
|
if !systemT.is_a?(SystemT) then
|
2572
2609
|
raise AnyError, "Invalid class for a system type: #{systemT.class}"
|
2573
2610
|
end
|
2611
|
+
# Set the base configuration of the added system.
|
2612
|
+
systemT.wrapper = self.systemT
|
2613
|
+
# Add it.
|
2574
2614
|
@systemTs << systemT
|
2575
2615
|
end
|
2576
2616
|
|
@@ -3781,6 +3821,93 @@ module HDLRuby::Low
|
|
3781
3821
|
end
|
3782
3822
|
end
|
3783
3823
|
end
|
3824
|
+
end
|
3825
|
+
|
3826
|
+
|
3827
|
+
##
|
3828
|
+
# Describes a system instance (re)configuration statement: not synthesizable!
|
3829
|
+
class Configure < Statement
|
3830
|
+
|
3831
|
+
# attr_reader :systemI, :systemT, :index
|
3832
|
+
attr_reader :ref, :index
|
3833
|
+
|
3834
|
+
# Creates a new (re)configure statement of system instance refered by
|
3835
|
+
# +ref+ with system number +index+
|
3836
|
+
def initialize(ref,index)
|
3837
|
+
super()
|
3838
|
+
# Process the arguments.
|
3839
|
+
index = index.to_i
|
3840
|
+
unless ref.is_a?(Ref) then
|
3841
|
+
raise "Invalid class for a reference: #{ref.class}."
|
3842
|
+
end
|
3843
|
+
# Sets the arguments.
|
3844
|
+
@ref = ref
|
3845
|
+
ref.parent = self
|
3846
|
+
@index = index
|
3847
|
+
# @systemT = systemI.each_systemT.to_a[index]
|
3848
|
+
# # Check the systemT is valid.
|
3849
|
+
# unless @systemT then
|
3850
|
+
# raise "Invalid configuration index: #{index}."
|
3851
|
+
# end
|
3852
|
+
end
|
3853
|
+
|
3854
|
+
# Comparison for hash: structural comparison.
|
3855
|
+
def eql?(obj)
|
3856
|
+
return false unless obj.is_a?(Configure)
|
3857
|
+
return false unless @ref.eql?(obj.ref)
|
3858
|
+
return false unless @index.eql?(obj.index)
|
3859
|
+
return true
|
3860
|
+
end
|
3861
|
+
|
3862
|
+
# Iterates over each object deeply.
|
3863
|
+
#
|
3864
|
+
# Returns an enumerator if no ruby block is given.
|
3865
|
+
def each_deep(&ruby_block)
|
3866
|
+
# No ruby block? Return an enumerator.
|
3867
|
+
return to_enum(:each_deep) unless ruby_block
|
3868
|
+
# A ruby block? First apply it to current.
|
3869
|
+
ruby_block.call(self)
|
3870
|
+
# Then apply on the reference.
|
3871
|
+
@ref.each_deep(&ruby_block)
|
3872
|
+
end
|
3873
|
+
|
3874
|
+
# Hash function.
|
3875
|
+
def hash
|
3876
|
+
return (@ref.hash + @index.hash).hash
|
3877
|
+
end
|
3878
|
+
|
3879
|
+
# Clones (deeply)
|
3880
|
+
def clone
|
3881
|
+
return Configure.new(@ref.clone,@index)
|
3882
|
+
end
|
3883
|
+
|
3884
|
+
# Iterates over the nodes deeply if any.
|
3885
|
+
def each_node_deep(&ruby_block)
|
3886
|
+
# No ruby block? Return an enumerator.
|
3887
|
+
return to_enum(:each_node_deep) unless ruby_block
|
3888
|
+
# A ruby block? First apply it to current.
|
3889
|
+
ruby_block.call(self)
|
3890
|
+
# And recurse on the reference.
|
3891
|
+
@ref.each_node_deep(&ruby_block)
|
3892
|
+
end
|
3893
|
+
|
3894
|
+
# Iterates over all the blocks contained in the current block.
|
3895
|
+
def each_block_deep(&ruby_block)
|
3896
|
+
# No ruby block? Return an enumerator.
|
3897
|
+
return to_enum(:each_block_deep) unless ruby_block
|
3898
|
+
# A ruby block?
|
3899
|
+
# Nothing more to do anyway.
|
3900
|
+
end
|
3901
|
+
|
3902
|
+
# Iterates over all the statements contained in the current block.
|
3903
|
+
def each_statement_deep(&ruby_block)
|
3904
|
+
# No ruby block? Return an enumerator.
|
3905
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
3906
|
+
# A ruby block?
|
3907
|
+
# Apply it on self.
|
3908
|
+
ruby_block.call(self)
|
3909
|
+
# And that's all.
|
3910
|
+
end
|
3784
3911
|
|
3785
3912
|
end
|
3786
3913
|
|
@@ -3989,6 +4116,82 @@ module HDLRuby::Low
|
|
3989
4116
|
end
|
3990
4117
|
|
3991
4118
|
|
4119
|
+
##
|
4120
|
+
# Describes a timed terminate statement: not synthesizable!
|
4121
|
+
class TimeTerminate < Statement
|
4122
|
+
|
4123
|
+
# Creates a new timed terminate statement that terminate execution.
|
4124
|
+
def initialize
|
4125
|
+
super()
|
4126
|
+
end
|
4127
|
+
|
4128
|
+
# Iterates over each object deeply.
|
4129
|
+
#
|
4130
|
+
# Returns an enumerator if no ruby block is given.
|
4131
|
+
def each_deep(&ruby_block)
|
4132
|
+
# No ruby block? Return an enumerator.
|
4133
|
+
return to_enum(:each_deep) unless ruby_block
|
4134
|
+
# A ruby block? First apply it to current.
|
4135
|
+
ruby_block.call(self)
|
4136
|
+
# And that's all.
|
4137
|
+
end
|
4138
|
+
|
4139
|
+
# Iterates over all the nodes.
|
4140
|
+
def each_node(&ruby_block)
|
4141
|
+
# No ruby block? Return an enumerator.
|
4142
|
+
return to_enum(:each_node) unless ruby_block
|
4143
|
+
# A ruby block?
|
4144
|
+
# Nothing to do anyway.
|
4145
|
+
end
|
4146
|
+
|
4147
|
+
# Iterates over all the nodes deeply.
|
4148
|
+
def each_node_deep(&ruby_block)
|
4149
|
+
# No ruby block? Return an enumerator.
|
4150
|
+
return to_enum(:each_node_deep) unless ruby_block
|
4151
|
+
# A ruby block?
|
4152
|
+
# Apply of current node.
|
4153
|
+
ruby_block.call(self)
|
4154
|
+
# And that's all.
|
4155
|
+
end
|
4156
|
+
|
4157
|
+
# Iterates over all the statements deeply.
|
4158
|
+
def each_statement_deep(&ruby_block)
|
4159
|
+
# No ruby block? Return an enumerator.
|
4160
|
+
return to_enum(:each_statement_deep) unless ruby_block
|
4161
|
+
# A ruby block?
|
4162
|
+
# Apply of current node.
|
4163
|
+
ruby_block.call(self)
|
4164
|
+
# And that's all.
|
4165
|
+
end
|
4166
|
+
|
4167
|
+
# Iterates over all the blocks contained in the current block.
|
4168
|
+
def each_block_deep(&ruby_block)
|
4169
|
+
# No ruby block? Return an enumerator.
|
4170
|
+
return to_enum(:each_block_deep) unless ruby_block
|
4171
|
+
# A ruby block?
|
4172
|
+
# Nothing to do anyway.
|
4173
|
+
end
|
4174
|
+
|
4175
|
+
# Comparison for hash: structural comparison.
|
4176
|
+
def eql?(obj)
|
4177
|
+
return false unless obj.is_a?(TimeTerminate)
|
4178
|
+
return true
|
4179
|
+
end
|
4180
|
+
|
4181
|
+
# Hash function.
|
4182
|
+
def hash
|
4183
|
+
return TimeTerminate.hash
|
4184
|
+
end
|
4185
|
+
|
4186
|
+
# Clones the TimeRepeat (deeply)
|
4187
|
+
def clone
|
4188
|
+
return TimeTerminate.new
|
4189
|
+
end
|
4190
|
+
end
|
4191
|
+
|
4192
|
+
|
4193
|
+
|
4194
|
+
|
3992
4195
|
##
|
3993
4196
|
# Describes a block.
|
3994
4197
|
class Block < Statement
|
data/lib/HDLRuby/hruby_low2c.rb
CHANGED
@@ -135,6 +135,8 @@ module HDLRuby::Low
|
|
135
135
|
objs.each { |obj| res << " " << Low2C.make_name(obj) << "();\n" }
|
136
136
|
# Sets the top systemT.
|
137
137
|
res << " top_system = " << Low2C.obj_name(top) << ";\n"
|
138
|
+
# Enable it.
|
139
|
+
res << " set_enable_system(top_system,1);\n"
|
138
140
|
# Starts the simulation.
|
139
141
|
res<< " hruby_sim_core(\"#{name}\",#{init_visualizer},-1);\n"
|
140
142
|
# Close the main.
|
@@ -170,6 +172,7 @@ module HDLRuby::Low
|
|
170
172
|
# is the list of extra h files to include.
|
171
173
|
# def to_c(level = 0, *hnames)
|
172
174
|
def to_c(res, level = 0, *hnames)
|
175
|
+
# puts "SystemT.to_c with name=#{Low2C.obj_name(self)}#{@wrapper ? " and wrapper=#{Low2C.obj_name(@wrapper)}" : ""}"
|
173
176
|
# The header
|
174
177
|
# res = Low2C.includes(*hnames)
|
175
178
|
res << Low2C.includes(*hnames)
|
@@ -179,7 +182,16 @@ module HDLRuby::Low
|
|
179
182
|
|
180
183
|
# Generate the signals of the system.
|
181
184
|
# self.each_signal { |signal| signal.to_c(level) }
|
182
|
-
|
185
|
+
if ((defined? @wrapper) && @wrapper) then
|
186
|
+
# It is a reconfiguring system, alias the signals.
|
187
|
+
wrap_signals = @wrapper.each_signal.to_a
|
188
|
+
self.each_signal.with_index do |signal,i|
|
189
|
+
signal.to_c_alias(res,wrap_signals[i],level)
|
190
|
+
end
|
191
|
+
else
|
192
|
+
# It is a single system, default generation.
|
193
|
+
self.each_signal { |signal| signal.to_c(res,level) }
|
194
|
+
end
|
183
195
|
|
184
196
|
# Generate the code for all the blocks included in the system.
|
185
197
|
self.scope.each_scope_deep do |scope|
|
@@ -686,6 +698,10 @@ module HDLRuby::Low
|
|
686
698
|
res << "behavior->owner = NULL;\n"
|
687
699
|
end
|
688
700
|
|
701
|
+
# Set the behavior as not enabled. */
|
702
|
+
res << " " * (level+1)*3
|
703
|
+
res << "behavior->enabled = 0;\n"
|
704
|
+
|
689
705
|
# Set the behavior as inactive. */
|
690
706
|
res << " " * (level+1)*3
|
691
707
|
res << "behavior->activated = 0;\n"
|
@@ -842,11 +858,8 @@ module HDLRuby::Low
|
|
842
858
|
# +level+ is the hierachical level of the object.
|
843
859
|
# def to_c(level = 0)
|
844
860
|
def to_c(res,level = 0)
|
845
|
-
#
|
846
|
-
# res = ""
|
847
|
-
|
861
|
+
# puts "Signal.to_c with name: #{Low2C.obj_name(self)}"
|
848
862
|
# Declare the global variable holding the signal.
|
849
|
-
# res << "SignalI #{self.to_c_signal(level+1)};\n\n"
|
850
863
|
res << "SignalI "
|
851
864
|
self.to_c_signal(res,level+1)
|
852
865
|
res << ";\n\n"
|
@@ -854,6 +867,7 @@ module HDLRuby::Low
|
|
854
867
|
# The header of the signal generation.
|
855
868
|
res << " " * level*3
|
856
869
|
res << "SignalI " << Low2C.make_name(self) << "() {\n"
|
870
|
+
|
857
871
|
# res << " " * level*3
|
858
872
|
# res << "Value l,r,d;\n"
|
859
873
|
# res << " " * (level+1)*3
|
@@ -866,7 +880,6 @@ module HDLRuby::Low
|
|
866
880
|
# Sets the global variable of the signal.
|
867
881
|
res << "\n"
|
868
882
|
res << " " * (level+1)*3
|
869
|
-
# res << "#{self.to_c_signal(level+1)} = signalI;\n"
|
870
883
|
self.to_c_signal(res,level+1)
|
871
884
|
res << " = signalI;\n"
|
872
885
|
|
@@ -958,6 +971,43 @@ module HDLRuby::Low
|
|
958
971
|
|
959
972
|
return res;
|
960
973
|
end
|
974
|
+
|
975
|
+
## Generates the C text of the equivalent HDLRuby code in case
|
976
|
+
# the signals is actually an alias to another signal.
|
977
|
+
# +other+ is the target signal of the alias.
|
978
|
+
# +level+ is the hierachical level of the object.
|
979
|
+
def to_c_alias(res,target,level = 0)
|
980
|
+
# puts "Signal.to_c_alias with name: #{Low2C.obj_name(self)}"
|
981
|
+
# The resulting string.
|
982
|
+
# res = ""
|
983
|
+
|
984
|
+
# Declare the global variable holding the signal.
|
985
|
+
res << "SignalI "
|
986
|
+
self.to_c_signal(res,level+1)
|
987
|
+
res << ";\n\n"
|
988
|
+
|
989
|
+
# The header of the signal generation.
|
990
|
+
res << " " * level*3
|
991
|
+
res << "SignalI " << Low2C.make_name(self) << "() {\n"
|
992
|
+
|
993
|
+
res << "SignalI signalI = #{Low2C.obj_name(target)};\n"
|
994
|
+
|
995
|
+
# Sets the global variable of the signal.
|
996
|
+
res << "\n"
|
997
|
+
res << " " * (level+1)*3
|
998
|
+
self.to_c_signal(res,level+1)
|
999
|
+
res << " = signalI;\n"
|
1000
|
+
|
1001
|
+
# Generate the return of the signal.
|
1002
|
+
res << "\n"
|
1003
|
+
res << " " * (level+1)*3
|
1004
|
+
res << "return signalI;\n"
|
1005
|
+
|
1006
|
+
# Close the signal.
|
1007
|
+
res << " " * level*3
|
1008
|
+
res << "};\n\n"
|
1009
|
+
return res
|
1010
|
+
end
|
961
1011
|
end
|
962
1012
|
|
963
1013
|
|
@@ -999,9 +1049,22 @@ module HDLRuby::Low
|
|
999
1049
|
# Set the name
|
1000
1050
|
res << " " * (level+1)*3
|
1001
1051
|
res << "systemI->name = \"#{self.name}\";\n"
|
1002
|
-
# Set the type.
|
1052
|
+
# # Set the type.
|
1053
|
+
# res << " " * (level+1)*3
|
1054
|
+
# res << "systemI->system = " << Low2C.obj_name(self.systemT) << ";\n"
|
1055
|
+
# Set the systems.
|
1056
|
+
num_sys = self.each_systemT.to_a.size
|
1003
1057
|
res << " " * (level+1)*3
|
1004
|
-
res << "systemI->
|
1058
|
+
res << "systemI->num_systems = #{num_sys};\n"
|
1059
|
+
res << " " * (level+1)*3
|
1060
|
+
res << "systemI->systems = calloc(sizeof(SystemT), #{num_sys});\n"
|
1061
|
+
self.each_systemT.with_index do |sysT,i|
|
1062
|
+
res << " " * (level+1)*3
|
1063
|
+
res << "systemI->systems[#{i}] = #{Low2C.obj_name(sysT)};\n"
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
# Configure the instance to current systemT.
|
1067
|
+
res << (" " * (level*3)) << "configure(systemI,0);\n"
|
1005
1068
|
|
1006
1069
|
# Generate the return of the signal.
|
1007
1070
|
res << "\n"
|
@@ -1100,6 +1163,10 @@ module HDLRuby::Low
|
|
1100
1163
|
res << "code->owner = NULL;\n"
|
1101
1164
|
end
|
1102
1165
|
|
1166
|
+
# Set the code as enabled (for now, may change in a near future). */
|
1167
|
+
res << " " * (level+1)*3
|
1168
|
+
res << "code->enabled = 1;\n"
|
1169
|
+
|
1103
1170
|
# Set the code as inactive. */
|
1104
1171
|
res << " " * (level+1)*3
|
1105
1172
|
res << "code->activated = 0;\n"
|
@@ -1392,6 +1459,28 @@ module HDLRuby::Low
|
|
1392
1459
|
end
|
1393
1460
|
end
|
1394
1461
|
|
1462
|
+
## Extends the TimeTerminate class with generation of C text.
|
1463
|
+
class TimeTerminate
|
1464
|
+
|
1465
|
+
# Generates the C text of the equivalent HDLRuby code.
|
1466
|
+
# +level+ is the hierachical level of the object.
|
1467
|
+
def to_c(res,level = 0)
|
1468
|
+
# Save the value pool state.
|
1469
|
+
res << (" " * (level*3)) << "terminate();\n"
|
1470
|
+
end
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
## Extends the Configure class with generation of C text.
|
1474
|
+
class Configure
|
1475
|
+
|
1476
|
+
# Generates the C text of the equivalent HDLRuby code.
|
1477
|
+
# +level+ is the hierachical level of the object.
|
1478
|
+
def to_c(res,level = 0)
|
1479
|
+
# Save the value pool state.
|
1480
|
+
res << (" " * (level*3)) << "configure(#{Low2C.obj_name(self.ref.resolve)},#{self.index});\n"
|
1481
|
+
end
|
1482
|
+
end
|
1483
|
+
|
1395
1484
|
|
1396
1485
|
## Extends the If class with generation of C text.
|
1397
1486
|
class If
|
@@ -925,6 +925,18 @@ module HDLRuby::Low
|
|
925
925
|
end.join(" & ") + ";\n"
|
926
926
|
end
|
927
927
|
end
|
928
|
+
|
929
|
+
## Extends the TimeTerminate class with generation of HDLRuby::High text.
|
930
|
+
class TimeTerminate
|
931
|
+
|
932
|
+
# Generates the text of the equivalent HDLRuby::High code.
|
933
|
+
# +vars+ is the list of the variables and
|
934
|
+
# +level+ is the hierachical level of the object.
|
935
|
+
def to_vhdl(vars,level = 0)
|
936
|
+
# Generate a report statement.
|
937
|
+
return " " * (level*3) + "finish;\n"
|
938
|
+
end
|
939
|
+
end
|
928
940
|
|
929
941
|
## Extends the If class with generation of HDLRuby::High text.
|
930
942
|
class If
|
@@ -75,6 +75,18 @@ module HDLRuby::Low
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
|
79
|
+
## Extends the TimeTerminate class with functionality for converting booleans
|
80
|
+
# in assignments to select operators.
|
81
|
+
class TimeTerminate
|
82
|
+
|
83
|
+
# Converts booleans in assignments to select operators.
|
84
|
+
def boolean_in_assign2select!
|
85
|
+
# Nothing to do.
|
86
|
+
return self
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
78
90
|
|
79
91
|
## Extends the If class with functionality for converting booleans
|
80
92
|
# in assignments to select operators.
|
@@ -71,7 +71,7 @@ module HDLRuby::Low
|
|
71
71
|
class Statement
|
72
72
|
# Explicit the types conversions in the statement.
|
73
73
|
def explicit_types!
|
74
|
-
raise "Should implement explicit_types for class #{self.class}."
|
74
|
+
raise "Should implement explicit_types! for class #{self.class}."
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -98,7 +98,26 @@ module HDLRuby::Low
|
|
98
98
|
self.map_args!(&:explicit_types)
|
99
99
|
return self
|
100
100
|
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
## Extends the Configure class with fixing of types and constants.
|
105
|
+
class Configure
|
106
|
+
# Explicit the types conversions in the statement.
|
107
|
+
def explicit_types!
|
108
|
+
# Nothing to do.
|
109
|
+
return self
|
110
|
+
end
|
111
|
+
end
|
101
112
|
|
113
|
+
|
114
|
+
## Extends the TimeTerminate class with fixing of types and constants.
|
115
|
+
class TimeTerminate
|
116
|
+
# Explicit the types conversions in the statement.
|
117
|
+
def explicit_types!
|
118
|
+
# Nothing to do.
|
119
|
+
return self
|
120
|
+
end
|
102
121
|
end
|
103
122
|
|
104
123
|
|
@@ -163,7 +163,7 @@ module HDLRuby::Low
|
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
166
|
-
## Extends the
|
166
|
+
## Extends the Print class with functionality for converting select
|
167
167
|
# expressions to case statements.
|
168
168
|
class Print
|
169
169
|
# Extract the Select expressions.
|
@@ -175,6 +175,16 @@ module HDLRuby::Low
|
|
175
175
|
return selects
|
176
176
|
end
|
177
177
|
end
|
178
|
+
|
179
|
+
## Extends the TimeTerminate class with functionality for converting select
|
180
|
+
# expressions to case statements.
|
181
|
+
class TimeTerminate
|
182
|
+
# Extract the Select expressions.
|
183
|
+
def extract_selects!
|
184
|
+
# Nothing to extract.
|
185
|
+
return []
|
186
|
+
end
|
187
|
+
end
|
178
188
|
|
179
189
|
## Extends the If class with functionality for converting select
|
180
190
|
# expressions to case statements.
|
@@ -171,7 +171,7 @@ module HDLRuby::Low
|
|
171
171
|
|
172
172
|
# Enhance Print with generation of verilog code.
|
173
173
|
class Print
|
174
|
-
# Converts the
|
174
|
+
# Converts the print to Verilog code.
|
175
175
|
def to_verilog(spc = 3)
|
176
176
|
code = "#{" " * spc}$write(#{self.each_arg.map do |arg|
|
177
177
|
arg.to_verilog
|
@@ -180,6 +180,14 @@ module HDLRuby::Low
|
|
180
180
|
end
|
181
181
|
end
|
182
182
|
|
183
|
+
# Enhance TimeTerminate with generation of verilog code.
|
184
|
+
class TimeTerminate
|
185
|
+
# Converts the terminate to Verilog code.
|
186
|
+
def to_verilog(spc = 3)
|
187
|
+
return "#{" " * spc}$finish;"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
183
191
|
# To scheduling to the Block.
|
184
192
|
# Enhance Block with generation of verilog code.
|
185
193
|
class Block
|
data/lib/HDLRuby/sim/hruby_sim.h
CHANGED
@@ -467,7 +467,10 @@ typedef struct SystemIS_ {
|
|
467
467
|
Object owner; /* The owner if any. */
|
468
468
|
|
469
469
|
char* name; /* The name of the signal. */
|
470
|
-
SystemT system; /* The instantiated system. */
|
470
|
+
SystemT system; /* The currently instantiated system. */
|
471
|
+
|
472
|
+
int num_systems; /* The number of systems possibly instantiated here. */
|
473
|
+
SystemT* systems; /* The systems possibly instantiated here. */
|
471
474
|
} SystemIS;
|
472
475
|
|
473
476
|
|
@@ -499,6 +502,8 @@ typedef struct BehaviorS_ {
|
|
499
502
|
Event* events; /* The events of the behavior. */
|
500
503
|
Block block; /* The block of the behavior. */
|
501
504
|
|
505
|
+
int enabled; /* Tells if the behavior is enabled or not. */
|
506
|
+
|
502
507
|
int activated; /* Tells if the behavior is activated or not. */
|
503
508
|
|
504
509
|
int timed; /* Tell if the behavior is timed or not:
|
@@ -519,6 +524,8 @@ typedef struct CodeS_ {
|
|
519
524
|
Event* events; /* The events of the behavior. */
|
520
525
|
void (*function)(); /* The function to execute for the code. */
|
521
526
|
|
527
|
+
int enabled; /* Tells if the behavior is enabled or not. */
|
528
|
+
|
522
529
|
int activated; /* Tells if the code is activated or not. */
|
523
530
|
} CodeS;
|
524
531
|
|
@@ -623,6 +630,16 @@ extern unsigned long long make_delay(int value, Unit unit);
|
|
623
630
|
* @param func function to applie on each signal. */
|
624
631
|
extern void each_all_signal(void (*func)(SignalI));
|
625
632
|
|
633
|
+
|
634
|
+
/** Configure a system instance.
|
635
|
+
* @param systemI the system instance to configure.
|
636
|
+
* @param idx the index of the target system. */
|
637
|
+
extern void configure(SystemI systemI, int idx);
|
638
|
+
|
639
|
+
|
640
|
+
/** Terminates the simulation. */
|
641
|
+
extern void terminate();
|
642
|
+
|
626
643
|
/* Interface to the visualization engine. */
|
627
644
|
|
628
645
|
typedef struct {
|
@@ -701,6 +718,11 @@ extern void init_vcd_visualizer(char* name);
|
|
701
718
|
|
702
719
|
/* The interface to the simulator core. */
|
703
720
|
|
721
|
+
/** Sets the enable status of the behaviors of a system type.
|
722
|
+
* @param systemT the system type to process.
|
723
|
+
* @param status the enable status. */
|
724
|
+
extern void set_enable_system(SystemT systemT, int status);
|
725
|
+
|
704
726
|
/** The simulation core function.
|
705
727
|
* @param name the name of the simulation.
|
706
728
|
* @param init_vizualizer the vizualizer engine initializer.
|
@@ -253,8 +253,8 @@ void hruby_sim_update_signals() {
|
|
253
253
|
if (obj->kind == BEHAVIOR) {
|
254
254
|
/* Behavior case. */
|
255
255
|
Behavior beh = (Behavior)obj;
|
256
|
-
/* Is the code really activated? */
|
257
|
-
if (beh->activated) {
|
256
|
+
/* Is the code really enabled and activated? */
|
257
|
+
if (beh->enabled && beh->activated) {
|
258
258
|
/* Yes, execute it. */
|
259
259
|
beh->block->function();
|
260
260
|
/* And deactivate it. */
|
@@ -264,7 +264,7 @@ void hruby_sim_update_signals() {
|
|
264
264
|
/* Other code case. */
|
265
265
|
Code cod = (Code)obj;
|
266
266
|
/* Is the code really activated? */
|
267
|
-
if (cod->activated) {
|
267
|
+
if (cod->enabled && cod->activated) {
|
268
268
|
/* Yes, execute it. */
|
269
269
|
cod->function();
|
270
270
|
/* And deactivate it. */
|
@@ -294,6 +294,35 @@ void hruby_sim_advance_time() {
|
|
294
294
|
}
|
295
295
|
|
296
296
|
|
297
|
+
/** Sets the enamble status of the behaviors of a scope.
|
298
|
+
* @param scope the scope to process.
|
299
|
+
* @param status the enable status. */
|
300
|
+
static void set_enable_scope(Scope scope, int status) {
|
301
|
+
int i;
|
302
|
+
int num_beh = scope->num_behaviors;
|
303
|
+
Behavior* behs = scope->behaviors;
|
304
|
+
int num_scp = scope->num_scopes;
|
305
|
+
Scope* scps = scope->scopes;
|
306
|
+
|
307
|
+
/* Enable the behaviors. */
|
308
|
+
for(i=0; i<num_beh; ++i) {
|
309
|
+
behs[i]->enabled = status;
|
310
|
+
}
|
311
|
+
|
312
|
+
/* Recurse on the sub scopes. */
|
313
|
+
for(i=0; i<num_scp; ++i) {
|
314
|
+
set_enable_scope(scps[i],status);
|
315
|
+
}
|
316
|
+
}
|
317
|
+
|
318
|
+
/** Sets the enable status of the behaviors of a system type.
|
319
|
+
* @param systemT the system type to process.
|
320
|
+
* @param status the enable status. */
|
321
|
+
void set_enable_system(SystemT systemT, int status) {
|
322
|
+
set_enable_scope(systemT->scope,status);
|
323
|
+
}
|
324
|
+
|
325
|
+
|
297
326
|
/** Activates a behavior.
|
298
327
|
* @param behavior the behavior to activate. */
|
299
328
|
void activate_behavior(Behavior behavior) {
|
@@ -359,7 +388,8 @@ void* behavior_run(void* arg) {
|
|
359
388
|
pthread_mutex_unlock(&hruby_sim_mutex);
|
360
389
|
// printf("#2\n");
|
361
390
|
/* Now can start the execution of the behavior. */
|
362
|
-
behavior->
|
391
|
+
if (behavior->enabled)
|
392
|
+
behavior->block->function();
|
363
393
|
// printf("#3\n");
|
364
394
|
/* Now can start the execution of the behavior. */
|
365
395
|
/* Stops the behavior. */
|
@@ -635,11 +665,35 @@ unsigned long long make_delay(int value, Unit unit) {
|
|
635
665
|
|
636
666
|
|
637
667
|
|
638
|
-
|
639
|
-
*
|
668
|
+
/** Iterates over all the signals.
|
669
|
+
* @param func function to applie on each signal. */
|
640
670
|
void each_all_signal(void (*func)(SignalI)) {
|
641
671
|
int i;
|
642
672
|
for(i = 0; i<num_all_signals; ++i) {
|
643
673
|
func(all_signals[i]);
|
644
674
|
}
|
645
675
|
}
|
676
|
+
|
677
|
+
|
678
|
+
/** Configure a system instance.
|
679
|
+
* @param systemI the system instance to configure.
|
680
|
+
* @param idx the index of the target system. */
|
681
|
+
void configure(SystemI systemI, int idx) {
|
682
|
+
int i;
|
683
|
+
// printf("Configure to: %i\n",idx);
|
684
|
+
/* Sets the current system type. */
|
685
|
+
systemI->system = systemI->systems[idx];
|
686
|
+
/* Disable all the behaviors of the system instance. */
|
687
|
+
for(i=0; i<systemI->num_systems; ++i) {
|
688
|
+
if (i != idx)
|
689
|
+
set_enable_system(systemI->systems[i],0);
|
690
|
+
}
|
691
|
+
/* Enable the current system. */
|
692
|
+
set_enable_system(systemI->systems[idx],1);
|
693
|
+
}
|
694
|
+
|
695
|
+
|
696
|
+
/** Terminates the simulation. */
|
697
|
+
void terminate() {
|
698
|
+
exit(0);
|
699
|
+
}
|
@@ -85,7 +85,7 @@ static void vcd_print_name(Object object) {
|
|
85
85
|
vcd_print("%s",name);
|
86
86
|
} else {
|
87
87
|
/* No name, use the address of the object as name generator.*/
|
88
|
-
vcd_print("$%p",(void*)object);
|
88
|
+
vcd_print("x$%p",(void*)object);
|
89
89
|
}
|
90
90
|
break;
|
91
91
|
default: /* Nothing to do */
|
data/lib/HDLRuby/std/reconf.rb
CHANGED
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.
|
4
|
+
version: 2.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/HDLRuby/hdr_samples/adder_assign_error.rb
|
77
77
|
- lib/HDLRuby/hdr_samples/adder_bench.rb
|
78
78
|
- lib/HDLRuby/hdr_samples/adder_gen.rb
|
79
|
+
- lib/HDLRuby/hdr_samples/adder_gen_gen.rb
|
79
80
|
- lib/HDLRuby/hdr_samples/adder_kadai.rb
|
80
81
|
- lib/HDLRuby/hdr_samples/adder_nodef_error.rb
|
81
82
|
- lib/HDLRuby/hdr_samples/addsub.rb
|
@@ -150,6 +151,7 @@ files:
|
|
150
151
|
- lib/HDLRuby/hdr_samples/with_connector.rb
|
151
152
|
- lib/HDLRuby/hdr_samples/with_connector_memory.rb
|
152
153
|
- lib/HDLRuby/hdr_samples/with_decoder.rb
|
154
|
+
- lib/HDLRuby/hdr_samples/with_def.rb
|
153
155
|
- lib/HDLRuby/hdr_samples/with_fixpoint.rb
|
154
156
|
- lib/HDLRuby/hdr_samples/with_fsm.rb
|
155
157
|
- lib/HDLRuby/hdr_samples/with_function_generator.rb
|
@@ -165,6 +167,7 @@ files:
|
|
165
167
|
- lib/HDLRuby/hdr_samples/with_ref_array.rb
|
166
168
|
- lib/HDLRuby/hdr_samples/with_str2value.rb
|
167
169
|
- lib/HDLRuby/hdr_samples/with_subsums.rb
|
170
|
+
- lib/HDLRuby/hdr_samples/with_terminate.rb
|
168
171
|
- lib/HDLRuby/hdr_samples/with_to_a.rb
|
169
172
|
- lib/HDLRuby/hdr_samples/with_to_array.rb
|
170
173
|
- lib/HDLRuby/hdr_samples/with_values.rb
|