HDLRuby 2.7.11 → 2.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/HDLRuby/hdr_samples/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
|