HDLRuby 2.3.2 → 2.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -13
- data/lib/HDLRuby/hdr_samples/with_channel.rb +49 -8
- data/lib/HDLRuby/hdr_samples/with_linear.rb +44 -24
- data/lib/HDLRuby/hdrcc.rb +5 -6
- data/lib/HDLRuby/hruby_low.rb +19 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +2 -0
- data/lib/HDLRuby/std/channel.rb +299 -144
- data/lib/HDLRuby/std/memory.rb +2 -2
- data/lib/HDLRuby/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6548ba8f8c1572f8aa254b168eab065bc5d0a06ac996d792b4082a9243a2dfc9
|
4
|
+
data.tar.gz: 97891dad52f2454d37755af82cf6d23b2665cccd39a44caff81701921f233931
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6df258eebc8a3448824aca9bf39d24ad98c9302728c2584bb34880b8160b42a00f6b7e0fed68a4097403046e0621bf16c8048c43ce95090254f4e9e6e1ebc079
|
7
|
+
data.tar.gz: 73cc373d53e91a756922c8539f15283f793db0ce6e1b3e7c2ae566ae6e2c19691ee62d7dd3ac5ca1f1e19c61a809ab234aba3c790ae207327f8cd2609c76816f
|
data/README.md
CHANGED
@@ -2815,27 +2815,17 @@ This library provides a unified interface to complex communication protocols thr
|
|
2815
2815
|
### Using a channel
|
2816
2816
|
|
2817
2817
|
A channel is used similarly to a pipe: it has an input where data can be written and an output where data can be read. The ordering of the data and the synchronization depend on the internals of the channel, e.g., a channel can be FIFO or LIFO. The interaction with the channel is done using the following methods:
|
2818
|
-
|
2819
|
-
* `input <name>`: generate ports in the system for reading from the channel amd associate them to `name`
|
2820
|
-
* `output <name>`: generate ports in the system for writing to the channel and associate them to `name`
|
2821
|
-
* `inout <name>`: generate ports in the system for reading and writing to the channel and associate them to `name`
|
2822
|
-
* `inner <name>`: generates inner signals for accessing directly the channel
|
2823
|
-
|
2824
|
-
__Note__: `input`, `output`, `inout` and `inner` for channels work similarly to the ones of data types for declaring signals. In particular, `input`, `output` and `inout` are to be used in systems that do not include the channel and `inner` is to be used in the system that include the channel.
|
2825
|
-
|
2826
|
-
When the channel ports are declared, they can be accessed using the following methods depending on whether they are writing or reading ports:
|
2827
2818
|
|
2828
2819
|
* `write(<args>) <block>`: write to the channel and execute `block` when `write` completes. `args` is a list of arguments required for performing the write that depend on the channel.
|
2829
2820
|
* `read(<args>) <block>`: read the channel and execute `block` when the read completes. `args` is a list of arguments required for performing the write that depend on the channel.
|
2830
2821
|
|
2822
|
+
|
2831
2823
|
For example, a system sending successive 8-bit values through a channel can be described as follows:
|
2832
2824
|
|
2833
2825
|
```ruby
|
2834
2826
|
system :producer8 do |channel|
|
2835
2827
|
# Inputs of the producer: clock and reset.
|
2836
2828
|
input :clk, :rst
|
2837
|
-
# Instantiate the channel ports
|
2838
|
-
channel.output :chi
|
2839
2829
|
# Inner 8-bit counter for generating values.
|
2840
2830
|
[8].inner :counter
|
2841
2831
|
|
@@ -2843,7 +2833,7 @@ system :producer8 do |channel|
|
|
2843
2833
|
par(clk.posedge) do
|
2844
2834
|
hif(rst) { counter <= 0 }
|
2845
2835
|
helse do
|
2846
|
-
|
2836
|
+
channel.write(counter) { counter <= counter + 1 }
|
2847
2837
|
end
|
2848
2838
|
end
|
2849
2839
|
end
|
@@ -2851,6 +2841,22 @@ end
|
|
2851
2841
|
|
2852
2842
|
__Note__: In the code above, the channel is passed as generic argument of the system.
|
2853
2843
|
|
2844
|
+
The access points to a channel can also be handled individually by declaring ports using the following methods:
|
2845
|
+
|
2846
|
+
* `input <name>`: declares a port for reading from the channel and associate them to `name` if any
|
2847
|
+
* `output <name>`: declares a port for writing to the channel and associate them to `name` if any
|
2848
|
+
* `inout <name>`: declares a port for reading and writing to the channel and associate them to `name` if any
|
2849
|
+
|
2850
|
+
Such port can then be accessed using the same `read` and `write` method of a channel, the difference being that they can also be configured for new access procedure using the `wrap` method:
|
2851
|
+
|
2852
|
+
* `wrap(<args>) <code>`: creates a new port whose read or write procedure has the elements of `<args>` and the ones produced by `<code>` assign to the arguments of the read or write procedure.
|
2853
|
+
|
2854
|
+
For example, assuming `mem` is a channel whose read and write access have as argument the target address and data signals, the following code creates a port for always accessing at address 0:
|
2855
|
+
|
2856
|
+
```ruby
|
2857
|
+
addr0 = channel.input.wrap(0)
|
2858
|
+
```
|
2859
|
+
|
2854
2860
|
### Channel branches
|
2855
2861
|
|
2856
2862
|
Some channel may include several branches, they are accessed by name using the following method:
|
@@ -2894,7 +2900,7 @@ Where `name` is the name of the channel and `block` is a procedure block describ
|
|
2894
2900
|
The first argument of the block must be the following:
|
2895
2901
|
- `blk`: the block to execute when the write completes.
|
2896
2902
|
Other arguments can be freely defined, and will be required by the `write` command.
|
2897
|
-
* `brancher(name) <block>`: defines branch named +name+ described in `block`. The content of block can be any content valid for a channel, with the additional
|
2903
|
+
* `brancher(name) <block>`: defines branch named +name+ described in `block`. The content of block can be any content valid for a channel, with the additional possibility to access the internals of the upper channel.
|
2898
2904
|
|
2899
2905
|
For example, a channel implemented by a simple register of generic type `typ`, that can be set to 0 using the `reset` command can be described as follows:
|
2900
2906
|
|
@@ -63,12 +63,13 @@ end
|
|
63
63
|
|
64
64
|
|
65
65
|
# A system writing indefinitely to a channel.
|
66
|
+
# Checking usage of channel without declaring a port.
|
66
67
|
system :producer8 do |channel|
|
67
|
-
# puts "channel=#{channel}"
|
68
|
+
# puts "channel=#{channel}, channel methods=#{channel.methods}"
|
68
69
|
# Inputs of the producer: clock and reset.
|
69
70
|
input :clk, :rst
|
70
|
-
# Instantiate the channel ports
|
71
|
-
channel.output :ch
|
71
|
+
# # Instantiate the channel ports
|
72
|
+
# channel.output :ch
|
72
73
|
# Inner 8-bit counter for generating values.
|
73
74
|
[8].inner :counter
|
74
75
|
|
@@ -76,7 +77,8 @@ system :producer8 do |channel|
|
|
76
77
|
par(clk.posedge) do
|
77
78
|
hif(rst) { counter <= 0 }
|
78
79
|
helse do
|
79
|
-
ch.write(counter) { counter <= counter + 1 }
|
80
|
+
# ch.write(counter) { counter <= counter + 1 }
|
81
|
+
channel.write(counter) { counter <= counter + 1 }
|
80
82
|
end
|
81
83
|
end
|
82
84
|
end
|
@@ -96,20 +98,59 @@ system :consummer8 do |channel|
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
101
|
+
# A system reading indefinitely from a channel.
|
102
|
+
# Version without port declaration.
|
103
|
+
system :consummer16 do |channel|
|
104
|
+
# Input of the consummer: a clock is enough.
|
105
|
+
input :clk
|
106
|
+
# # Instantiate the channel ports
|
107
|
+
# channel.input :ch
|
108
|
+
# Inner buffer for storing the cunsummed value.
|
109
|
+
[16].inner :buf
|
110
|
+
|
111
|
+
# The value consumption process
|
112
|
+
par(clk.posedge) do
|
113
|
+
# ch.read(buf)
|
114
|
+
channel.read(buf)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
99
118
|
|
100
119
|
# A system testing the handshaker.
|
101
120
|
system :hs_test do
|
102
121
|
input :clk,:rst
|
103
122
|
|
104
|
-
# Declares
|
105
|
-
handshaker([8]).(:
|
123
|
+
# Declares two handshakers
|
124
|
+
handshaker([8]).(:hs0)
|
125
|
+
handshaker([16]).(:hs1)
|
106
126
|
|
107
127
|
# # Sets the reset.
|
108
128
|
# par(rst.posedge) { hs.reset }
|
129
|
+
|
130
|
+
# For the first handshake
|
109
131
|
|
110
132
|
# Instantiate the producer.
|
111
|
-
producer8(
|
133
|
+
producer8(hs0).(:producerI).(clk,rst)
|
112
134
|
|
113
135
|
# Instantiate the consummer.
|
114
|
-
consummer8(
|
136
|
+
consummer8(hs0).(:consummerI).(clk)
|
137
|
+
|
138
|
+
# For the second handshaker
|
139
|
+
|
140
|
+
# Instantiatethe consummer.
|
141
|
+
consummer16(hs1).(:consummer2I).(clk)
|
142
|
+
|
143
|
+
# Produce from within.
|
144
|
+
[16].inner :counter
|
145
|
+
|
146
|
+
# hs1.output :port
|
147
|
+
|
148
|
+
par(clk.posedge) do
|
149
|
+
hif(rst) { counter <= 0 }
|
150
|
+
helse do
|
151
|
+
# port.write(counter) { counter <= counter + 1 }
|
152
|
+
hs1.write(counter) { counter <= counter + 1 }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
115
156
|
end
|
@@ -22,23 +22,29 @@ system :testmat do
|
|
22
22
|
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memL1)
|
23
23
|
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memR)
|
24
24
|
# Access ports.
|
25
|
-
memL0.branch(:rinc).inner :readL0
|
26
|
-
memL1.branch(:rinc).inner :readL1
|
27
|
-
memR.branch(:rinc).inner :readR
|
25
|
+
# # memL0.branch(:rinc).inner :readL0
|
26
|
+
# # memL1.branch(:rinc).inner :readL1
|
27
|
+
# # memR.branch(:rinc).inner :readR
|
28
|
+
# memL0.branch(:rinc).input :readL0
|
29
|
+
# memL1.branch(:rinc).input :readL1
|
30
|
+
# memR.branch(:rinc).input :readR
|
28
31
|
|
29
32
|
# Prepares the left and acc arrays.
|
30
|
-
lefts = [readL0, readL1]
|
33
|
+
# lefts = [readL0, readL1]
|
34
|
+
lefts = [memL0.branch(:rinc), memL1.branch(:rinc)]
|
31
35
|
|
32
36
|
# Accumulators memory.
|
33
37
|
mem_file([8],2,clk,rst,rinc: :rst).(:memAcc)
|
34
|
-
memAcc.branch(:anum).inner :accs
|
38
|
+
# # memAcc.branch(:anum).inner :accs
|
39
|
+
memAcc.branch(:anum).inout :accs
|
35
40
|
accs_out = [accs.wrap(0), accs.wrap(1)]
|
36
41
|
|
37
42
|
# Layer 0 ack.
|
38
43
|
inner :ack0
|
39
44
|
|
40
45
|
# Instantiate the matrix product.
|
41
|
-
mac_n1([8],clk,req,ack0,lefts,readR,accs_out)
|
46
|
+
# mac_n1([8],clk,req,ack0,lefts,readR,accs_out)
|
47
|
+
mac_n1([8],clk,req,ack0,lefts,memR.branch(:rinc),accs_out)
|
42
48
|
|
43
49
|
# Translation.
|
44
50
|
# Translation memory.
|
@@ -46,10 +52,12 @@ system :testmat do
|
|
46
52
|
# Tarnslation result
|
47
53
|
mem_file([8],2,clk,rst,rinc: :rst).(:memF)
|
48
54
|
# Access ports.
|
49
|
-
memT.branch(:anum).inner :readT
|
50
|
-
memF.branch(:anum).inner :writeF
|
55
|
+
# # memT.branch(:anum).inner :readT
|
56
|
+
# # memF.branch(:anum).inner :writeF
|
57
|
+
memT.branch(:anum).input :readT
|
58
|
+
memF.branch(:anum).output :writeF
|
51
59
|
regRs = [ readT.wrap(0), readT.wrap(1) ]
|
52
|
-
regLs =
|
60
|
+
regLs = accs_out
|
53
61
|
regs = [ writeF.wrap(0), writeF.wrap(1) ]
|
54
62
|
|
55
63
|
# Translater ack.
|
@@ -64,9 +72,10 @@ system :testmat do
|
|
64
72
|
# Input memories.
|
65
73
|
mem_dual([8],2,clk,rst, rinc: :rst,winc: :rst).(:mem2L0)
|
66
74
|
# Access ports.
|
67
|
-
mem2L0.branch(:rinc).inner :read2L0
|
68
|
-
#
|
69
|
-
|
75
|
+
# # mem2L0.branch(:rinc).inner :read2L0
|
76
|
+
# # memF.branch(:rinc).inner :readF
|
77
|
+
# mem2L0.branch(:rinc).input :read2L0
|
78
|
+
# memF.branch(:rinc).input :readF
|
70
79
|
|
71
80
|
# Second layer ack.
|
72
81
|
inner :ack1
|
@@ -76,29 +85,40 @@ system :testmat do
|
|
76
85
|
|
77
86
|
sub do
|
78
87
|
# Instantiate the second matrix product.
|
79
|
-
# mac([8],clk,
|
80
|
-
mac([8],clk,ackT,ack1,
|
88
|
+
# mac([8],clk,ackT,ack1,read2L0,readF,channel_port(res))
|
89
|
+
mac([8],clk,ackT,ack1,mem2L0.branch(:rinc),memF.branch(:rinc),
|
90
|
+
channel_port(res))
|
81
91
|
end
|
82
92
|
|
83
93
|
|
84
94
|
|
85
95
|
# The memory initializer.
|
86
|
-
memL0.branch(:winc).inner :writeL0
|
87
|
-
memL1.branch(:winc).inner :writeL1
|
88
|
-
memR.branch(:winc).inner :writeR
|
89
|
-
memT.branch(:winc).inner :writeT
|
90
|
-
mem2L0.branch(:winc).inner :write2L0
|
96
|
+
# # memL0.branch(:winc).inner :writeL0
|
97
|
+
# # memL1.branch(:winc).inner :writeL1
|
98
|
+
# # memR.branch(:winc).inner :writeR
|
99
|
+
# # memT.branch(:winc).inner :writeT
|
100
|
+
# # mem2L0.branch(:winc).inner :write2L0
|
101
|
+
# memL0.branch(:winc).output :writeL0
|
102
|
+
# memL1.branch(:winc).output :writeL1
|
103
|
+
# memR.branch(:winc).output :writeR
|
104
|
+
# mem2L0.branch(:winc).output :write2L0
|
105
|
+
# memT.branch(:winc).output :writeT
|
91
106
|
inner :fill, :fill2
|
92
107
|
[8].inner :val
|
93
108
|
par(clk.posedge) do
|
94
109
|
hif(fill) do
|
95
|
-
writeL0.write(val)
|
96
|
-
writeL1.write(val+1)
|
97
|
-
writeR.write(val+1)
|
110
|
+
# writeL0.write(val)
|
111
|
+
# writeL1.write(val+1)
|
112
|
+
# writeR.write(val+1)
|
113
|
+
memL0.branch(:winc).write(val)
|
114
|
+
memL1.branch(:winc).write(val+1)
|
115
|
+
memR.branch(:winc).write(val+1)
|
98
116
|
end
|
99
117
|
hif(fill2) do
|
100
|
-
write2L0.write(val+2)
|
101
|
-
writeT.write(val+2)
|
118
|
+
# write2L0.write(val+2)
|
119
|
+
# writeT.write(val+2)
|
120
|
+
mem2L0.branch(:winc).write(val+2)
|
121
|
+
memT.branch(:winc).write(val+2)
|
102
122
|
end
|
103
123
|
end
|
104
124
|
|
data/lib/HDLRuby/hdrcc.rb
CHANGED
@@ -241,7 +241,7 @@ include HDLRuby
|
|
241
241
|
# Process the command line options
|
242
242
|
$options = {}
|
243
243
|
$optparse = OptionParser.new do |opts|
|
244
|
-
opts.banner = "Usage: hdrcc.rb [options] <input file> [<output file>]"
|
244
|
+
opts.banner = "Usage: hdrcc.rb [options] <input file> [<output directory or file>]"
|
245
245
|
|
246
246
|
opts.separator ""
|
247
247
|
opts.separator "Where:"
|
@@ -323,18 +323,17 @@ $optparse = OptionParser.new do |opts|
|
|
323
323
|
opts.separator ""
|
324
324
|
opts.separator "Notice:"
|
325
325
|
opts.separator "* If no output option is given, simply checks the input file"
|
326
|
-
opts.separator "* If no output file is given, the result is given through the standard output."
|
327
326
|
opts.separator "* If no top system is given, it will be automatically searched in the input file."
|
328
327
|
opts.separator ""
|
329
328
|
opts.separator "Examples:"
|
330
329
|
opts.separator "* Compile system named `adder` from `adder.rb` input file and generate `adder.yaml` low-level YAML description:"
|
331
330
|
opts.separator " hdrcc.rb --yaml --top adder adder.rb adder.yaml"
|
332
|
-
opts.separator "* Compile `adder.rb` input file and generate
|
333
|
-
opts.separator " hdrcc.rb --vhdl adder.rb
|
331
|
+
opts.separator "* Compile `adder.rb` input file and generate low-level VHDL description files in `adder_vhd` directory:"
|
332
|
+
opts.separator " hdrcc.rb --vhdl adder.rb adder_vhd"
|
334
333
|
opts.separator "* Check the validity of `adder.rb` input file:"
|
335
334
|
opts.separator " hdrcc.rb adder.rb"
|
336
|
-
opts.separator "* Compile system `adder` whose bit width is generic from `adder_gen.rb` input file to a 16-bit circuit whose low-level Verilog HDL description
|
337
|
-
opts.separator " hdrcc -v -t adder --param 16 adder_gen.rb"
|
335
|
+
opts.separator "* Compile system `adder` whose bit width is generic from `adder_gen.rb` input file to a 16-bit circuit whose low-level Verilog HDL description files are put in `adder_gen_v` directory:"
|
336
|
+
opts.separator " hdrcc -v -t adder --param 16 adder_gen.rb adder_gen_v"
|
338
337
|
opts.separator "* Compile system `multer` with inputs and output bit width is generic from `multer_gen.rb` input file to a 16x16->32 bit cicruit whose low-level YAML description is saved to output file `multer_gen.yaml`"
|
339
338
|
opts.separator "hdrcc -y -t multer -p 16,16,32 multer_gen.rb multer_gen.yaml"
|
340
339
|
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -1123,6 +1123,10 @@ module HDLRuby::Low
|
|
1123
1123
|
return self.parent.is_a?(SystemT) ? self : self.parent.top_scope
|
1124
1124
|
end
|
1125
1125
|
|
1126
|
+
# Gets the parent system, i.e., the parent of the top scope.
|
1127
|
+
def parent_system
|
1128
|
+
return self.top_scope.parent
|
1129
|
+
end
|
1126
1130
|
|
1127
1131
|
end
|
1128
1132
|
|
@@ -2132,6 +2136,11 @@ module HDLRuby::Low
|
|
2132
2136
|
def top_scope
|
2133
2137
|
return parent.top_scope
|
2134
2138
|
end
|
2139
|
+
|
2140
|
+
# Gets the parent system, i.e., the parent of the top scope.
|
2141
|
+
def parent_system
|
2142
|
+
return self.top_scope.parent
|
2143
|
+
end
|
2135
2144
|
end
|
2136
2145
|
|
2137
2146
|
|
@@ -2619,6 +2628,11 @@ module HDLRuby::Low
|
|
2619
2628
|
def top_scope
|
2620
2629
|
return self.scope.top_scope
|
2621
2630
|
end
|
2631
|
+
|
2632
|
+
# Gets the parent system, i.e., the parent of the top scope.
|
2633
|
+
def parent_system
|
2634
|
+
return self.top_scope.parent
|
2635
|
+
end
|
2622
2636
|
end
|
2623
2637
|
|
2624
2638
|
|
@@ -3717,6 +3731,11 @@ module HDLRuby::Low
|
|
3717
3731
|
def top_scope
|
3718
3732
|
return self.parent.is_a?(Scope) ? self.parent : self.parent.top_scope
|
3719
3733
|
end
|
3734
|
+
|
3735
|
+
# Gets the parent system, i.e., the parent of the top scope.
|
3736
|
+
def parent_system
|
3737
|
+
return self.top_scope.parent
|
3738
|
+
end
|
3720
3739
|
end
|
3721
3740
|
|
3722
3741
|
|
@@ -365,6 +365,7 @@ void* behavior_run(void* arg) {
|
|
365
365
|
* @note create a thread per timed behavior. */
|
366
366
|
void hruby_sim_start_timed_behaviors() {
|
367
367
|
int i;
|
368
|
+
pthread_mutex_lock(&hruby_sim_mutex);
|
368
369
|
/* Sets the end flags to 0. */
|
369
370
|
sim_end_flag = 0;
|
370
371
|
/* Create and start the threads. */
|
@@ -375,6 +376,7 @@ void hruby_sim_start_timed_behaviors() {
|
|
375
376
|
pthread_create(&timed_behaviors[i]->thread,NULL,
|
376
377
|
&behavior_run,timed_behaviors[i]);
|
377
378
|
}
|
379
|
+
pthread_mutex_unlock(&hruby_sim_mutex);
|
378
380
|
}
|
379
381
|
|
380
382
|
/** Ends waiting all the threads properly terminates. */
|
data/lib/HDLRuby/std/channel.rb
CHANGED
@@ -96,6 +96,9 @@ module HDLRuby::High::Std
|
|
96
96
|
def wrap(*args)
|
97
97
|
return ChannelPortB.new(self,*args)
|
98
98
|
end
|
99
|
+
|
100
|
+
# The scope the port has been declared in.
|
101
|
+
attr_reader :scope
|
99
102
|
end
|
100
103
|
|
101
104
|
|
@@ -113,6 +116,7 @@ module HDLRuby::High::Std
|
|
113
116
|
@namespace = namespace
|
114
117
|
@reader_proc = reader_proc.to_proc
|
115
118
|
@rester_proc = reseter_proc ? reseter_proc.to_proc : proc {}
|
119
|
+
@scope = HDLRuby::High.cur_scope
|
116
120
|
end
|
117
121
|
|
118
122
|
## Performs a read on the channel using +args+ and +ruby_block+
|
@@ -157,6 +161,7 @@ module HDLRuby::High::Std
|
|
157
161
|
@namespace = namespace
|
158
162
|
@writer_proc = writer_proc.to_proc
|
159
163
|
@reseter_proc = reseter_proc ? reseter_proc.to_proc : proc {}
|
164
|
+
@scope = HDLRuby::High.cur_scope
|
160
165
|
end
|
161
166
|
|
162
167
|
## Performs a write on the channel using +args+ and +ruby_block+
|
@@ -206,6 +211,7 @@ module HDLRuby::High::Std
|
|
206
211
|
@reader_proc = reader_proc ? reader_proc.to_proc : proc { }
|
207
212
|
@writer_proc = writer_proc ? writer_proc.to_proc : proc { }
|
208
213
|
@reseter_proc = reseter_proc ? reseter_proc.to_proc : proc {}
|
214
|
+
@scope = HDLRuby::High.cur_scope
|
209
215
|
end
|
210
216
|
|
211
217
|
## Performs a read on the channel using +args+ and +ruby_block+
|
@@ -281,6 +287,8 @@ module HDLRuby::High::Std
|
|
281
287
|
@args_write = args.clone
|
282
288
|
@args_access = args.clone
|
283
289
|
end
|
290
|
+
|
291
|
+
@scope = @port.scope
|
284
292
|
end
|
285
293
|
|
286
294
|
## Performs a read on the channel using +args+ and +ruby_block+
|
@@ -332,6 +340,12 @@ module HDLRuby::High::Std
|
|
332
340
|
# building a channel.
|
333
341
|
attr_reader :namespace
|
334
342
|
|
343
|
+
# The read port if any.
|
344
|
+
attr_reader :read_port
|
345
|
+
|
346
|
+
# The write port if any.
|
347
|
+
attr_reader :write_port
|
348
|
+
|
335
349
|
## Creates a new channel instance with +name+ built from +ruby_block+.
|
336
350
|
def initialize(name,&ruby_block)
|
337
351
|
# Check and set the name of the channel.
|
@@ -346,6 +360,10 @@ module HDLRuby::High::Std
|
|
346
360
|
# Keep access to self.
|
347
361
|
obj = self
|
348
362
|
|
363
|
+
# At first there no read nor write port.
|
364
|
+
@read_port = nil
|
365
|
+
@write_port = nil
|
366
|
+
|
349
367
|
# The reader input ports by name.
|
350
368
|
@reader_inputs = {}
|
351
369
|
# The reader output ports by name.
|
@@ -367,11 +385,6 @@ module HDLRuby::High::Std
|
|
367
385
|
# The accesser inout ports by name.
|
368
386
|
@accesser_inouts = {}
|
369
387
|
|
370
|
-
# # The default reset procedures (reseters), by default do nothing.
|
371
|
-
# @input_reseter_proc = proc {}
|
372
|
-
# @output_reseter_proc = proc {}
|
373
|
-
# @inout_reseter_proc = proc {}
|
374
|
-
|
375
388
|
# The branch channels
|
376
389
|
@branches = {}
|
377
390
|
|
@@ -427,6 +440,11 @@ module HDLRuby::High::Std
|
|
427
440
|
HDLRuby::High.space_reg(@name) { obj }
|
428
441
|
end
|
429
442
|
|
443
|
+
# Get the parent system.
|
444
|
+
def parent_system
|
445
|
+
return self.scope.parent_system
|
446
|
+
end
|
447
|
+
|
430
448
|
# The methods for defining the channel
|
431
449
|
|
432
450
|
# For the channel itself
|
@@ -606,6 +624,12 @@ module HDLRuby::High::Std
|
|
606
624
|
@writer_inouts.values
|
607
625
|
end
|
608
626
|
|
627
|
+
## Tells if the channel support inout port.
|
628
|
+
def inout?
|
629
|
+
return @accesser_inputs.any? || @accesser_outputs.any? ||
|
630
|
+
@accesser_inouts.any?
|
631
|
+
end
|
632
|
+
|
609
633
|
# Defines a branch in the channel named +name+ built executing
|
610
634
|
# +ruby_block+.
|
611
635
|
# Alternatively, a ready channel instance can be passed as argument
|
@@ -620,8 +644,7 @@ module HDLRuby::High::Std
|
|
620
644
|
@branches[name] = channelI
|
621
645
|
return self
|
622
646
|
end
|
623
|
-
#
|
624
|
-
# channelI = HDLRuby::High.channel_instance(name, &ruby_block)
|
647
|
+
# Now, create the branch.
|
625
648
|
channelI = HDLRuby::High::Std.channel_instance(name, &ruby_block)
|
626
649
|
@branches[name] = channelI
|
627
650
|
return self
|
@@ -644,54 +667,83 @@ module HDLRuby::High::Std
|
|
644
667
|
|
645
668
|
# Reader, writer and accesser side.
|
646
669
|
|
647
|
-
## Declares the
|
648
|
-
def input(name)
|
670
|
+
## Declares the reader port as and assigned them to +name+.
|
671
|
+
def input(name = nil)
|
649
672
|
# Ensure name is a symbol.
|
673
|
+
name = HDLRuby.uniq_name unless name
|
650
674
|
name = name.to_sym
|
675
|
+
# Ensure the port is not already existing.
|
676
|
+
if @read_port then
|
677
|
+
raise "Read port already declared for channel instance: " +
|
678
|
+
self.name
|
679
|
+
end
|
680
|
+
|
651
681
|
# Access the ports
|
652
|
-
loc_inputs = @reader_inputs
|
653
|
-
loc_outputs = @reader_outputs
|
654
|
-
loc_inouts = @reader_inouts
|
682
|
+
# loc_inputs = @reader_inputs
|
683
|
+
# loc_outputs = @reader_outputs
|
684
|
+
# loc_inouts = @reader_inouts
|
685
|
+
loc_inputs = @reader_inputs.merge(@accesser_inputs)
|
686
|
+
loc_outputs = @reader_outputs.merge(@accesser_outputs)
|
687
|
+
loc_inouts = @reader_inouts.merge(@accesser_inouts)
|
688
|
+
locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
655
689
|
# The generated port with corresponding channel port pairs.
|
656
690
|
port_pairs = []
|
657
|
-
|
658
|
-
|
659
|
-
#
|
660
|
-
|
661
|
-
|
662
|
-
|
691
|
+
if HDLRuby::High.cur_system == self.parent_system then
|
692
|
+
# Port in same system as the channel case.
|
693
|
+
# Add them to the current system.
|
694
|
+
HDLRuby::High.cur_system.open do
|
695
|
+
locs.each do |name,sig|
|
696
|
+
port_pairs << [sig, sig.type.inner(name)]
|
697
|
+
end
|
663
698
|
end
|
664
|
-
|
665
|
-
|
666
|
-
|
699
|
+
obj = self
|
700
|
+
# Make the inner connection
|
701
|
+
port_pairs.each do |sig, port|
|
702
|
+
sig.parent.open do
|
703
|
+
port.to_ref <= sig
|
704
|
+
end
|
667
705
|
end
|
668
|
-
|
669
|
-
|
670
|
-
|
706
|
+
else
|
707
|
+
# Port in different system as the channel case.
|
708
|
+
# Add them to the current system.
|
709
|
+
HDLRuby::High.cur_system.open do
|
710
|
+
# The inputs
|
711
|
+
loc_inputs.each do |name,sig|
|
712
|
+
# puts "name=#{name} sig.name=#{sig.name}"
|
713
|
+
port_pairs << [sig, sig.type.input(name)]
|
714
|
+
end
|
715
|
+
# The outputs
|
716
|
+
loc_outputs.each do |name,sig|
|
717
|
+
port_pairs << [sig, sig.type.output(name)]
|
718
|
+
end
|
719
|
+
# The inouts
|
720
|
+
loc_inouts.each do |name,sig|
|
721
|
+
port_pairs << [sig, sig.type.inout(name)]
|
722
|
+
end
|
671
723
|
end
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
724
|
+
obj = self
|
725
|
+
# Make the connection of the instance.
|
726
|
+
HDLRuby::High.cur_system.on_instance do |inst|
|
727
|
+
obj.scope.open do
|
728
|
+
port_pairs.each do |sig, port|
|
729
|
+
RefObject.new(inst,port.to_ref) <= sig
|
730
|
+
end
|
679
731
|
end
|
680
732
|
end
|
681
733
|
end
|
682
734
|
|
683
735
|
# Fill the reader namespace with the access to the reader signals.
|
684
|
-
|
736
|
+
loc_inputs.each do |name,sig|
|
685
737
|
@reader_namespace.add_method(sig.name) do
|
686
738
|
HDLRuby::High.top_user.send(name)
|
687
739
|
end
|
688
740
|
end
|
689
|
-
|
741
|
+
loc_outputs.each do |name,sig|
|
690
742
|
@reader_namespace.add_method(sig.name) do
|
691
743
|
HDLRuby::High.top_user.send(name)
|
692
744
|
end
|
693
745
|
end
|
694
|
-
|
746
|
+
loc_inouts.each do |name,sig|
|
695
747
|
@reader_namespace.add_method(sig.name) do
|
696
748
|
HDLRuby::High.top_user.send(name)
|
697
749
|
end
|
@@ -701,56 +753,88 @@ module HDLRuby::High::Std
|
|
701
753
|
# NOTE: for now, simply associate the channel to name.
|
702
754
|
chp = ChannelPortR.new(@reader_namespace,@reader_proc,@input_reseter_proc)
|
703
755
|
HDLRuby::High.space_reg(name) { chp }
|
756
|
+
# Save the port in the channe to avoid conflicting declaration.
|
757
|
+
@read_port = chp
|
704
758
|
return chp
|
705
759
|
end
|
706
760
|
|
707
761
|
## Declares the ports for the writer and assigned them to +name+.
|
708
|
-
def output(name)
|
762
|
+
def output(name = nil)
|
709
763
|
# Ensure name is a symbol.
|
764
|
+
name = HDLRuby.uniq_name unless name
|
710
765
|
name = name.to_sym
|
766
|
+
# Ensure the port is not already existing.
|
767
|
+
if @write_port then
|
768
|
+
raise "Write port already declared for channel instance: " +
|
769
|
+
self.name
|
770
|
+
end
|
711
771
|
# Access the ports
|
712
|
-
loc_inputs = @writer_inputs
|
713
|
-
loc_outputs = @writer_outputs
|
714
|
-
loc_inouts = @writer_inouts
|
772
|
+
# loc_inputs = @writer_inputs
|
773
|
+
# loc_outputs = @writer_outputs
|
774
|
+
# loc_inouts = @writer_inouts
|
775
|
+
loc_inputs = @writer_inputs.merge(@accesser_inputs)
|
776
|
+
loc_outputs = @writer_outputs.merge(@accesser_outputs)
|
777
|
+
loc_inouts = @writer_inouts.merge(@accesser_inouts)
|
778
|
+
locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
715
779
|
# The generated port with corresponding channel port pairs.
|
716
780
|
port_pairs = []
|
717
|
-
#
|
718
|
-
HDLRuby::High.cur_system.
|
719
|
-
#
|
720
|
-
|
721
|
-
|
781
|
+
# puts "cur_system=#{HDLRuby::High.cur_system} self.parent_system=#{self.parent_system}"
|
782
|
+
if HDLRuby::High.cur_system == self.parent_system then
|
783
|
+
# puts "Inner found!"
|
784
|
+
# Port in same system as the channel case.
|
785
|
+
# Add them to the current system.
|
786
|
+
HDLRuby::High.cur_system.open do
|
787
|
+
locs.each do |name,sig|
|
788
|
+
port_pairs << [sig, sig.type.inner(name)]
|
789
|
+
end
|
722
790
|
end
|
723
|
-
|
724
|
-
|
725
|
-
|
791
|
+
obj = self
|
792
|
+
# Make the inner connection
|
793
|
+
port_pairs.each do |sig, port|
|
794
|
+
sig.parent.open do
|
795
|
+
port.to_ref <= sig
|
796
|
+
end
|
726
797
|
end
|
727
|
-
|
728
|
-
|
729
|
-
|
798
|
+
else
|
799
|
+
# Portds in different system as the channel's case.
|
800
|
+
# Add them to the current system.
|
801
|
+
HDLRuby::High.cur_system.open do
|
802
|
+
# The inputs
|
803
|
+
loc_inputs.each do |name,sig|
|
804
|
+
port_pairs << [sig, sig.type.input(name)]
|
805
|
+
end
|
806
|
+
# The outputs
|
807
|
+
loc_outputs.each do |name,sig|
|
808
|
+
port_pairs << [sig, sig.type.output(name)]
|
809
|
+
end
|
810
|
+
# The inouts
|
811
|
+
loc_inouts.each do |name,sig|
|
812
|
+
port_pairs << [sig, sig.type.inout(name)]
|
813
|
+
end
|
730
814
|
end
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
815
|
+
obj = self
|
816
|
+
# Make the connection of the instance.
|
817
|
+
HDLRuby::High.cur_system.on_instance do |inst|
|
818
|
+
obj.scope.open do
|
819
|
+
port_pairs.each do |sig, port|
|
820
|
+
RefObject.new(inst,port.to_ref) <= sig
|
821
|
+
end
|
738
822
|
end
|
739
823
|
end
|
740
824
|
end
|
741
825
|
|
742
826
|
# Fill the writer namespace with the access to the writer signals.
|
743
|
-
|
827
|
+
loc_inputs.each do |name,sig|
|
744
828
|
@writer_namespace.add_method(sig.name) do
|
745
829
|
HDLRuby::High.top_user.send(name)
|
746
830
|
end
|
747
831
|
end
|
748
|
-
|
832
|
+
loc_outputs.each do |name,sig|
|
749
833
|
@writer_namespace.add_method(sig.name) do
|
750
834
|
HDLRuby::High.top_user.send(name)
|
751
835
|
end
|
752
836
|
end
|
753
|
-
|
837
|
+
loc_inouts.each do |name,sig|
|
754
838
|
@writer_namespace.add_method(sig.name) do
|
755
839
|
HDLRuby::High.top_user.send(name)
|
756
840
|
end
|
@@ -760,73 +844,28 @@ module HDLRuby::High::Std
|
|
760
844
|
# NOTE: for now, simply associate the channel to name.
|
761
845
|
chp = ChannelPortW.new(@writer_namespace,@writer_proc,@output_reseter_proc)
|
762
846
|
HDLRuby::High.space_reg(name) { chp }
|
847
|
+
# Save the port in the channe to avoid conflicting declaration.
|
848
|
+
@write_port = chp
|
763
849
|
return chp
|
764
850
|
end
|
765
851
|
|
766
|
-
|
767
|
-
|
852
|
+
|
853
|
+
## Declares the accesser port and assigned them to +name+.
|
854
|
+
def inout(name = nil)
|
768
855
|
# Ensure name is a symbol.
|
856
|
+
name = HDLRuby.uniq_name unless name
|
769
857
|
name = name.to_sym
|
770
|
-
#
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
# The generated port with corresponding channel port pairs.
|
775
|
-
port_pairs = []
|
776
|
-
# Add them to the current system.
|
777
|
-
HDLRuby::High.cur_system.open do
|
778
|
-
# The inputs
|
779
|
-
loc_inputs.each do |name,sig|
|
780
|
-
port_pairs << [sig, sig.type.input(name)]
|
781
|
-
end
|
782
|
-
# The outputs
|
783
|
-
loc_outputs.each do |name,sig|
|
784
|
-
port_pairs << [sig, sig.type.output(name)]
|
785
|
-
end
|
786
|
-
# The inouts
|
787
|
-
loc_inouts.each do |name,sig|
|
788
|
-
port_pairs << [sig, sig.type.inout(name)]
|
789
|
-
end
|
790
|
-
end
|
791
|
-
obj = self
|
792
|
-
# Make the connection of the instance.
|
793
|
-
HDLRuby::High.cur_system.on_instance do |inst|
|
794
|
-
obj.scope.open do
|
795
|
-
port_pairs.each do |sig, port|
|
796
|
-
RefObject.new(inst,port.to_ref) <= sig
|
797
|
-
end
|
798
|
-
end
|
858
|
+
# Ensure the port is not already existing.
|
859
|
+
if @read_port then
|
860
|
+
raise "Read port already declared for channel instance: " +
|
861
|
+
self.name
|
799
862
|
end
|
800
863
|
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
HDLRuby::High.top_user.send(name)
|
805
|
-
end
|
864
|
+
if @write_port then
|
865
|
+
raise "Write port already declared for channel instance: " +
|
866
|
+
self.name
|
806
867
|
end
|
807
|
-
@accesser_outputs.each do |name,sig|
|
808
|
-
@accesser_namespace.add_method(sig.name) do
|
809
|
-
HDLRuby::High.top_user.send(name)
|
810
|
-
end
|
811
|
-
end
|
812
|
-
@accesser_inouts.each do |name,sig|
|
813
|
-
@accesser_namespace.add_method(sig.name) do
|
814
|
-
HDLRuby::High.top_user.send(name)
|
815
|
-
end
|
816
|
-
end
|
817
|
-
|
818
|
-
# Give access to the ports through name.
|
819
|
-
# NOTE: for now, simply associate the channel to name.
|
820
|
-
chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
821
|
-
HDLRuby::High.space_reg(name) { chp }
|
822
|
-
return chp
|
823
|
-
end
|
824
868
|
|
825
|
-
## Declares the ports for accessing the channel as an inner component
|
826
|
-
# and assigned them to +name+.
|
827
|
-
def inner(name)
|
828
|
-
# Ensure name is a symbol.
|
829
|
-
name = name.to_sym
|
830
869
|
# Access the ports
|
831
870
|
loc_inputs = @accesser_inputs.merge(@reader_inputs).
|
832
871
|
merge(@writer_inputs)
|
@@ -837,21 +876,51 @@ module HDLRuby::High::Std
|
|
837
876
|
locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
838
877
|
# The generated port with corresponding channel port pairs.
|
839
878
|
port_pairs = []
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
879
|
+
if HDLRuby::High.cur_system == self.parent_system then
|
880
|
+
# Port in same system as the channel case.
|
881
|
+
# Add them to the current system.
|
882
|
+
HDLRuby::High.cur_system.open do
|
883
|
+
locs.each do |name,sig|
|
884
|
+
port_pairs << [sig, sig.type.inner(name)]
|
885
|
+
end
|
844
886
|
end
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
887
|
+
obj = self
|
888
|
+
# Make the inner connection
|
889
|
+
port_pairs.each do |sig, port|
|
890
|
+
sig.parent.open do
|
891
|
+
port.to_ref <= sig
|
892
|
+
end
|
893
|
+
end
|
894
|
+
else
|
895
|
+
# Port in different system as the channel case.
|
896
|
+
# Add them to the current system.
|
897
|
+
HDLRuby::High.cur_system.open do
|
898
|
+
# The inputs
|
899
|
+
loc_inputs.each do |name,sig|
|
900
|
+
# puts "name=#{name} sig.name=#{sig.name}"
|
901
|
+
port_pairs << [sig, sig.type.input(name)]
|
902
|
+
end
|
903
|
+
# The outputs
|
904
|
+
loc_outputs.each do |name,sig|
|
905
|
+
port_pairs << [sig, sig.type.output(name)]
|
906
|
+
end
|
907
|
+
# The inouts
|
908
|
+
loc_inouts.each do |name,sig|
|
909
|
+
port_pairs << [sig, sig.type.inout(name)]
|
910
|
+
end
|
911
|
+
end
|
912
|
+
obj = self
|
913
|
+
# Make the connection of the instance.
|
914
|
+
HDLRuby::High.cur_system.on_instance do |inst|
|
915
|
+
obj.scope.open do
|
916
|
+
port_pairs.each do |sig, port|
|
917
|
+
RefObject.new(inst,port.to_ref) <= sig
|
918
|
+
end
|
919
|
+
end
|
851
920
|
end
|
852
921
|
end
|
853
922
|
|
854
|
-
#
|
923
|
+
# Fill the reader namespace with the access to the reader signals.
|
855
924
|
loc_inputs.each do |name,sig|
|
856
925
|
@accesser_namespace.add_method(sig.name) do
|
857
926
|
HDLRuby::High.top_user.send(name)
|
@@ -872,37 +941,121 @@ module HDLRuby::High::Std
|
|
872
941
|
# NOTE: for now, simply associate the channel to name.
|
873
942
|
chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
874
943
|
HDLRuby::High.space_reg(name) { chp }
|
944
|
+
# Save the port in the channe to avoid conflicting declaration.
|
945
|
+
@read_port = chp
|
946
|
+
@write_port = chp
|
875
947
|
return chp
|
876
948
|
end
|
877
949
|
|
950
|
+
# ## Declares the ports for accessing the channel as an inner component
|
951
|
+
# # and assigned them to +name+.
|
952
|
+
# def inner(name)
|
953
|
+
# # Ensure name is a symbol.
|
954
|
+
# name = name.to_sym
|
955
|
+
# # Access the ports
|
956
|
+
# loc_inputs = @accesser_inputs.merge(@reader_inputs).
|
957
|
+
# merge(@writer_inputs)
|
958
|
+
# loc_outputs = @accesser_outputs.merge(@reader_outputs).
|
959
|
+
# merge(@writer_outputs)
|
960
|
+
# loc_inouts = @accesser_inouts.merge(@reader_inouts).
|
961
|
+
# merge(@writer_inouts)
|
962
|
+
# locs = loc_inputs.merge(loc_outputs).merge(loc_inouts)
|
963
|
+
# # The generated port with corresponding channel port pairs.
|
964
|
+
# port_pairs = []
|
965
|
+
# # Add them to the current system.
|
966
|
+
# HDLRuby::High.cur_system.open do
|
967
|
+
# locs.each do |name,sig|
|
968
|
+
# port_pairs << [sig, sig.type.inner(name)]
|
969
|
+
# end
|
970
|
+
# end
|
971
|
+
# obj = self
|
972
|
+
# # Make the inner connection
|
973
|
+
# port_pairs.each do |sig, port|
|
974
|
+
# sig.parent.open do
|
975
|
+
# port.to_ref <= sig
|
976
|
+
# end
|
977
|
+
# end
|
978
|
+
|
979
|
+
# # Set ups the accesser's namespace
|
980
|
+
# loc_inputs.each do |name,sig|
|
981
|
+
# @accesser_namespace.add_method(sig.name) do
|
982
|
+
# HDLRuby::High.top_user.send(name)
|
983
|
+
# end
|
984
|
+
# end
|
985
|
+
# loc_outputs.each do |name,sig|
|
986
|
+
# @accesser_namespace.add_method(sig.name) do
|
987
|
+
# HDLRuby::High.top_user.send(name)
|
988
|
+
# end
|
989
|
+
# end
|
990
|
+
# loc_inouts.each do |name,sig|
|
991
|
+
# @accesser_namespace.add_method(sig.name) do
|
992
|
+
# HDLRuby::High.top_user.send(name)
|
993
|
+
# end
|
994
|
+
# end
|
995
|
+
|
996
|
+
# # Give access to the ports through name.
|
997
|
+
# # NOTE: for now, simply associate the channel to name.
|
998
|
+
# chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc)
|
999
|
+
# HDLRuby::High.space_reg(name) { chp }
|
1000
|
+
# return chp
|
1001
|
+
# end
|
1002
|
+
|
1003
|
+
|
878
1004
|
|
879
1005
|
## Performs a read on the channel using +args+ and +ruby_block+
|
880
1006
|
# as arguments.
|
1007
|
+
# NOTE:
|
1008
|
+
# * Will generate a port if not present.
|
1009
|
+
# * Will generate an error if a read is tempted while the read
|
1010
|
+
# port has been declared within another system.
|
881
1011
|
def read(*args,&ruby_block)
|
882
|
-
#
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
1012
|
+
# Is there a port to read?
|
1013
|
+
unless self.read_port then
|
1014
|
+
# No, generate a new one.
|
1015
|
+
# Is it possible to be inout?
|
1016
|
+
if self.inout? then
|
1017
|
+
# Yes, create an inout port.
|
1018
|
+
self.inout(HDLRuby.uniq_name)
|
1019
|
+
else
|
1020
|
+
# No, create an input port.
|
1021
|
+
self.input(HDLRuby.uniq_name)
|
1022
|
+
end
|
889
1023
|
end
|
890
|
-
|
1024
|
+
# Ensure the read port is within current system.
|
1025
|
+
unless self.read_port.scope.system != HDLRuby::High.cur_system then
|
1026
|
+
raise "Cannot read from a port external of current system for channel " + self.name
|
1027
|
+
end
|
1028
|
+
# Performs the read.
|
1029
|
+
self.read_port.read(*args,&ruby_block)
|
891
1030
|
end
|
892
1031
|
|
893
1032
|
## Performs a write on the channel using +args+ and +ruby_block+
|
894
1033
|
# as arguments.
|
1034
|
+
# NOTE:
|
1035
|
+
# * Will generate a port if not present.
|
1036
|
+
# * Will generate an error if a read is tempted while the read
|
1037
|
+
# port has been declared within another system.
|
895
1038
|
def write(*args,&ruby_block)
|
896
|
-
#
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
1039
|
+
# Is there a port to write?
|
1040
|
+
unless self.write_port then
|
1041
|
+
# No, generate a new one.
|
1042
|
+
# Is it possible to be inout?
|
1043
|
+
if self.inout? then
|
1044
|
+
# Yes, create an inout port.
|
1045
|
+
self.inout(HDLRuby.uniq_name)
|
1046
|
+
else
|
1047
|
+
# No, create an output port.
|
1048
|
+
self.output(HDLRuby.uniq_name)
|
1049
|
+
end
|
903
1050
|
end
|
904
|
-
|
1051
|
+
# Ensure the write port is within current system.
|
1052
|
+
unless self.write_port.scope.system != HDLRuby::High.cur_system then
|
1053
|
+
raise "Cannot write from a port external of current system for channel " + self.name
|
1054
|
+
end
|
1055
|
+
# Performs the write.
|
1056
|
+
self.write_port.write(*args,&ruby_block)
|
905
1057
|
end
|
1058
|
+
|
906
1059
|
|
907
1060
|
## Performs a reset on the channel using +args+ and +ruby_block+
|
908
1061
|
# as arguments.
|
@@ -925,6 +1078,8 @@ module HDLRuby::High::Std
|
|
925
1078
|
# Create a new object wrapper for +obj+.
|
926
1079
|
def initialize(obj)
|
927
1080
|
@obj = obj
|
1081
|
+
|
1082
|
+
@scope = HDLRuby::High.cur_scope
|
928
1083
|
end
|
929
1084
|
|
930
1085
|
# Port read with arguments +args+ executing +ruby_block+ in
|
data/lib/HDLRuby/std/memory.rb
CHANGED
@@ -889,11 +889,11 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
|
|
889
889
|
rst_name = br_rsts[:winc].to_sym
|
890
890
|
else
|
891
891
|
rst_name = rst.name
|
892
|
-
|
892
|
+
writer_input rst_name
|
893
893
|
end
|
894
894
|
# Declares the address counter.
|
895
895
|
[size.width-1].inner :abus_w
|
896
|
-
|
896
|
+
writer_inout :abus_w
|
897
897
|
|
898
898
|
# Defines the write procedure at address +addr+
|
899
899
|
# using +target+ as target of access result.
|
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.3.
|
4
|
+
version: 2.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|