HDLRuby 2.1.2 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/HDLRuby.gemspec +4 -2
- data/README.md +84 -25
- data/lib/HDLRuby/hdr_samples/mei8.rb +2 -2
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/with_channel.rb +11 -13
- data/lib/HDLRuby/hdr_samples/with_memory.rb +123 -0
- data/lib/HDLRuby/hdrcc.rb +62 -55
- data/lib/HDLRuby/high_samples/with_top_unshift.rb +29 -0
- data/lib/HDLRuby/high_samples/with_unshift.rb +25 -0
- data/lib/HDLRuby/hruby_high.rb +120 -10
- data/lib/HDLRuby/hruby_low.rb +32 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +5 -1
- data/lib/HDLRuby/hruby_verilog.rb +1 -1
- data/lib/HDLRuby/std/channel.rb +488 -111
- data/lib/HDLRuby/std/memory.rb +328 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +11 -8
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'HDLRuby'
|
2
|
+
|
3
|
+
configure_high
|
4
|
+
|
5
|
+
|
6
|
+
# A example of behavior with some unshifted statements in the top block
|
7
|
+
# of a behavior.
|
8
|
+
system :with_top_unshift do
|
9
|
+
[15..0].input :x,:y, :clk
|
10
|
+
[16..0].inner :w0,:w1
|
11
|
+
[16..0].output :o
|
12
|
+
|
13
|
+
seq(clk.posedge) do
|
14
|
+
w0 <= x + y
|
15
|
+
par do
|
16
|
+
w1 <= w0 * x
|
17
|
+
top_block.unshift { o <= w1 + y }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Instantiate it for checking.
|
23
|
+
with_top_unshift :with_top_unshiftI
|
24
|
+
|
25
|
+
# Generate the low level representation.
|
26
|
+
low = with_top_unshiftI.systemT.to_low
|
27
|
+
|
28
|
+
# Displays it
|
29
|
+
puts low.to_yaml
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'HDLRuby'
|
2
|
+
|
3
|
+
configure_high
|
4
|
+
|
5
|
+
|
6
|
+
# A example of behavior with some unshifted statements in a block.
|
7
|
+
system :with_unshift do
|
8
|
+
[15..0].input :x,:y, :clk
|
9
|
+
[16..0].inner :w
|
10
|
+
[16..0].output :o
|
11
|
+
|
12
|
+
seq(clk.posedge) do
|
13
|
+
w <= x + y
|
14
|
+
unshift { o <= w + y }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Instantiate it for checking.
|
19
|
+
with_unshift :with_unshiftI
|
20
|
+
|
21
|
+
# Generate the low level representation.
|
22
|
+
low = with_unshiftI.systemT.to_low
|
23
|
+
|
24
|
+
# Displays it
|
25
|
+
puts low.to_yaml
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -1187,6 +1187,11 @@ module HDLRuby::High
|
|
1187
1187
|
end
|
1188
1188
|
|
1189
1189
|
|
1190
|
+
# Gets the current system.
|
1191
|
+
def cur_system
|
1192
|
+
return HDLRuby::High.cur_system
|
1193
|
+
end
|
1194
|
+
|
1190
1195
|
include Hmux
|
1191
1196
|
|
1192
1197
|
# Fills a low level scope with self's contents.
|
@@ -2321,6 +2326,41 @@ module HDLRuby::High
|
|
2321
2326
|
return Cast.new(type.to_type,self.to_expr)
|
2322
2327
|
end
|
2323
2328
|
|
2329
|
+
# Casts to a bit vector type.
|
2330
|
+
def to_bit
|
2331
|
+
return self.as(bit[self.width])
|
2332
|
+
end
|
2333
|
+
|
2334
|
+
# Casts to an unsigned bit vector type.
|
2335
|
+
def to_unsigned
|
2336
|
+
return self.as(unsigned[self.width])
|
2337
|
+
end
|
2338
|
+
|
2339
|
+
# Casts to a signed bit vector type.
|
2340
|
+
def to_unsigned
|
2341
|
+
return self.as(signed[self.width])
|
2342
|
+
end
|
2343
|
+
|
2344
|
+
# Extends on the left to +n+ bits filling with +v+ bit values.
|
2345
|
+
def ljust(n,v)
|
2346
|
+
return [(v.to_s * (n-self.width)).to_expr, self]
|
2347
|
+
end
|
2348
|
+
|
2349
|
+
# Extends on the right to +n+ bits filling with +v+ bit values.
|
2350
|
+
def rjust(n,v)
|
2351
|
+
return [self, (v.to_s * (n-self.width)).to_expr]
|
2352
|
+
end
|
2353
|
+
|
2354
|
+
# Extends on the left to +n+ bits filling with 0.
|
2355
|
+
def zext(n)
|
2356
|
+
return self.ljust(n,0)
|
2357
|
+
end
|
2358
|
+
|
2359
|
+
# Extends on the left to +n+ bits preserving the signe.
|
2360
|
+
def sext(n)
|
2361
|
+
return self.ljust(self[-1])
|
2362
|
+
end
|
2363
|
+
|
2324
2364
|
# Gets the origin method for operation +op+.
|
2325
2365
|
def self.orig_operator(op)
|
2326
2366
|
return (op.to_s + "_orig").to_sym
|
@@ -2342,6 +2382,26 @@ module HDLRuby::High
|
|
2342
2382
|
define_method(orig_operator(operator),&meth)
|
2343
2383
|
end
|
2344
2384
|
|
2385
|
+
# Left shift of +n+ bits.
|
2386
|
+
def ls(n)
|
2387
|
+
return self << n
|
2388
|
+
end
|
2389
|
+
|
2390
|
+
# Right shift of +n+ bits.
|
2391
|
+
def rs(n)
|
2392
|
+
return self >> n
|
2393
|
+
end
|
2394
|
+
|
2395
|
+
# Left rotate of +n+ bits.
|
2396
|
+
def lr(n)
|
2397
|
+
return [self[-(n+1)..0], self[-1..-(n)]]
|
2398
|
+
end
|
2399
|
+
|
2400
|
+
# Right rotate of +n+ bits.
|
2401
|
+
def rr(n)
|
2402
|
+
return [self[(n-1)..0], self[-1..n]]
|
2403
|
+
end
|
2404
|
+
|
2345
2405
|
# Coerce by forcing convertion of obj to expression.
|
2346
2406
|
def coerce(obj)
|
2347
2407
|
if obj.is_a?(HDLRuby::Low::Expression) then
|
@@ -2806,10 +2866,10 @@ module HDLRuby::High
|
|
2806
2866
|
return High.cur_behavior
|
2807
2867
|
end
|
2808
2868
|
|
2809
|
-
# Gets the enclosing block if any.
|
2810
|
-
def block
|
2811
|
-
|
2812
|
-
end
|
2869
|
+
# # Gets the enclosing block if any.
|
2870
|
+
# def block
|
2871
|
+
# return High.cur_block
|
2872
|
+
# end
|
2813
2873
|
|
2814
2874
|
# Converts the this reference to HDLRuby::Low.
|
2815
2875
|
def to_low
|
@@ -3182,13 +3242,50 @@ module HDLRuby::High
|
|
3182
3242
|
self.add_block(self.mode,name,&ruby_block)
|
3183
3243
|
end
|
3184
3244
|
|
3185
|
-
#
|
3186
|
-
|
3187
|
-
|
3188
|
-
|
3189
|
-
|
3245
|
+
# Adds statements at the top of the block.
|
3246
|
+
def unshift(&ruby_block)
|
3247
|
+
# Create a sub block for the statements.
|
3248
|
+
block = High.make_block(self.mode,:"",&ruby_block)
|
3249
|
+
# Unshifts it.
|
3250
|
+
self.unshift_statement(block)
|
3251
|
+
# Use its return value.
|
3252
|
+
return block.return_value
|
3190
3253
|
end
|
3191
3254
|
|
3255
|
+
# # Get the current mode of the block.
|
3256
|
+
# #
|
3257
|
+
# # NOTE: for name coherency purpose only.
|
3258
|
+
# def block
|
3259
|
+
# return self.mode
|
3260
|
+
# end
|
3261
|
+
|
3262
|
+
# Gets the current block.
|
3263
|
+
def cur_block
|
3264
|
+
return HDLRuby::High.cur_block
|
3265
|
+
end
|
3266
|
+
|
3267
|
+
# Gets the top block of the current behavior.
|
3268
|
+
def top_block
|
3269
|
+
return HDLRuby::High.top_block
|
3270
|
+
end
|
3271
|
+
|
3272
|
+
# Gets the current behavior.
|
3273
|
+
def cur_behavior
|
3274
|
+
return HDLRuby::High.cur_behavior
|
3275
|
+
end
|
3276
|
+
|
3277
|
+
# Gets the current scope.
|
3278
|
+
def cur_scope
|
3279
|
+
return HDLRuby::High.cur_scope
|
3280
|
+
end
|
3281
|
+
|
3282
|
+
# Gets the current system.
|
3283
|
+
def cur_system
|
3284
|
+
return HDLRuby::High.cur_system
|
3285
|
+
end
|
3286
|
+
|
3287
|
+
|
3288
|
+
|
3192
3289
|
# Need to be able to declare select operators
|
3193
3290
|
include Hmux
|
3194
3291
|
|
@@ -3624,7 +3721,6 @@ module HDLRuby::High
|
|
3624
3721
|
end
|
3625
3722
|
end
|
3626
3723
|
|
3627
|
-
|
3628
3724
|
# Gets the enclosing block if any.
|
3629
3725
|
#
|
3630
3726
|
# NOTE: +level+ allows to get an upper block of the currently enclosing
|
@@ -3640,6 +3736,20 @@ module HDLRuby::High
|
|
3640
3736
|
end
|
3641
3737
|
end
|
3642
3738
|
|
3739
|
+
# Gets the top enclosing block if any.
|
3740
|
+
def self.top_block(level = 0)
|
3741
|
+
blk = cur_block(level)
|
3742
|
+
unless blk.is_a?(Block)
|
3743
|
+
raise AnyError,
|
3744
|
+
"Not within a block: #{blk.user.class}"
|
3745
|
+
end
|
3746
|
+
if Namespaces[-1-level-1].user.is_a?(Scope) then
|
3747
|
+
return blk
|
3748
|
+
else
|
3749
|
+
return top_block(level+1)
|
3750
|
+
end
|
3751
|
+
end
|
3752
|
+
|
3643
3753
|
# Registers hardware referencing method +name+ to the current namespace.
|
3644
3754
|
def self.space_reg(name,&ruby_block)
|
3645
3755
|
# print "registering #{name} in #{Namespaces[-1]}\n"
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -3495,6 +3495,24 @@ module HDLRuby::Low
|
|
3495
3495
|
statement
|
3496
3496
|
end
|
3497
3497
|
|
3498
|
+
# Adds a +statement+ and the begining of the block
|
3499
|
+
#
|
3500
|
+
# NOTE: TimeWait is not supported unless for TimeBlock objects.
|
3501
|
+
def unshift_statement(statement)
|
3502
|
+
unless statement.is_a?(Statement) then
|
3503
|
+
raise AnyError,
|
3504
|
+
"Invalid class for a statement: #{statement.class}"
|
3505
|
+
end
|
3506
|
+
if statement.is_a?(TimeWait) then
|
3507
|
+
raise AnyError,
|
3508
|
+
"Timed statements are not supported in common blocks."
|
3509
|
+
end
|
3510
|
+
@statements.unshift(statement)
|
3511
|
+
# And set its parent.
|
3512
|
+
statement.parent = self
|
3513
|
+
statement
|
3514
|
+
end
|
3515
|
+
|
3498
3516
|
# Gets the number of statements.
|
3499
3517
|
def num_statements
|
3500
3518
|
return @statements.size
|
@@ -3620,6 +3638,20 @@ module HDLRuby::Low
|
|
3620
3638
|
statement
|
3621
3639
|
end
|
3622
3640
|
|
3641
|
+
# Adds a +statement+ and the begining of the block
|
3642
|
+
#
|
3643
|
+
# NOTE: TimeWait is not supported unless for TimeBlock objects.
|
3644
|
+
def unshift_statement(statement)
|
3645
|
+
unless statement.is_a?(Statement) then
|
3646
|
+
raise AnyError,
|
3647
|
+
"Invalid class for a statement: #{statement.class}"
|
3648
|
+
end
|
3649
|
+
@statements.unshift(statement)
|
3650
|
+
# And set its parent.
|
3651
|
+
statement.parent = self
|
3652
|
+
statement
|
3653
|
+
end
|
3654
|
+
|
3623
3655
|
# Comparison for hash: structural comparison.
|
3624
3656
|
def eql?(obj)
|
3625
3657
|
return false unless obj.is_a?(TimeBlock)
|
@@ -1100,7 +1100,11 @@ module HDLRuby::Low
|
|
1100
1100
|
# when Numeric
|
1101
1101
|
# return self.content.to_s
|
1102
1102
|
when HDLRuby::BitString
|
1103
|
-
|
1103
|
+
# Compute the extension: in case of signed type, the extension
|
1104
|
+
# is the last bit. Otherwise it is 0 unless the last bit
|
1105
|
+
# is not defined (Z or X).
|
1106
|
+
sign = self.type.signed? ? self.content.to_s[-1] :
|
1107
|
+
/[01]/ =~ self.content[-1] ? "0" : self.content[-1]
|
1104
1108
|
return '"' + self.content.to_s.rjust(width,sign).upcase + '"'
|
1105
1109
|
else
|
1106
1110
|
sign = self.type.signed? ? (self.content>=0 ? "0" : "1") : "0"
|
data/lib/HDLRuby/std/channel.rb
CHANGED
@@ -18,7 +18,8 @@ module HDLRuby::High::Std
|
|
18
18
|
@name = name.to_sym
|
19
19
|
# Sets the block for instantiating a channel.
|
20
20
|
@ruby_block = ruby_block
|
21
|
-
# Sets the instantiation procedure.
|
21
|
+
# Sets the instantiation procedure if named.
|
22
|
+
return if @name.empty?
|
22
23
|
obj = self
|
23
24
|
HDLRuby::High.space_reg(@name) do |*args|
|
24
25
|
obj.instantiate(*args)
|
@@ -42,11 +43,12 @@ module HDLRuby::High::Std
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
# Generates the channels.
|
46
|
+
channelI = nil
|
45
47
|
args.each do |nameI|
|
46
48
|
channelI = ChannelI.new(name,&@ruby_block)
|
47
49
|
HDLRuby::High.space_reg(nameI) { channelI }
|
48
|
-
channelI
|
49
50
|
end
|
51
|
+
channelI
|
50
52
|
end
|
51
53
|
|
52
54
|
alias_method :call, :instantiate
|
@@ -55,11 +57,172 @@ module HDLRuby::High::Std
|
|
55
57
|
|
56
58
|
## Creates a new channel type named +name+ whose instances are
|
57
59
|
# creating executing +ruby_block+.
|
58
|
-
def channel(name,&ruby_block)
|
60
|
+
def self.channel(name,&ruby_block)
|
59
61
|
return ChannelT.new(name,&ruby_block)
|
60
62
|
end
|
61
63
|
|
64
|
+
## Creates a new channel type named +name+ whose instances are
|
65
|
+
# creating executing +ruby_block+.
|
66
|
+
def channel(name,&ruby_block)
|
67
|
+
HDLRuby::High::Std.channel(name,&ruby_block)
|
68
|
+
end
|
69
|
+
|
70
|
+
## Creates directly an instance of channel named +name+ using
|
71
|
+
# +ruby_block+ built with +args+.
|
72
|
+
def self.channel_instance(name,*args,&ruby_block)
|
73
|
+
return ChannelT.new(:"",&ruby_block).instantiate(name,*args)
|
74
|
+
end
|
75
|
+
|
76
|
+
## Creates directly an instance of channel named +name+ using
|
77
|
+
# +ruby_block+ built with +args+.
|
78
|
+
def channel_instance(name,*args,&ruby_block)
|
79
|
+
HDLRuby::High::Std.channel_instance(name,*args,&ruby_block)
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
##
|
84
|
+
# Describes a read port to a channel.
|
85
|
+
class ChannelPortR
|
86
|
+
|
87
|
+
# Creates a new channel reader running in +namespace+ and
|
88
|
+
# reading using +reader_proc+ and reseting using +reseter_proc+.
|
89
|
+
def initialize(namespace,reader_proc,reseter_proc)
|
90
|
+
unless namespace.is_a?(Namespace)
|
91
|
+
raise "Invalid class for a namespace: #{namespace.class}"
|
92
|
+
end
|
93
|
+
@namespace = namespace
|
94
|
+
@reader_proc = reader_proc.to_proc
|
95
|
+
@rester_proc = reseter_proc.to_proc
|
96
|
+
end
|
97
|
+
|
98
|
+
## Performs a read on the channel using +args+ and +ruby_block+
|
99
|
+
# as arguments.
|
100
|
+
def read(*args,&ruby_block)
|
101
|
+
# Gain access to the reader as local variable.
|
102
|
+
reader_proc = @reader_proc
|
103
|
+
# Execute the code generating the accesser in context.
|
104
|
+
HDLRuby::High.space_push(@namespace)
|
105
|
+
HDLRuby::High.cur_block.open do
|
106
|
+
instance_exec(ruby_block,*args,&reader_proc)
|
107
|
+
end
|
108
|
+
HDLRuby::High.space_pop
|
109
|
+
end
|
110
|
+
|
111
|
+
## Performs a reset on the channel using +args+ and +ruby_block+
|
112
|
+
# as arguments.
|
113
|
+
def reset(*args,&ruby_block)
|
114
|
+
# Gain access to the accesser as local variable.
|
115
|
+
reseter_proc = @reseter_proc
|
116
|
+
# Execute the code generating the accesser in context.
|
117
|
+
HDLRuby::High.space_push(@namespace)
|
118
|
+
HDLRuby::High.cur_block.open do
|
119
|
+
instance_exec(ruby_block,*args,&reseter_proc)
|
120
|
+
end
|
121
|
+
HDLRuby::High.space_pop
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
##
|
127
|
+
# Describes a writer port to a channel.
|
128
|
+
class ChannelPortW
|
129
|
+
|
130
|
+
# Creates a new channel writer running in +namespace+ and
|
131
|
+
# writing using +writer_proc+ and reseting using +reseter_proc+.
|
132
|
+
def initialize(namespace,writer_proc,reseter_proc)
|
133
|
+
unless namespace.is_a?(Namespace)
|
134
|
+
raise "Invalid class for a namespace: #{namespace.class}"
|
135
|
+
end
|
136
|
+
@namespace = namespace
|
137
|
+
@writer_proc = writer_proc.to_proc
|
138
|
+
@reseter_proc = reseter_proc.to_proc
|
139
|
+
end
|
140
|
+
|
141
|
+
## Performs a write on the channel using +args+ and +ruby_block+
|
142
|
+
# as arguments.
|
143
|
+
def write(*args,&ruby_block)
|
144
|
+
# Gain access to the writer as local variable.
|
145
|
+
writer_proc = @writer_proc
|
146
|
+
# Execute the code generating the accesser in context.
|
147
|
+
HDLRuby::High.space_push(@namespace)
|
148
|
+
HDLRuby::High.cur_block.open do
|
149
|
+
instance_exec(ruby_block,*args,&writer_proc)
|
150
|
+
end
|
151
|
+
HDLRuby::High.space_pop
|
152
|
+
end
|
153
|
+
|
154
|
+
## Performs a reset on the channel using +args+ and +ruby_block+
|
155
|
+
# as arguments.
|
156
|
+
def reset(*args,&ruby_block)
|
157
|
+
# Gain access to the accesser as local variable.
|
158
|
+
reseter_proc = @reseter_proc
|
159
|
+
# Execute the code generating the accesser in context.
|
160
|
+
HDLRuby::High.space_push(@namespace)
|
161
|
+
HDLRuby::High.cur_block.open do
|
162
|
+
instance_exec(ruby_block,*args,&reseter_proc)
|
163
|
+
end
|
164
|
+
HDLRuby::High.space_pop
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
|
62
169
|
|
170
|
+
##
|
171
|
+
# Describes an access port to a channel.
|
172
|
+
class ChannelPortA
|
173
|
+
|
174
|
+
# Creates a new channel accesser running in +namespace+
|
175
|
+
# and reading using +reader_proc+, writing using +writer_proc+,
|
176
|
+
# and reseting using +reseter_proc+.
|
177
|
+
def initialize(namespace,reader_proc,writer_proc,reseter_proc)
|
178
|
+
unless namespace.is_a?(Namespace)
|
179
|
+
raise "Invalid class for a namespace: #{namespace.class}"
|
180
|
+
end
|
181
|
+
@namespace = namespace
|
182
|
+
@reader_proc = reader_proc.to_proc
|
183
|
+
@writer_proc = writer_proc.to_proc
|
184
|
+
@reseter_proc = reseter_proc.to_proc
|
185
|
+
end
|
186
|
+
|
187
|
+
## Performs a read on the channel using +args+ and +ruby_block+
|
188
|
+
# as arguments.
|
189
|
+
def read(*args,&ruby_block)
|
190
|
+
# Gain access to the accesser as local variable.
|
191
|
+
reader_proc = @reader_proc
|
192
|
+
# Execute the code generating the accesser in context.
|
193
|
+
HDLRuby::High.space_push(@namespace)
|
194
|
+
HDLRuby::High.cur_block.open do
|
195
|
+
instance_exec(ruby_block,*args,&reader_proc)
|
196
|
+
end
|
197
|
+
HDLRuby::High.space_pop
|
198
|
+
end
|
199
|
+
|
200
|
+
## Performs a write on the channel using +args+ and +ruby_block+
|
201
|
+
# as arguments.
|
202
|
+
def write(*args,&ruby_block)
|
203
|
+
# Gain access to the accesser as local variable.
|
204
|
+
writer_proc = @writer_proc
|
205
|
+
# Execute the code generating the accesser in context.
|
206
|
+
HDLRuby::High.space_push(@namespace)
|
207
|
+
HDLRuby::High.cur_block.open do
|
208
|
+
instance_exec(ruby_block,*args,&writer_proc)
|
209
|
+
end
|
210
|
+
HDLRuby::High.space_pop
|
211
|
+
end
|
212
|
+
|
213
|
+
## Performs a reset on the channel using +args+ and +ruby_block+
|
214
|
+
# as arguments.
|
215
|
+
def reset(*args,&ruby_block)
|
216
|
+
# Gain access to the accesser as local variable.
|
217
|
+
reseter_proc = @reseter_proc
|
218
|
+
# Execute the code generating the accesser in context.
|
219
|
+
HDLRuby::High.space_push(@namespace)
|
220
|
+
HDLRuby::High.cur_block.open do
|
221
|
+
instance_exec(ruby_block,*args,&reseter_proc)
|
222
|
+
end
|
223
|
+
HDLRuby::High.space_pop
|
224
|
+
end
|
225
|
+
end
|
63
226
|
|
64
227
|
|
65
228
|
##
|
@@ -75,16 +238,19 @@ module HDLRuby::High::Std
|
|
75
238
|
attr_reader :scope
|
76
239
|
|
77
240
|
# The namespace associated with the current execution when
|
78
|
-
# building a channel
|
241
|
+
# building a channel.
|
79
242
|
attr_reader :namespace
|
80
243
|
|
81
244
|
## Creates a new channel instance with +name+ built from +ruby_block+.
|
82
245
|
def initialize(name,&ruby_block)
|
83
|
-
# Check and set the name
|
246
|
+
# Check and set the name of the channel.
|
84
247
|
@name = name.to_sym
|
248
|
+
# Generate a name for the scope containing the signals of
|
249
|
+
# the channel.
|
250
|
+
@scope_name = HDLRuby.uniq_name
|
85
251
|
|
86
|
-
# Sets the scope.
|
87
|
-
@scope = HDLRuby::High.cur_scope
|
252
|
+
# # Sets the scope.
|
253
|
+
# @scope = HDLRuby::High.cur_scope
|
88
254
|
|
89
255
|
# Keep access to self.
|
90
256
|
obj = self
|
@@ -103,58 +269,93 @@ module HDLRuby::High::Std
|
|
103
269
|
# The writer inout ports by name.
|
104
270
|
@writer_inouts = {}
|
105
271
|
|
272
|
+
# The accesser input ports by name.
|
273
|
+
@accesser_inputs = {}
|
274
|
+
# The accesser output ports by name.
|
275
|
+
@accesser_outputs = {}
|
276
|
+
# The accesser inout ports by name.
|
277
|
+
@accesser_inouts = {}
|
278
|
+
|
279
|
+
# The default reset procedures (reseters), by default do nothing.
|
280
|
+
@input_reseter_proc = proc {}
|
281
|
+
@output_reseter_proc = proc {}
|
282
|
+
@inout_reseter_proc = proc {}
|
283
|
+
|
284
|
+
# The branch channels
|
285
|
+
@branches = {}
|
286
|
+
|
106
287
|
# Create the namespaces for building the channel, its readers
|
107
|
-
# and its
|
288
|
+
# its writers and its accessers.
|
108
289
|
|
109
290
|
# Creates the namespace of the channel.
|
110
|
-
@
|
291
|
+
@namespace = Namespace.new(self)
|
111
292
|
# Make it give access to the internal of the class.
|
112
|
-
@
|
113
|
-
@
|
114
|
-
@
|
115
|
-
@
|
116
|
-
@
|
117
|
-
@
|
118
|
-
@
|
119
|
-
@
|
293
|
+
@namespace.add_method(:reader_input, &method(:reader_input))
|
294
|
+
@namespace.add_method(:reader_output, &method(:reader_output))
|
295
|
+
@namespace.add_method(:reader_inout, &method(:reader_inout))
|
296
|
+
@namespace.add_method(:writer_input, &method(:writer_input))
|
297
|
+
@namespace.add_method(:writer_output, &method(:writer_output))
|
298
|
+
@namespace.add_method(:writer_inout, &method(:writer_inout))
|
299
|
+
@namespace.add_method(:accesser_input, &method(:accesser_input))
|
300
|
+
@namespace.add_method(:accesser_output,&method(:accesser_output))
|
301
|
+
@namespace.add_method(:accesser_inout, &method(:accesser_inout))
|
302
|
+
@namespace.add_method(:reader, &method(:reader))
|
303
|
+
@namespace.add_method(:writer, &method(:writer))
|
304
|
+
@namespace.add_method(:brancher, &method(:brancher))
|
120
305
|
|
121
306
|
# Creates the namespace of the reader.
|
122
307
|
@reader_namespace = Namespace.new(self)
|
123
308
|
# Creates the namespace of the writer.
|
124
309
|
@writer_namespace = Namespace.new(self)
|
310
|
+
# Creates the namespace of the accesser.
|
311
|
+
@accesser_namespace = Namespace.new(self)
|
125
312
|
|
126
|
-
#
|
127
|
-
@namespace = @channel_namespace
|
128
|
-
|
129
|
-
# Builds the channel.
|
313
|
+
# Builds the channel within a new scope.
|
130
314
|
HDLRuby::High.space_push(@namespace)
|
131
315
|
# puts "top_user=#{HDLRuby::High.top_user}"
|
132
|
-
|
316
|
+
scope_name = @scope_name
|
317
|
+
scope = nil
|
318
|
+
HDLRuby::High.top_user.instance_eval do
|
319
|
+
sub(scope_name) do
|
320
|
+
# Generate the channel code.
|
321
|
+
ruby_block.call
|
322
|
+
end
|
323
|
+
end
|
133
324
|
HDLRuby::High.space_pop
|
134
325
|
|
326
|
+
# Keep access to the scope containing the code of the channel.
|
327
|
+
@scope = @namespace.send(scope_name)
|
328
|
+
# puts "@scope=#{@scope}"
|
329
|
+
# Adds the name space of the scope to the namespace of the
|
330
|
+
# channel
|
331
|
+
@namespace.concat_namespace(@scope.namespace)
|
332
|
+
|
135
333
|
# Gives access to the channel by registering its name.
|
136
334
|
obj = self
|
137
|
-
HDLRuby::High.space_reg(@name) { self }
|
335
|
+
# HDLRuby::High.space_reg(@name) { self }
|
336
|
+
HDLRuby::High.space_reg(@name) { obj }
|
138
337
|
end
|
139
338
|
|
140
339
|
# The methods for defining the channel
|
141
340
|
|
142
341
|
# For the channel itself
|
143
342
|
|
144
|
-
## Defines new command +name+ to execute +ruby_block+ for the
|
145
|
-
# channel.
|
146
|
-
def command(name,&ruby_block)
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
343
|
+
# ## Defines new command +name+ to execute +ruby_block+ for the
|
344
|
+
# # channel.
|
345
|
+
# def command(name,&ruby_block)
|
346
|
+
# # Ensures name is a symbol.
|
347
|
+
# name = name.to_sym
|
348
|
+
# res = nil
|
349
|
+
# # Sets the new command.
|
350
|
+
# self.define_singleton_method(name) do |*args|
|
351
|
+
# HDLRuby::High.space_push(@namespace)
|
352
|
+
# HDLRuby::High.cur_block.open do
|
353
|
+
# res = instance_exec(*args,&ruby_block)
|
354
|
+
# end
|
355
|
+
# HDLRuby::High.space_pop
|
356
|
+
# res
|
357
|
+
# end
|
358
|
+
# end
|
158
359
|
|
159
360
|
# For the reader and the writer
|
160
361
|
|
@@ -230,18 +431,74 @@ module HDLRuby::High::Std
|
|
230
431
|
end
|
231
432
|
end
|
232
433
|
|
434
|
+
## Sets the signals accessible through +key+ to be accesser input port.
|
435
|
+
def accesser_input(*keys)
|
436
|
+
# Registers each signal as accesser port
|
437
|
+
keys.each do |key|
|
438
|
+
# Ensure the key is a symbol.
|
439
|
+
key = key.to_sym
|
440
|
+
# Register it with the corresponding signal.
|
441
|
+
name = HDLRuby.uniq_name # The name of the signal is uniq.
|
442
|
+
@accesser_inputs[name] = send(key)
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
## Sets the signals accessible through +key+ to be accesser output port.
|
447
|
+
def accesser_output(*keys)
|
448
|
+
# Registers each signal as accesser port
|
449
|
+
keys.each do |key|
|
450
|
+
# Ensure the key is a symbol.
|
451
|
+
key = key.to_sym
|
452
|
+
# Register it with the corresponding signal.
|
453
|
+
name = HDLRuby.uniq_name # The name of the signal is uniq.
|
454
|
+
@accesser_outputs[name] = send(key)
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
## Sets the signals accessible through +key+ to be accesser inout port.
|
459
|
+
def accesser_inout(*keys)
|
460
|
+
# Registers each signal as accesser port
|
461
|
+
keys.each do |key|
|
462
|
+
# Ensure the key is a symbol.
|
463
|
+
key = key.to_sym
|
464
|
+
# Register it with the corresponding signal.
|
465
|
+
name = HDLRuby.uniq_name # The name of the signal is uniq.
|
466
|
+
@accesser_inouts[name] = send(key)
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
|
233
471
|
## Sets the read procedure to be +ruby_block+.
|
234
472
|
def reader(&ruby_block)
|
235
473
|
@reader_proc = ruby_block
|
236
474
|
end
|
237
475
|
|
238
|
-
## Sets the
|
476
|
+
## Sets the writer procedure to be +ruby_block+.
|
239
477
|
def writer(&ruby_block)
|
240
478
|
@writer_proc = ruby_block
|
241
479
|
end
|
242
480
|
|
243
|
-
#
|
481
|
+
# ## Sets the accesser procedure to be +ruby_block+.
|
482
|
+
# def accesser(&ruby_block)
|
483
|
+
# @accesser_proc = ruby_block
|
484
|
+
# end
|
485
|
+
|
486
|
+
## Sets the input port reset to be +ruby_block+.
|
487
|
+
def input_reseter(&ruby_block)
|
488
|
+
@input_reseter_proc = ruby_block
|
489
|
+
end
|
490
|
+
|
491
|
+
## Sets the output port reset to be +ruby_block+.
|
492
|
+
def output_reseter(&ruby_block)
|
493
|
+
@output_reseter_proc = ruby_block
|
494
|
+
end
|
495
|
+
|
496
|
+
## Sets the inout port reset to be +ruby_block+.
|
497
|
+
def inout_reseter(&ruby_block)
|
498
|
+
@inout_reseter_proc = ruby_block
|
499
|
+
end
|
244
500
|
|
501
|
+
# The methods for accessing the channel
|
245
502
|
# Channel side.
|
246
503
|
|
247
504
|
## Gets the list of the signals of the channel to be connected
|
@@ -258,22 +515,32 @@ module HDLRuby::High::Std
|
|
258
515
|
@writer_inouts.values
|
259
516
|
end
|
260
517
|
|
261
|
-
#
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
#
|
274
|
-
|
275
|
-
#
|
276
|
-
#
|
518
|
+
# Defines a branch in the channel named +name+ built executing
|
519
|
+
# +ruby_block+.
|
520
|
+
def brancher(name,*args,&ruby_block)
|
521
|
+
# Ensure name is a symbol.
|
522
|
+
name = name.to_s unless name.respond_to?(:to_sym)
|
523
|
+
name = name.to_sym
|
524
|
+
# Create the branch.
|
525
|
+
channelI = HDLRuby::High.channel_instance(name,*args,&ruby_block)
|
526
|
+
@branches[name] = channelI
|
527
|
+
end
|
528
|
+
|
529
|
+
|
530
|
+
# Methods used on the channel outside its definition.
|
531
|
+
|
532
|
+
# Gets branch channel +name+.
|
533
|
+
# NOTE: +name+ can be of any type on purpose.
|
534
|
+
def branch(name)
|
535
|
+
# Ensure name is a symbol.
|
536
|
+
name = name.to_s unless name.respond_to?(:to_sym)
|
537
|
+
name = name.to_sym
|
538
|
+
# Get the branch.
|
539
|
+
return @branches[name]
|
540
|
+
end
|
541
|
+
|
542
|
+
|
543
|
+
# Reader, writer and accesser side.
|
277
544
|
|
278
545
|
## Declares the ports for the reader and assigned them to +name+.
|
279
546
|
def input(name)
|
@@ -289,6 +556,7 @@ module HDLRuby::High::Std
|
|
289
556
|
HDLRuby::High.cur_system.open do
|
290
557
|
# The inputs
|
291
558
|
loc_inputs.each do |name,sig|
|
559
|
+
# puts "name=#{name} sig.name=#{sig.name}"
|
292
560
|
port_pairs << [sig, sig.type.input(name)]
|
293
561
|
end
|
294
562
|
# The outputs
|
@@ -309,28 +577,32 @@ module HDLRuby::High::Std
|
|
309
577
|
end
|
310
578
|
end
|
311
579
|
end
|
580
|
+
|
581
|
+
# Fill the reader namespace with the access to the reader signals.
|
582
|
+
@reader_inputs.each do |name,sig|
|
583
|
+
@reader_namespace.add_method(sig.name) do
|
584
|
+
HDLRuby::High.top_user.send(name)
|
585
|
+
end
|
586
|
+
end
|
587
|
+
@reader_outputs.each do |name,sig|
|
588
|
+
@reader_namespace.add_method(sig.name) do
|
589
|
+
HDLRuby::High.top_user.send(name)
|
590
|
+
end
|
591
|
+
end
|
592
|
+
@reader_inouts.each do |name,sig|
|
593
|
+
@reader_namespace.add_method(sig.name) do
|
594
|
+
HDLRuby::High.top_user.send(name)
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
312
598
|
# Give access to the ports through name.
|
313
599
|
# NOTE: for now, simply associate the channel to name.
|
314
|
-
|
315
|
-
HDLRuby::High.space_reg(name) {
|
316
|
-
|
317
|
-
|
318
|
-
# ## Declares the ports for the writer.
|
319
|
-
# def writer_ports
|
320
|
-
# loc_inputs = @writer_inputs
|
321
|
-
# loc_outputs = @writer_outputs
|
322
|
-
# loc_inouts = @writer_inouts
|
323
|
-
# HDLRuby::High.cur_system.open do
|
324
|
-
# # The inputs
|
325
|
-
# loc_inputs.each { |name,sig| sig.type.input name }
|
326
|
-
# # The outputs
|
327
|
-
# loc_outputs.each { |name,sig| sig.type.output name }
|
328
|
-
# # The inouts
|
329
|
-
# loc_inouts.each { |name,sig| sig.type.inout name }
|
330
|
-
# end
|
331
|
-
# end
|
600
|
+
chp = ChannelPortR.new(@reader_namespace,@reader_proc,@input_reseter_proc)
|
601
|
+
HDLRuby::High.space_reg(name) { chp }
|
602
|
+
return chp
|
603
|
+
end
|
332
604
|
|
333
|
-
## Declares the ports for the
|
605
|
+
## Declares the ports for the writer and assigned them to +name+.
|
334
606
|
def output(name)
|
335
607
|
# Ensure name is a symbol.
|
336
608
|
name = name.to_sym
|
@@ -364,77 +636,182 @@ module HDLRuby::High::Std
|
|
364
636
|
end
|
365
637
|
end
|
366
638
|
end
|
639
|
+
|
640
|
+
# Fill the writer namespace with the access to the writer signals.
|
641
|
+
@writer_inputs.each do |name,sig|
|
642
|
+
@writer_namespace.add_method(sig.name) do
|
643
|
+
HDLRuby::High.top_user.send(name)
|
644
|
+
end
|
645
|
+
end
|
646
|
+
@writer_outputs.each do |name,sig|
|
647
|
+
@writer_namespace.add_method(sig.name) do
|
648
|
+
HDLRuby::High.top_user.send(name)
|
649
|
+
end
|
650
|
+
end
|
651
|
+
@writer_inouts.each do |name,sig|
|
652
|
+
@writer_namespace.add_method(sig.name) do
|
653
|
+
HDLRuby::High.top_user.send(name)
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
367
657
|
# Give access to the ports through name.
|
368
658
|
# NOTE: for now, simply associate the channel to name.
|
369
|
-
|
370
|
-
HDLRuby::High.space_reg(name) {
|
659
|
+
chp = ChannelPortW.new(@writer_namespace,@writer_proc,@output_reseter_proc)
|
660
|
+
HDLRuby::High.space_reg(name) { chp }
|
661
|
+
return chp
|
371
662
|
end
|
372
663
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
#
|
378
|
-
@
|
379
|
-
|
664
|
+
## Declares the ports for the accesser and assigned them to +name+.
|
665
|
+
def inout(name)
|
666
|
+
# Ensure name is a symbol.
|
667
|
+
name = name.to_sym
|
668
|
+
# Access the ports
|
669
|
+
loc_inputs = @accesser_inputs
|
670
|
+
loc_outputs = @accesser_outputs
|
671
|
+
loc_inouts = @accesser_inouts
|
672
|
+
# The generated port with corresponding channel port pairs.
|
673
|
+
port_pairs = []
|
674
|
+
# Add them to the current system.
|
675
|
+
HDLRuby::High.cur_system.open do
|
676
|
+
# The inputs
|
677
|
+
loc_inputs.each do |name,sig|
|
678
|
+
port_pairs << [sig, sig.type.input(name)]
|
679
|
+
end
|
680
|
+
# The outputs
|
681
|
+
loc_outputs.each do |name,sig|
|
682
|
+
port_pairs << [sig, sig.type.output(name)]
|
683
|
+
end
|
684
|
+
# The inouts
|
685
|
+
loc_inouts.each do |name,sig|
|
686
|
+
port_pairs << [sig, sig.type.inout(name)]
|
687
|
+
end
|
688
|
+
end
|
689
|
+
obj = self
|
690
|
+
# Make the connection of the instance.
|
691
|
+
HDLRuby::High.cur_system.on_instance do |inst|
|
692
|
+
obj.scope.open do
|
693
|
+
port_pairs.each do |sig, port|
|
694
|
+
RefObject.new(inst,port.to_ref) <= sig
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
# Set ups the accesser's namespace
|
700
|
+
@accesser_inputs.each do |name,sig|
|
701
|
+
@accesser_namespace.add_method(sig.name) do
|
380
702
|
HDLRuby::High.top_user.send(name)
|
381
703
|
end
|
382
704
|
end
|
383
|
-
@
|
384
|
-
@
|
705
|
+
@accesser_outputs.each do |name,sig|
|
706
|
+
@accesser_namespace.add_method(sig.name) do
|
385
707
|
HDLRuby::High.top_user.send(name)
|
386
708
|
end
|
387
709
|
end
|
388
|
-
@
|
389
|
-
@
|
710
|
+
@accesser_inouts.each do |name,sig|
|
711
|
+
@accesser_namespace.add_method(sig.name) do
|
390
712
|
HDLRuby::High.top_user.send(name)
|
391
713
|
end
|
392
714
|
end
|
715
|
+
|
716
|
+
# Give access to the ports through name.
|
717
|
+
# NOTE: for now, simply associate the channel to name.
|
718
|
+
chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
719
|
+
HDLRuby::High.space_reg(name) { chp }
|
720
|
+
return chp
|
721
|
+
end
|
722
|
+
|
723
|
+
## Declares the ports for accessing the channel as an inner component
|
724
|
+
# and assigned them to +name+.
|
725
|
+
def inner(name)
|
726
|
+
# Ensure name is a symbol.
|
727
|
+
name = name.to_sym
|
728
|
+
# Access the ports
|
729
|
+
loc_inputs = @accesser_inputs.merge(@reader_inputs).
|
730
|
+
merge(@writer_inputs)
|
731
|
+
loc_outputs = @accesser_outputs.merge(@reader_outputs).
|
732
|
+
merge(@writer_outputs)
|
733
|
+
loc_inouts = @accesser_inouts.merge(@reader_inouts).
|
734
|
+
merge(@writer_inouts)
|
735
|
+
locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
736
|
+
# The generated port with corresponding channel port pairs.
|
737
|
+
port_pairs = []
|
738
|
+
# Add them to the current system.
|
739
|
+
HDLRuby::High.cur_system.open do
|
740
|
+
locs.each do |name,sig|
|
741
|
+
port_pairs << [sig, sig.type.inner(name)]
|
742
|
+
end
|
743
|
+
end
|
744
|
+
obj = self
|
745
|
+
# Make the inner connection
|
746
|
+
port_pairs.each do |sig, port|
|
747
|
+
port.to_ref <= sig
|
748
|
+
end
|
749
|
+
|
750
|
+
# Set ups the accesser's namespace
|
751
|
+
@accesser_inputs.each do |name,sig|
|
752
|
+
@accesser_namespace.add_method(sig.name) do
|
753
|
+
HDLRuby::High.top_user.send(name)
|
754
|
+
end
|
755
|
+
end
|
756
|
+
@accesser_outputs.each do |name,sig|
|
757
|
+
@accesser_namespace.add_method(sig.name) do
|
758
|
+
HDLRuby::High.top_user.send(name)
|
759
|
+
end
|
760
|
+
end
|
761
|
+
@accesser_inouts.each do |name,sig|
|
762
|
+
@accesser_namespace.add_method(sig.name) do
|
763
|
+
HDLRuby::High.top_user.send(name)
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
# Give access to the ports through name.
|
768
|
+
# NOTE: for now, simply associate the channel to name.
|
769
|
+
chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
770
|
+
HDLRuby::High.space_reg(name) { chp }
|
771
|
+
return chp
|
772
|
+
end
|
773
|
+
|
774
|
+
|
775
|
+
## Performs a read on the channel using +args+ and +ruby_block+
|
776
|
+
# as arguments.
|
777
|
+
def read(*args,&ruby_block)
|
393
778
|
# Gain access to the reader as local variable.
|
394
779
|
reader_proc = @reader_proc
|
395
|
-
# The context is the one of the reader.
|
396
|
-
@namespace = @reader_namespace
|
780
|
+
# # The context is the one of the reader.
|
397
781
|
# Execute the code generating the reader in context.
|
398
782
|
HDLRuby::High.space_push(@namespace)
|
399
783
|
HDLRuby::High.cur_block.open do
|
400
784
|
instance_exec(ruby_block,*args,&reader_proc)
|
401
785
|
end
|
402
786
|
HDLRuby::High.space_pop
|
403
|
-
# Restores the default context.
|
404
|
-
@namespace = @channel_namespace
|
405
787
|
end
|
406
788
|
|
407
789
|
## Performs a write on the channel using +args+ and +ruby_block+
|
408
790
|
# as arguments.
|
409
791
|
def write(*args,&ruby_block)
|
410
|
-
# Fill the writer namespace with the access to the writer signals.
|
411
|
-
@writer_inputs.each do |name,sig|
|
412
|
-
@writer_namespace.add_method(sig.name) do
|
413
|
-
HDLRuby::High.top_user.send(name)
|
414
|
-
end
|
415
|
-
end
|
416
|
-
@writer_outputs.each do |name,sig|
|
417
|
-
@writer_namespace.add_method(sig.name) do
|
418
|
-
HDLRuby::High.top_user.send(name)
|
419
|
-
end
|
420
|
-
end
|
421
|
-
@writer_inouts.each do |name,sig|
|
422
|
-
@writer_namespace.add_method(sig.name) do
|
423
|
-
HDLRuby::High.top_user.send(name)
|
424
|
-
end
|
425
|
-
end
|
426
792
|
# Gain access to the writer as local variable.
|
427
793
|
writer_proc = @writer_proc
|
428
|
-
# The context is the one of the writer.
|
429
|
-
@namespace = @writer_namespace
|
794
|
+
# # The context is the one of the writer.
|
430
795
|
# Execute the code generating the writer in context.
|
431
796
|
HDLRuby::High.space_push(@namespace)
|
432
797
|
HDLRuby::High.cur_block.open do
|
433
798
|
instance_exec(ruby_block,*args,&writer_proc)
|
434
799
|
end
|
435
800
|
HDLRuby::High.space_pop
|
436
|
-
|
437
|
-
|
801
|
+
end
|
802
|
+
|
803
|
+
## Performs a reset on the channel using +args+ and +ruby_block+
|
804
|
+
# as arguments.
|
805
|
+
def reset(*args,&ruby_block)
|
806
|
+
# Gain access to the writer as local variable.
|
807
|
+
reseter_proc = @inout_reseter_proc
|
808
|
+
# # The context is the one of the writer.
|
809
|
+
# Execute the code generating the writer in context.
|
810
|
+
HDLRuby::High.space_push(@namespace)
|
811
|
+
HDLRuby::High.cur_block.open do
|
812
|
+
instance_exec(ruby_block,*args,&reseter_proc)
|
813
|
+
end
|
814
|
+
HDLRuby::High.space_pop
|
438
815
|
end
|
439
816
|
end
|
440
817
|
|