HDLRuby 2.4.12 → 2.4.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/HDLRuby/hdr_samples/WithMultiChannelExpVerilog/with_multi_channels_hs_32.v +1277 -0
- data/lib/HDLRuby/hdr_samples/WithMultiChannelExpVerilog/with_multi_channels_qu_213.v +1345 -0
- data/lib/HDLRuby/hdr_samples/WithMultiChannelExpVerilog/with_multi_channels_qu_222.v +1339 -0
- data/lib/HDLRuby/hdr_samples/WithMultiChannelExpVerilog/with_multi_channels_rg_23.v +1248 -0
- data/lib/HDLRuby/hdr_samples/make_multi_channels_v.rb +24 -0
- data/lib/HDLRuby/hdr_samples/make_multi_channels_vcd.rb +17 -17
- data/lib/HDLRuby/hdr_samples/with_connector.rb +245 -0
- data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +98 -0
- data/lib/HDLRuby/hdr_samples/with_multi_channels.rb +109 -201
- data/lib/HDLRuby/hruby_tools.rb +7 -1
- data/lib/HDLRuby/sim/hruby_sim_calc.c +3 -1
- data/lib/HDLRuby/std/connector.rb +110 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +10 -2
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
# Script for generating the vcd files.
|
|
3
|
+
|
|
4
|
+
# The configuration scenarii
|
|
5
|
+
$scenarii = [
|
|
6
|
+
[:_clk2_clk2, :register], # 0
|
|
7
|
+
[:_clk2_nclk2, :register], # 1
|
|
8
|
+
[:_clk2_clk3, :register], # 2
|
|
9
|
+
[:_clk3_clk2, :register], # 3
|
|
10
|
+
[:_clk2_clk2, :handshake], # 4
|
|
11
|
+
[:_clk2_nclk2, :handshake], # 5
|
|
12
|
+
[:_clk2_clk3, :handshake], # 6
|
|
13
|
+
[:_clk3_clk2, :handshake], # 7
|
|
14
|
+
[:clk2_clk2_clk2, :queue], # 8
|
|
15
|
+
[:clk2_clk2_nclk2, :queue], # 9
|
|
16
|
+
[:clk1_clk2_clk3, :queue], # 10
|
|
17
|
+
[:clk3_clk2_clk1, :queue], # 11
|
|
18
|
+
[:clk2_clk3_clk1, :queue], # 12
|
|
19
|
+
[:clk2_clk1_clk3, :queue], # 13
|
|
20
|
+
]
|
|
21
|
+
$scenarii.each_with_index do |scenarii,i|
|
|
22
|
+
puts "scenario: [#{i}] #{scenarii}"
|
|
23
|
+
`bundle exec ../hdrcc.rb --verilog with_multi_channels.rb WithMultiChannelPaper.V#{i} #{i}`
|
|
24
|
+
end
|
|
@@ -3,23 +3,23 @@
|
|
|
3
3
|
|
|
4
4
|
# The configuration scenarii
|
|
5
5
|
$scenarii = [
|
|
6
|
-
[:
|
|
7
|
-
[:
|
|
8
|
-
[:
|
|
9
|
-
[:
|
|
10
|
-
[:
|
|
11
|
-
[:
|
|
12
|
-
[:
|
|
13
|
-
[:
|
|
14
|
-
[:
|
|
15
|
-
[:
|
|
16
|
-
[:
|
|
17
|
-
[:
|
|
18
|
-
[:
|
|
19
|
-
[:
|
|
20
|
-
[:double,:queue] # 14
|
|
6
|
+
[:_clk2_clk2, :register], # 0
|
|
7
|
+
[:_clk2_nclk2, :register], # 1
|
|
8
|
+
[:_clk2_clk3, :register], # 2
|
|
9
|
+
[:_clk3_clk2, :register], # 3
|
|
10
|
+
[:_clk2_clk2, :handshake], # 4
|
|
11
|
+
[:_clk2_nclk2, :handshake], # 5
|
|
12
|
+
[:_clk2_clk3, :handshake], # 6
|
|
13
|
+
[:_clk3_clk2, :handshake], # 7
|
|
14
|
+
[:clk2_clk2_clk2, :queue], # 8
|
|
15
|
+
[:clk2_clk2_nclk2, :queue], # 9
|
|
16
|
+
[:clk1_clk2_clk3, :queue], # 10
|
|
17
|
+
[:clk3_clk2_clk1, :queue], # 11
|
|
18
|
+
[:clk2_clk3_clk1, :queue], # 12
|
|
19
|
+
[:clk2_clk1_clk3, :queue], # 13
|
|
21
20
|
]
|
|
22
|
-
|
|
21
|
+
$scenarii.each_with_index do |scenarii,i|
|
|
22
|
+
puts "scenario: [#{i}] #{scenarii}"
|
|
23
23
|
`bundle exec ../hdrcc.rb -S --vcd with_multi_channels.rb WithMultiChannelPaper #{i}`
|
|
24
|
-
`mv WithMultiChannelPaper/hruby_simulator.vcd WithMultiChannelPaper/#{i.to_s.to_s.rjust(2,"0")}_#{
|
|
24
|
+
`mv WithMultiChannelPaper/hruby_simulator.vcd WithMultiChannelPaper/#{i.to_s.to_s.rjust(2,"0")}_#{scenarii[0]}_#{scenarii[1]}.vcd`
|
|
25
25
|
end
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
require 'std/channel.rb'
|
|
2
|
+
require 'std/connector.rb'
|
|
3
|
+
|
|
4
|
+
include HDLRuby::High::Std
|
|
5
|
+
|
|
6
|
+
# Sample for testing the connectors of channels.
|
|
7
|
+
|
|
8
|
+
# Channel describing a buffered queue storing data of +typ+ type of +depth+,
|
|
9
|
+
# synchronized through clk and reset on +rst+.
|
|
10
|
+
channel(:queue) do |typ,depth,clk,rst|
|
|
11
|
+
# The inner buffer of the queue.
|
|
12
|
+
typ[-depth].inner :buffer
|
|
13
|
+
# The read and write pointers.
|
|
14
|
+
[depth.width].inner :rptr, :wptr
|
|
15
|
+
# The read and write command signals.
|
|
16
|
+
inner :rreq, :wreq
|
|
17
|
+
# The read and write ack signals.
|
|
18
|
+
inner :rack, :wack
|
|
19
|
+
# The read/write data registers.
|
|
20
|
+
typ.inner :rdata, :wdata
|
|
21
|
+
|
|
22
|
+
# The flags telling of the channel is synchronized
|
|
23
|
+
inner :rsync, :wsync
|
|
24
|
+
|
|
25
|
+
# The process handling the decoupled access to the buffer.
|
|
26
|
+
par(clk.posedge) do
|
|
27
|
+
hif(rst) { rptr <= 0; wptr <= 0 }
|
|
28
|
+
helse do
|
|
29
|
+
hif(~rsync) do
|
|
30
|
+
hif (~rreq) { rack <= 0 }
|
|
31
|
+
hif(rreq & (~rack) & (rptr != wptr)) do
|
|
32
|
+
rdata <= buffer[rptr]
|
|
33
|
+
rptr <= (rptr + 1) % depth
|
|
34
|
+
rack <= 1
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
hif(~wsync) do
|
|
39
|
+
hif (~wreq) { wack <= 0 }
|
|
40
|
+
hif(wreq & (~wack) & (((wptr+1) % depth) != rptr)) do
|
|
41
|
+
buffer[wptr] <= wdata
|
|
42
|
+
wptr <= (wptr + 1) % depth
|
|
43
|
+
wack <= 1
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
reader_output :rreq, :rptr, :rsync
|
|
50
|
+
reader_input :rdata, :rack, :wptr, :buffer
|
|
51
|
+
|
|
52
|
+
# The read primitive.
|
|
53
|
+
reader do |blk,target|
|
|
54
|
+
if (cur_behavior.on_event?(clk.posedge,clk.negedge)) then
|
|
55
|
+
# Same clk event, synchrone case: perform a direct access.
|
|
56
|
+
# Now perform the access.
|
|
57
|
+
top_block.unshift do
|
|
58
|
+
rsync <= 1
|
|
59
|
+
rreq <= 0
|
|
60
|
+
end
|
|
61
|
+
seq do
|
|
62
|
+
hif(rptr != wptr) do
|
|
63
|
+
# target <= rdata
|
|
64
|
+
target <= buffer[rptr]
|
|
65
|
+
rptr <= (rptr + 1) % depth
|
|
66
|
+
blk.call if blk
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
else
|
|
70
|
+
# Different clk event, perform a decoupled access.
|
|
71
|
+
top_block.unshift do
|
|
72
|
+
rsync <= 0
|
|
73
|
+
rreq <= 0
|
|
74
|
+
end
|
|
75
|
+
par do
|
|
76
|
+
hif (~rack) { rreq <= 1 }
|
|
77
|
+
helsif(rreq) do
|
|
78
|
+
rreq <= 0
|
|
79
|
+
target <= rdata
|
|
80
|
+
blk.call if blk
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
writer_output :wreq, :wdata, :wptr, :wsync, :buffer
|
|
87
|
+
writer_input :wack, :rptr
|
|
88
|
+
|
|
89
|
+
# The write primitive.
|
|
90
|
+
writer do |blk,target|
|
|
91
|
+
if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
|
|
92
|
+
# Same clk event, synchrone case: perform a direct access.
|
|
93
|
+
top_block.unshift do
|
|
94
|
+
wsync <= 1
|
|
95
|
+
wreq <= 0
|
|
96
|
+
end
|
|
97
|
+
hif(((wptr+1) % depth) != rptr) do
|
|
98
|
+
buffer[wptr] <= target
|
|
99
|
+
wptr <= (wptr + 1) % depth
|
|
100
|
+
blk.call if blk
|
|
101
|
+
end
|
|
102
|
+
else
|
|
103
|
+
# Different clk event, asynchrone case: perform a decoupled access.
|
|
104
|
+
top_block.unshift do
|
|
105
|
+
wsync <= 0
|
|
106
|
+
wreq <= 0
|
|
107
|
+
end
|
|
108
|
+
seq do
|
|
109
|
+
hif (~wack) do
|
|
110
|
+
wreq <= 1
|
|
111
|
+
wdata <= target
|
|
112
|
+
end
|
|
113
|
+
helsif(wreq) do
|
|
114
|
+
wreq <= 0
|
|
115
|
+
blk.call if blk
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# Module for testing the connector.
|
|
126
|
+
system :with_connectors do
|
|
127
|
+
inner :clk, :rst
|
|
128
|
+
|
|
129
|
+
# First tester.
|
|
130
|
+
[4].inner :counter
|
|
131
|
+
[4*4].inner :res
|
|
132
|
+
inner :ack_in, :ack_out
|
|
133
|
+
|
|
134
|
+
# The input queue.
|
|
135
|
+
queue(bit[4],4,clk,rst).(:in_qu)
|
|
136
|
+
|
|
137
|
+
# The middle queues.
|
|
138
|
+
mid_qus = 4.times.map do |i|
|
|
139
|
+
queue(bit[4],4,clk,rst).(:"mid_qu#{i}")
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# The output queue.
|
|
143
|
+
queue(bit[4*4],4,clk,rst).(:out_qu)
|
|
144
|
+
|
|
145
|
+
# Connect the input queue to the middle queues.
|
|
146
|
+
duplicator(bit[4],clk.negedge,in_qu,mid_qus)
|
|
147
|
+
|
|
148
|
+
# Connect the middle queues to the output queue.
|
|
149
|
+
merger([bit[4]]*4,clk.negedge,mid_qus,out_qu)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# Second tester.
|
|
153
|
+
[4].inner :counterb
|
|
154
|
+
[4].inner :resb
|
|
155
|
+
inner :ack_inb0, :ack_inb1, :ack_outb
|
|
156
|
+
|
|
157
|
+
# The input queues.
|
|
158
|
+
queue(bit[4],4,clk,rst).(:in_qub0)
|
|
159
|
+
queue(bit[4],4,clk,rst).(:in_qub1)
|
|
160
|
+
|
|
161
|
+
# The output queue.
|
|
162
|
+
queue(bit[4],4,clk,rst).(:out_qub)
|
|
163
|
+
|
|
164
|
+
# Connect then with a serializer.
|
|
165
|
+
serializer(bit[4],clk.negedge,[in_qub0,in_qub1],out_qub)
|
|
166
|
+
|
|
167
|
+
# # Slow version, always work
|
|
168
|
+
# par(clk.posedge) do
|
|
169
|
+
# ack_in <= 0
|
|
170
|
+
# ack_out <= 1
|
|
171
|
+
# hif(rst) { counter <= 0 }
|
|
172
|
+
# helse do
|
|
173
|
+
# hif(ack_out) do
|
|
174
|
+
# ack_out <= 0
|
|
175
|
+
# in_qu.write(counter) do
|
|
176
|
+
# ack_in <= 1
|
|
177
|
+
# counter <= counter + 1
|
|
178
|
+
# end
|
|
179
|
+
# end
|
|
180
|
+
# hif(ack_in) do
|
|
181
|
+
# mid_qu0.read(res_0)
|
|
182
|
+
# mid_qu1.read(res_1)
|
|
183
|
+
# mid_qu2.read(res_2)
|
|
184
|
+
# mid_qu3.read(res_3) { ack_out <= 1 }
|
|
185
|
+
# end
|
|
186
|
+
# end
|
|
187
|
+
# end
|
|
188
|
+
|
|
189
|
+
# Fast version but assumes connected channels are blocking
|
|
190
|
+
par(clk.posedge) do
|
|
191
|
+
ack_in <= 0
|
|
192
|
+
ack_inb0 <= 0
|
|
193
|
+
ack_inb1 <= 0
|
|
194
|
+
hif(rst) { counter <= 0; counterb <= 0 }
|
|
195
|
+
helse do
|
|
196
|
+
in_qu.write(counter) do
|
|
197
|
+
ack_in <= 1
|
|
198
|
+
counter <= counter + 1
|
|
199
|
+
end
|
|
200
|
+
hif(ack_in) do
|
|
201
|
+
out_qu.read(res)
|
|
202
|
+
end
|
|
203
|
+
hif(~ack_inb0) do
|
|
204
|
+
in_qub0.write(counterb) do
|
|
205
|
+
ack_inb0 <= 1
|
|
206
|
+
counterb <= counterb + 1
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
helse do
|
|
210
|
+
in_qub1.write(counterb) do
|
|
211
|
+
ack_inb1 <= 1
|
|
212
|
+
counterb <= counterb + 1
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
hif(ack_inb0 | ack_inb1) do
|
|
216
|
+
out_qub.read(resb)
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
timed do
|
|
222
|
+
clk <= 0
|
|
223
|
+
rst <= 0
|
|
224
|
+
!10.ns
|
|
225
|
+
clk <= 1
|
|
226
|
+
!10.ns
|
|
227
|
+
clk <= 0
|
|
228
|
+
rst <= 1
|
|
229
|
+
!10.ns
|
|
230
|
+
clk <= 1
|
|
231
|
+
!10.ns
|
|
232
|
+
clk <= 0
|
|
233
|
+
!10.ns
|
|
234
|
+
clk <= 1
|
|
235
|
+
!10.ns
|
|
236
|
+
clk <= 0
|
|
237
|
+
rst <= 0
|
|
238
|
+
16.times do
|
|
239
|
+
!10.ns
|
|
240
|
+
clk <= 1
|
|
241
|
+
!10.ns
|
|
242
|
+
clk <= 0
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'std/memory.rb'
|
|
2
|
+
require "std/fixpoint.rb"
|
|
3
|
+
require 'std/channel.rb'
|
|
4
|
+
require 'std/connector.rb'
|
|
5
|
+
|
|
6
|
+
include HDLRuby::High::Std
|
|
7
|
+
|
|
8
|
+
system :channel_connector do
|
|
9
|
+
# データ型の宣言
|
|
10
|
+
integer_width = 4 # 整数部のビット幅
|
|
11
|
+
decimal_width = 4 # 実数部のビット幅
|
|
12
|
+
address_width = 4 # lutのアドレスのビット幅
|
|
13
|
+
typ = signed[integer_width + decimal_width] # データ型
|
|
14
|
+
|
|
15
|
+
inputs_x = _00010011
|
|
16
|
+
inputs_h = _10100001
|
|
17
|
+
columns = [2, 2, 1]
|
|
18
|
+
|
|
19
|
+
inner :clk, # clock
|
|
20
|
+
:rst, # reset
|
|
21
|
+
:req, # request
|
|
22
|
+
:fill # 入力値のメモリへの書き込み
|
|
23
|
+
|
|
24
|
+
# inputs_x = quantize(inputs_x, typ, decimal_width)
|
|
25
|
+
# inputs_h = quantize(inputs_h, typ, decimal_width)
|
|
26
|
+
|
|
27
|
+
mem_rom(typ, columns[0], clk, rst, inputs_x, rinc: :rst, winc: :rst).(:rom_inputs_x) # 入力値を格納するrom(x)
|
|
28
|
+
|
|
29
|
+
mem_rom(typ, columns[0], clk, rst, inputs_h, rinc: :rst, winc: :rst).(:rom_inputs_h) # 入力値を格納するrom(h)
|
|
30
|
+
|
|
31
|
+
mem_dual(typ, columns[0], clk, rst, rinc: :rst, winc: :rst).(:ram_inputs_serializer) #
|
|
32
|
+
|
|
33
|
+
mem_dual(typ, columns[0]*2, clk, rst, rinc: :rst, winc: :rst).(:ram_inputs_merger) #
|
|
34
|
+
|
|
35
|
+
reader_inputs_x = rom_inputs_x.branch(:rinc) #入力値xの読みだし用branch
|
|
36
|
+
reader_inputs_h = rom_inputs_h.branch(:rinc) #入力値hの読みだし用branch
|
|
37
|
+
writer_inputs_serializer = ram_inputs_serializer.branch(:winc) #入力値を合成した値の書き込み用branch
|
|
38
|
+
writer_inputs_meger = ram_inputs_merger.branch(:winc) #入力値を合成した値の書き込み用branch
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
serializer(typ,clk.negedge,[reader_inputs_x,reader_inputs_h],writer_inputs_serializer)
|
|
42
|
+
|
|
43
|
+
# merger([typ]*2,clk.negedge,[reader_inputs_x,reader_inputs_h], writer_inputs_meger)
|
|
44
|
+
|
|
45
|
+
# duplicator(typ,clk.negedge,reader_inputs_r,[])
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
timed do
|
|
49
|
+
# リセット
|
|
50
|
+
clk <= 0
|
|
51
|
+
rst <= 0
|
|
52
|
+
req <= 0
|
|
53
|
+
fill <= 0
|
|
54
|
+
!10.ps
|
|
55
|
+
|
|
56
|
+
# メモリ読み出し位置の初期化
|
|
57
|
+
rst <= 1
|
|
58
|
+
!10.ps
|
|
59
|
+
clk <= 1
|
|
60
|
+
!10.ps
|
|
61
|
+
clk <= 0
|
|
62
|
+
!10.ps
|
|
63
|
+
clk <= 1
|
|
64
|
+
!10.ps
|
|
65
|
+
|
|
66
|
+
# パラメータのメモリへの書き込み
|
|
67
|
+
clk <= 0
|
|
68
|
+
rst <= 0
|
|
69
|
+
fill <= 1
|
|
70
|
+
|
|
71
|
+
!10.ps
|
|
72
|
+
10.times do |i|
|
|
73
|
+
clk <= 1
|
|
74
|
+
!10.ps
|
|
75
|
+
clk <= 0
|
|
76
|
+
!10.ps
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
fill <= 0
|
|
80
|
+
clk <= 1
|
|
81
|
+
!10.ps
|
|
82
|
+
|
|
83
|
+
# 計算の実行
|
|
84
|
+
clk <= 0
|
|
85
|
+
req <= 1
|
|
86
|
+
!10.ps
|
|
87
|
+
clk <= 1
|
|
88
|
+
!10.ps
|
|
89
|
+
clk <= 0
|
|
90
|
+
!10.ps
|
|
91
|
+
30.times do
|
|
92
|
+
clk <= 1
|
|
93
|
+
!10.ps
|
|
94
|
+
clk <= 0
|
|
95
|
+
!10.ps
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -10,36 +10,41 @@ channel(:queue) do |typ,depth,clk,rst|
|
|
|
10
10
|
# The read and write pointers.
|
|
11
11
|
[depth.width].inner :rptr, :wptr
|
|
12
12
|
# The read and write command signals.
|
|
13
|
-
inner :
|
|
13
|
+
inner :rreq, :wreq
|
|
14
14
|
# The read and write ack signals.
|
|
15
15
|
inner :rack, :wack
|
|
16
|
-
# The ack check deactivator (for synchron accesses).
|
|
17
|
-
inner :hrack, :hwack
|
|
18
16
|
# The read/write data registers.
|
|
19
17
|
typ.inner :rdata, :wdata
|
|
20
18
|
|
|
19
|
+
# The flags telling of the channel is synchronized
|
|
20
|
+
inner :rsync, :wsync
|
|
21
|
+
|
|
21
22
|
# The process handling the decoupled access to the buffer.
|
|
22
23
|
par(clk.posedge) do
|
|
23
|
-
# rack <= 0
|
|
24
|
-
# wack <= 0
|
|
25
|
-
hif (~rcmd) { rack <= 0 }
|
|
26
|
-
hif (~wcmd) { wack <= 0 }
|
|
27
24
|
hif(rst) { rptr <= 0; wptr <= 0 }
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
25
|
+
helse do
|
|
26
|
+
hif(~rsync) do
|
|
27
|
+
hif (~rreq) { rack <= 0 }
|
|
28
|
+
hif(rreq & (~rack) & (rptr != wptr)) do
|
|
29
|
+
rdata <= buffer[rptr]
|
|
30
|
+
rptr <= (rptr + 1) % depth
|
|
31
|
+
rack <= 1
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
hif(~wsync) do
|
|
36
|
+
hif (~wreq) { wack <= 0 }
|
|
37
|
+
hif(wreq & (~wack) & (((wptr+1) % depth) != rptr)) do
|
|
38
|
+
buffer[wptr] <= wdata
|
|
39
|
+
wptr <= (wptr + 1) % depth
|
|
40
|
+
wack <= 1
|
|
41
|
+
end
|
|
42
|
+
end
|
|
37
43
|
end
|
|
38
44
|
end
|
|
39
|
-
par { rdata <= buffer[rptr] }
|
|
40
45
|
|
|
41
|
-
reader_output :
|
|
42
|
-
reader_input :rdata, :rack
|
|
46
|
+
reader_output :rreq, :rptr, :rsync
|
|
47
|
+
reader_input :rdata, :rack, :wptr, :buffer
|
|
43
48
|
|
|
44
49
|
# The read primitive.
|
|
45
50
|
reader do |blk,target|
|
|
@@ -47,66 +52,64 @@ channel(:queue) do |typ,depth,clk,rst|
|
|
|
47
52
|
# Same clk event, synchrone case: perform a direct access.
|
|
48
53
|
# Now perform the access.
|
|
49
54
|
top_block.unshift do
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
rsync <= 1
|
|
56
|
+
rreq <= 0
|
|
52
57
|
end
|
|
53
58
|
seq do
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
hif(rptr != wptr) do
|
|
60
|
+
target <= buffer[rptr]
|
|
61
|
+
rptr <= (rptr + 1) % depth
|
|
62
|
+
blk.call if blk
|
|
63
|
+
end
|
|
57
64
|
end
|
|
58
65
|
else
|
|
59
66
|
# Different clk event, perform a decoupled access.
|
|
60
67
|
top_block.unshift do
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
hif(rack) do
|
|
64
|
-
blk.call if blk
|
|
65
|
-
end
|
|
68
|
+
rsync <= 0
|
|
69
|
+
rreq <= 0
|
|
66
70
|
end
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# helse do
|
|
72
|
-
hif(rack==0) do
|
|
73
|
-
rcmd <= 1
|
|
71
|
+
par do
|
|
72
|
+
hif (~rack) { rreq <= 1 }
|
|
73
|
+
helsif(rreq) do
|
|
74
|
+
rreq <= 0
|
|
74
75
|
target <= rdata
|
|
76
|
+
blk.call if blk
|
|
75
77
|
end
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
|
|
80
|
-
writer_output :
|
|
81
|
-
writer_input :wack
|
|
82
|
+
writer_output :wreq, :wdata, :wptr, :wsync, :buffer
|
|
83
|
+
writer_input :wack, :rptr
|
|
82
84
|
|
|
83
85
|
# The write primitive.
|
|
84
86
|
writer do |blk,target|
|
|
85
87
|
if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
|
|
86
88
|
# Same clk event, synchrone case: perform a direct access.
|
|
87
89
|
top_block.unshift do
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
wsync <= 1
|
|
91
|
+
wreq <= 0
|
|
92
|
+
end
|
|
93
|
+
hif(((wptr+1) % depth) != rptr) do
|
|
94
|
+
buffer[wptr] <= target
|
|
95
|
+
wptr <= (wptr + 1) % depth
|
|
96
|
+
blk.call if blk
|
|
90
97
|
end
|
|
91
|
-
wcmd <= 1
|
|
92
|
-
wdata <= target
|
|
93
|
-
blk.call if blk
|
|
94
98
|
else
|
|
95
99
|
# Different clk event, asynchrone case: perform a decoupled access.
|
|
96
100
|
top_block.unshift do
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
hif(wack) do
|
|
100
|
-
blk.call if blk
|
|
101
|
-
end
|
|
101
|
+
wsync <= 0
|
|
102
|
+
wreq <= 0
|
|
102
103
|
end
|
|
103
104
|
seq do
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
hif (~wack) do
|
|
106
|
+
wreq <= 1
|
|
107
|
+
wdata <= target
|
|
108
|
+
end
|
|
109
|
+
helsif(wreq) do
|
|
110
|
+
wreq <= 0
|
|
111
|
+
blk.call if blk
|
|
112
|
+
end
|
|
110
113
|
end
|
|
111
114
|
end
|
|
112
115
|
end
|
|
@@ -181,82 +184,28 @@ channel(:handshake) do |typ|
|
|
|
181
184
|
end
|
|
182
185
|
end
|
|
183
186
|
|
|
184
|
-
# Channel describing a handshake for transmitting data of +typ+ type, reset
|
|
185
|
-
# by +rst+
|
|
186
|
-
channel(:handshake2) do |typ|
|
|
187
|
-
# The data signal.
|
|
188
|
-
typ.inner :data
|
|
189
|
-
# The request and acknowledge.
|
|
190
|
-
inner :req, :ack
|
|
191
|
-
# The write flag
|
|
192
|
-
inner :wf
|
|
193
|
-
|
|
194
|
-
reader_input :ack, :data
|
|
195
|
-
reader_output :req
|
|
196
|
-
|
|
197
|
-
# The read primitive.
|
|
198
|
-
reader do |blk,target|
|
|
199
|
-
top_block.unshift do
|
|
200
|
-
req <= 0
|
|
201
|
-
hif(ack & req == 1) do
|
|
202
|
-
target <= data
|
|
203
|
-
req <= 0
|
|
204
|
-
blk.call if blk
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
hif(ack == 0) do
|
|
208
|
-
req <= 1
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
writer_input :req
|
|
213
|
-
writer_output :ack, :data
|
|
214
|
-
writer_inout :wf
|
|
215
|
-
|
|
216
|
-
# The read primitive.
|
|
217
|
-
writer do |blk,target|
|
|
218
|
-
top_block.unshift do
|
|
219
|
-
ack <= 0
|
|
220
|
-
hif(wf & req & ~ack == 1) do
|
|
221
|
-
data <= target
|
|
222
|
-
ack <= 1
|
|
223
|
-
blk.call if blk
|
|
224
|
-
end
|
|
225
|
-
hif(~req) { wf <= 0 }
|
|
226
|
-
end
|
|
227
|
-
hif(~ack) do
|
|
228
|
-
wf <= 1
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
|
|
233
187
|
|
|
234
|
-
# $mode
|
|
235
|
-
# $mode = :nsync
|
|
236
|
-
# $mode = :async
|
|
237
|
-
# $mode = :proco # Producer / Consummer
|
|
238
|
-
# $mode = :double # Producer and Consummer with double channels.
|
|
188
|
+
# $mode: channel clock, producer clock, consumer clock (n: not clock)
|
|
239
189
|
# $channel = :register
|
|
240
190
|
# $channel = :handshake
|
|
241
191
|
# $channel = :queue
|
|
242
192
|
|
|
243
193
|
# The configuration scenarii
|
|
244
194
|
$scenarii = [
|
|
245
|
-
[:
|
|
246
|
-
[:
|
|
247
|
-
[:
|
|
248
|
-
[:
|
|
249
|
-
[:
|
|
250
|
-
[:
|
|
251
|
-
[:
|
|
252
|
-
[:
|
|
253
|
-
[:
|
|
254
|
-
[:
|
|
255
|
-
[:
|
|
256
|
-
[:
|
|
257
|
-
[:
|
|
258
|
-
[:
|
|
259
|
-
[:double,:queue] # 15
|
|
195
|
+
[:_clk2_clk2, :register], # 0
|
|
196
|
+
[:_clk2_nclk2, :register], # 1
|
|
197
|
+
[:_clk2_clk3, :register], # 2
|
|
198
|
+
[:_clk3_clk2, :register], # 3
|
|
199
|
+
[:_clk2_clk2, :handshake], # 4
|
|
200
|
+
[:_clk2_nclk2, :handshake], # 5
|
|
201
|
+
[:_clk2_clk3, :handshake], # 6
|
|
202
|
+
[:_clk3_clk2, :handshake], # 7
|
|
203
|
+
[:clk2_clk2_clk2, :queue], # 8
|
|
204
|
+
[:clk2_clk2_nclk2, :queue], # 9
|
|
205
|
+
[:clk1_clk2_clk3, :queue], # 10
|
|
206
|
+
[:clk3_clk2_clk1, :queue], # 11
|
|
207
|
+
[:clk2_clk3_clk1, :queue], # 12
|
|
208
|
+
[:clk2_clk1_clk3, :queue], # 13
|
|
260
209
|
]
|
|
261
210
|
|
|
262
211
|
# The configuration
|
|
@@ -266,113 +215,72 @@ puts "scenario: #{$scenarii[ARGV[-1].to_i]}"
|
|
|
266
215
|
|
|
267
216
|
# Testing the queue channel.
|
|
268
217
|
system :test_queue do
|
|
269
|
-
inner :
|
|
218
|
+
inner :rst, :clk1, :clk2, :clk3
|
|
270
219
|
[8].inner :idata, :odata, :odata2
|
|
271
220
|
[4].inner :counter
|
|
272
221
|
|
|
222
|
+
|
|
223
|
+
# Assign the clocks
|
|
224
|
+
mode = $mode.to_s.split("_")
|
|
225
|
+
if ($channel == :queue) then
|
|
226
|
+
clk_que = send(mode[0])
|
|
227
|
+
end
|
|
228
|
+
ev_pro = mode[1][0] == "n" ?
|
|
229
|
+
send(mode[1][1..-1]).negedge : send(mode[1]).posedge
|
|
230
|
+
ev_con = mode[2][0] == "n" ?
|
|
231
|
+
send(mode[2][1..-1]).negedge : send(mode[2]).posedge
|
|
232
|
+
|
|
233
|
+
# Set up the channel
|
|
273
234
|
if $channel == :register then
|
|
274
235
|
register(bit[8]).(:my_ch)
|
|
275
|
-
register(bit[8]).(:my_ch2)
|
|
276
236
|
elsif $channel == :handshake then
|
|
277
237
|
handshake(bit[8],rst).(:my_ch)
|
|
278
|
-
handshake(bit[8],rst).(:my_ch2)
|
|
279
238
|
elsif $channel == :queue then
|
|
280
|
-
queue(bit[8],
|
|
281
|
-
queue(bit[8],5,clk,rst).(:my_ch2)
|
|
239
|
+
queue(bit[8],3,clk_que,rst).(:my_ch)
|
|
282
240
|
end
|
|
283
241
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
par(ev) do
|
|
290
|
-
hif(rst) do
|
|
291
|
-
counter <= 0
|
|
292
|
-
idata <= 0
|
|
293
|
-
# odata <= 0
|
|
294
|
-
end
|
|
295
|
-
helse do
|
|
296
|
-
hif (counter < 4) do
|
|
297
|
-
my_ch.write(idata) do
|
|
298
|
-
idata <= idata + 1
|
|
299
|
-
counter <= counter + 1
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
helsif ((counter > 10) & (counter < 15)) do
|
|
303
|
-
my_ch.read(odata) do
|
|
304
|
-
# idata <= idata - odata
|
|
305
|
-
counter <= counter + 1
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
helse do
|
|
309
|
-
counter <= counter + 1
|
|
310
|
-
end
|
|
311
|
-
end
|
|
242
|
+
# Producter/consumer mode
|
|
243
|
+
# Producer
|
|
244
|
+
par(ev_pro) do
|
|
245
|
+
hif(rst) do
|
|
246
|
+
idata <= 0
|
|
312
247
|
end
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
par(clk2.posedge) do
|
|
317
|
-
hif(rst) do
|
|
318
|
-
idata <= 0
|
|
319
|
-
end
|
|
320
|
-
helse do
|
|
321
|
-
my_ch.write(idata) do
|
|
322
|
-
idata <= idata + 1
|
|
323
|
-
end
|
|
248
|
+
helse do
|
|
249
|
+
my_ch.write(idata) do
|
|
250
|
+
idata <= idata + 1
|
|
324
251
|
end
|
|
325
252
|
end
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
helse do
|
|
332
|
-
my_ch.read(odata) do
|
|
333
|
-
counter <= counter + 1
|
|
334
|
-
end
|
|
335
|
-
end
|
|
253
|
+
end
|
|
254
|
+
# Consumer
|
|
255
|
+
par(ev_con) do
|
|
256
|
+
hif(rst) do
|
|
257
|
+
counter <= 0
|
|
336
258
|
end
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
hif(rst) do
|
|
341
|
-
counter <= 0
|
|
342
|
-
idata <= 0
|
|
343
|
-
end
|
|
344
|
-
helse do
|
|
345
|
-
my_ch.write(idata) do
|
|
346
|
-
idata <= idata + 1
|
|
347
|
-
end
|
|
348
|
-
my_ch.read(odata) do
|
|
349
|
-
my_ch2.write(odata)
|
|
350
|
-
end
|
|
351
|
-
my_ch2.read(odata2) do
|
|
352
|
-
counter <= counter + 1
|
|
353
|
-
end
|
|
259
|
+
helse do
|
|
260
|
+
my_ch.read(odata) do
|
|
261
|
+
counter <= counter + 1
|
|
354
262
|
end
|
|
355
263
|
end
|
|
356
264
|
end
|
|
357
265
|
|
|
358
266
|
timed do
|
|
359
|
-
|
|
267
|
+
clk1 <= 0
|
|
360
268
|
clk2 <= 0
|
|
361
269
|
clk3 <= 0
|
|
362
270
|
rst <= 0
|
|
363
271
|
!10.ns
|
|
364
|
-
|
|
272
|
+
clk1 <= 1
|
|
365
273
|
!10.ns
|
|
366
|
-
|
|
274
|
+
clk1 <= 0
|
|
367
275
|
rst <= 1
|
|
368
276
|
!3.ns
|
|
369
277
|
clk2 <= 1
|
|
370
278
|
!3.ns
|
|
371
279
|
clk3 <= 0
|
|
372
280
|
!4.ns
|
|
373
|
-
|
|
281
|
+
clk1 <= 1
|
|
374
282
|
!10.ns
|
|
375
|
-
|
|
283
|
+
clk1 <= 0
|
|
376
284
|
!3.ns
|
|
377
285
|
clk2 <= 0
|
|
378
286
|
!3.ns
|
|
@@ -381,9 +289,9 @@ system :test_queue do
|
|
|
381
289
|
rst <= 0
|
|
382
290
|
!2.ns
|
|
383
291
|
64.times do
|
|
384
|
-
|
|
292
|
+
clk1 <= 1
|
|
385
293
|
!10.ns
|
|
386
|
-
|
|
294
|
+
clk1 <= 0
|
|
387
295
|
!3.ns
|
|
388
296
|
clk2 <= ~clk2
|
|
389
297
|
!3.ns
|