HDLRuby 2.2.14 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -8
- data/lib/HDLRuby/hdr_samples/linear_test.rb +235 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +2 -2
- data/lib/HDLRuby/hdr_samples/ruby_fir_hw.rb +96 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +3 -2
- data/lib/HDLRuby/hdr_samples/with_linear.rb +166 -0
- data/lib/HDLRuby/hdr_samples/with_loop.rb +69 -0
- data/lib/HDLRuby/hdr_samples/with_memory.rb +13 -3
- data/lib/HDLRuby/hdrcc.rb +1 -1
- data/lib/HDLRuby/hruby_high.rb +12 -4
- data/lib/HDLRuby/hruby_low.rb +25 -28
- data/lib/HDLRuby/hruby_low2c.rb +10 -5
- data/lib/HDLRuby/hruby_low2high.rb +1 -1
- data/lib/HDLRuby/hruby_low2vhd.rb +63 -48
- data/lib/HDLRuby/hruby_low_fix_types.rb +6 -2
- data/lib/HDLRuby/hruby_low_mutable.rb +2 -1
- data/lib/HDLRuby/hruby_low_resolve.rb +7 -4
- data/lib/HDLRuby/hruby_low_without_concat.rb +8 -4
- data/lib/HDLRuby/hruby_types.rb +82 -72
- data/lib/HDLRuby/hruby_verilog.rb +9 -1
- data/lib/HDLRuby/sim/hruby_sim.h +21 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +254 -18
- data/lib/HDLRuby/std/channel.rb +103 -32
- data/lib/HDLRuby/std/fixpoint.rb +15 -6
- data/lib/HDLRuby/std/linear.rb +317 -0
- data/lib/HDLRuby/std/loop.rb +101 -0
- data/lib/HDLRuby/std/memory.rb +1000 -30
- data/lib/HDLRuby/std/task.rb +850 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb0edfa902fbbc4e330f9a7fd8c26dcfc745f8ce5eb8cd73e4c2047cfef7dc68
|
4
|
+
data.tar.gz: 5ddc2948c53b905fb25c0683fc31be5300a2aabff31384c9187dc784c9e66a76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93f86b91bf94ad22b4558ac912f950e79ec9373fafcdcaf2d33e8f1c34f3b77d30beec308f591d95f7ddafdcfda5bd283586216a98c882e12983fbe7301f43df
|
7
|
+
data.tar.gz: 60503ed5b5d45406827329bd6f42b961b9b6c74f47c630f7f0f21bd4d51bcbabffb380608c2287ee7dd8b60b5bb2039eaddd82357920eff3f6b437b40d59d34a
|
data/README.md
CHANGED
@@ -1301,14 +1301,7 @@ __The vector operator__ `[]` is used for building types representing vectors of
|
|
1301
1301
|
<type>[<range>]
|
1302
1302
|
```
|
1303
1303
|
|
1304
|
-
The `<range>` of a vector type indicates the position of the starting and ending bits
|
1305
|
-
is on the left side of the range, the vector is big endian, otherwise it is little endian. Negative values in a range are also possible and indicate positions bellow the radix point. For example, the following code describes a big-endian fixed-point type with 8 bits above the radix point and 4 bits
|
1306
|
-
bellow:
|
1307
|
-
|
1308
|
-
```ruby
|
1309
|
-
bit[7..-4]
|
1310
|
-
```
|
1311
|
-
|
1304
|
+
The `<range>` of a vector type indicates the position of the starting and ending bits.
|
1312
1305
|
A `n..0` range can also be abbreviated to `n+1`. For instance, the two following types are identical:
|
1313
1306
|
|
1314
1307
|
```ruby
|
@@ -2801,6 +2794,19 @@ bit[4,4].inner :sig
|
|
2801
2794
|
|
2802
2795
|
When performing computation with fixed point types, HDLRuby ensures that the result's decimal point position is correct.
|
2803
2796
|
|
2797
|
+
In addition to the fixed point data type, a method is added to the literal objects (Numeric) to convert them to fixed point representation:
|
2798
|
+
|
2799
|
+
```ruby
|
2800
|
+
<litteral>.to_fix(<number of bits after the decimal point>)
|
2801
|
+
```
|
2802
|
+
|
2803
|
+
For example the following code converts a floating point value to a fixed point value with 16 bits after the decimal point:
|
2804
|
+
|
2805
|
+
```
|
2806
|
+
3.178.to_fix(16)
|
2807
|
+
```
|
2808
|
+
|
2809
|
+
|
2804
2810
|
## Channel
|
2805
2811
|
<a name="channel"></a>
|
2806
2812
|
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'std/memory.rb'
|
2
|
+
require 'std/linear.rb'
|
3
|
+
|
4
|
+
include HDLRuby::High::Std
|
5
|
+
|
6
|
+
# Tries for matrix-vector product.
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
# Sample code for testing the linear library.
|
13
|
+
|
14
|
+
system :linear_test do
|
15
|
+
|
16
|
+
# Clock and reset.
|
17
|
+
inner :clk,:rst
|
18
|
+
|
19
|
+
# Request and acknoledge signals.
|
20
|
+
inner :req
|
21
|
+
[8].inner :ack
|
22
|
+
|
23
|
+
|
24
|
+
# Circuit for testing the scaling.
|
25
|
+
|
26
|
+
# Input memory
|
27
|
+
mem_file([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_scale_in)
|
28
|
+
# Output memory
|
29
|
+
mem_file([8],8,clk,rst, winc: :rst).(:mem_scale_out)
|
30
|
+
# Access ports.
|
31
|
+
mem_scale_in.branch(:anum).inner :mem_scale_inP
|
32
|
+
mem_scale_inPs = 8.times.map { |i| mem_scale_inP.wrap(i) }
|
33
|
+
mem_scale_out.branch(:anum).inner :mem_scale_outP
|
34
|
+
mem_scale_outPs = 8.times.map { |i| mem_scale_outP.wrap(i) }
|
35
|
+
|
36
|
+
# Build the scaler.
|
37
|
+
scale([8],clk.posedge,req,ack[0],channel_port(3),
|
38
|
+
mem_scale_inPs,mem_scale_outPs)
|
39
|
+
|
40
|
+
|
41
|
+
# Circuit for testing the parallel addition.
|
42
|
+
|
43
|
+
# Input memories
|
44
|
+
mem_file([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_addn_left_in)
|
45
|
+
mem_file([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_addn_right_in)
|
46
|
+
# Output memory
|
47
|
+
mem_file([8],8,clk,rst, winc: :rst).(:mem_addn_out)
|
48
|
+
# Access ports.
|
49
|
+
mem_addn_left_in.branch(:anum).inner :mem_addn_left_inP
|
50
|
+
mem_addn_left_inPs = 8.times.map { |i| mem_addn_left_inP.wrap(i) }
|
51
|
+
mem_addn_right_in.branch(:anum).inner :mem_addn_right_inP
|
52
|
+
mem_addn_right_inPs = 8.times.map { |i| mem_addn_right_inP.wrap(i) }
|
53
|
+
mem_addn_out.branch(:anum).inner :mem_addn_outP
|
54
|
+
mem_addn_outPs = 8.times.map { |i| mem_addn_outP.wrap(i) }
|
55
|
+
|
56
|
+
# Build the adder.
|
57
|
+
add_n([8],clk.posedge,ack[0],ack[1],mem_addn_left_inPs,
|
58
|
+
mem_addn_right_inPs,mem_addn_outPs)
|
59
|
+
|
60
|
+
|
61
|
+
# Circuit for testing the parallel multiplication.
|
62
|
+
|
63
|
+
# Input memories
|
64
|
+
mem_file([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_muln_left_in)
|
65
|
+
mem_file([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_muln_right_in)
|
66
|
+
# Output memory
|
67
|
+
mem_file([8],8,clk,rst, winc: :rst).(:mem_muln_out)
|
68
|
+
# Access ports.
|
69
|
+
mem_muln_left_in.branch(:anum).inner :mem_muln_left_inP
|
70
|
+
mem_muln_left_inPs = 8.times.map { |i| mem_muln_left_inP.wrap(i) }
|
71
|
+
mem_muln_right_in.branch(:anum).inner :mem_muln_right_inP
|
72
|
+
mem_muln_right_inPs = 8.times.map { |i| mem_muln_right_inP.wrap(i) }
|
73
|
+
mem_muln_out.branch(:anum).inner :mem_muln_outP
|
74
|
+
mem_muln_outPs = 8.times.map { |i| mem_muln_outP.wrap(i) }
|
75
|
+
|
76
|
+
# Build the multer.
|
77
|
+
mul_n([8],clk.posedge,ack[1],ack[2],mem_muln_left_inPs,
|
78
|
+
mem_muln_right_inPs,mem_muln_outPs)
|
79
|
+
|
80
|
+
|
81
|
+
# Circuit for testing the mac
|
82
|
+
# Output signal.
|
83
|
+
[8].inner :acc
|
84
|
+
|
85
|
+
# Build the mac.
|
86
|
+
mac([8],clk.posedge,ack[2],ack[3],channel_port(5), channel_port(6),
|
87
|
+
channel_port(acc))
|
88
|
+
|
89
|
+
|
90
|
+
# Circuit for testing the parallel mac.
|
91
|
+
# Input memory
|
92
|
+
mem_file([8],8,clk,rst, winc: :rst).(:mem_macn1_left_in)
|
93
|
+
# Output memory
|
94
|
+
mem_file([8],8,clk,rst, winc: :rst).(:mem_macn1_out)
|
95
|
+
# Access ports.
|
96
|
+
mem_macn1_left_in.branch(:anum).inner :mem_macn1_left_inP
|
97
|
+
mem_macn1_left_inPs = 8.times.map { |i| mem_macn1_left_inP.wrap(i) }
|
98
|
+
mem_macn1_out.branch(:anum).inner :mem_macn1_outP
|
99
|
+
mem_macn1_outPs = 8.times.map { |i| mem_macn1_outP.wrap(i) }
|
100
|
+
|
101
|
+
# Build the mac.
|
102
|
+
mac_n1([8],clk.posedge,ack[3],ack[4], mem_macn1_left_inPs,
|
103
|
+
channel_port(5), mem_macn1_outPs)
|
104
|
+
|
105
|
+
# Circuit for testing the linearun with mac.
|
106
|
+
# Input memories
|
107
|
+
mem_dual([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_macrn_left_in)
|
108
|
+
mem_dual([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_macrn_right_in)
|
109
|
+
# Access ports.
|
110
|
+
mem_macrn_left_in.branch(:rinc).inner :mem_macrn_left_in_readP
|
111
|
+
mem_macrn_right_in.branch(:rinc).inner :mem_macrn_right_in_readP
|
112
|
+
# Output signal.
|
113
|
+
[8].inner :accr
|
114
|
+
|
115
|
+
# Build the linearun mac.
|
116
|
+
linearun(8,clk.posedge,ack[4],ack[5]) do |ev,req,ack|
|
117
|
+
mac([8],ev,req,ack,mem_macrn_left_in_readP,mem_macrn_right_in_readP,
|
118
|
+
channel_port(accr))
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
# The memory initializer.
|
123
|
+
# Writing ports
|
124
|
+
mem_scale_in.branch(:winc).inner :mem_scale_in_writeP
|
125
|
+
mem_addn_left_in.branch(:winc).inner :mem_addn_left_in_writeP
|
126
|
+
mem_addn_right_in.branch(:winc).inner :mem_addn_right_in_writeP
|
127
|
+
mem_muln_left_in.branch(:winc).inner :mem_muln_left_in_writeP
|
128
|
+
mem_muln_right_in.branch(:winc).inner :mem_muln_right_in_writeP
|
129
|
+
mem_macn1_left_in.branch(:winc).inner :mem_macn1_left_in_writeP
|
130
|
+
mem_macrn_left_in.branch(:winc).inner :mem_macrn_left_in_writeP
|
131
|
+
mem_macrn_right_in.branch(:winc).inner :mem_macrn_right_in_writeP
|
132
|
+
# Filling index
|
133
|
+
[8].inner :idx
|
134
|
+
# Filling counter
|
135
|
+
[3].inner :cnt
|
136
|
+
# Filling value
|
137
|
+
[8].inner :val
|
138
|
+
|
139
|
+
# Start flag
|
140
|
+
inner :start
|
141
|
+
|
142
|
+
# The execution process
|
143
|
+
par(clk.posedge) do
|
144
|
+
hif(rst) { cnt <= 0; val <= 0 }
|
145
|
+
helse do
|
146
|
+
# Step index processing.
|
147
|
+
hif(cnt == 7) do
|
148
|
+
hif(idx < 8) { idx <= idx + 1 }
|
149
|
+
end
|
150
|
+
# Memory filling steps.
|
151
|
+
hcase(idx)
|
152
|
+
hwhen(0) do
|
153
|
+
mem_scale_in_writeP.write(val) do
|
154
|
+
cnt <= cnt + 1; val <= val + 1
|
155
|
+
end
|
156
|
+
end
|
157
|
+
hwhen(1) do
|
158
|
+
mem_addn_left_in_writeP.write(val) do
|
159
|
+
cnt <= cnt + 1; val <= val + 1
|
160
|
+
end
|
161
|
+
end
|
162
|
+
hwhen(2) do
|
163
|
+
mem_addn_right_in_writeP.write(val) do
|
164
|
+
cnt <= cnt + 1; val <= val + 1
|
165
|
+
end
|
166
|
+
end
|
167
|
+
hwhen(3) do
|
168
|
+
mem_muln_left_in_writeP.write(val-24) do
|
169
|
+
cnt <= cnt + 1; val <= val + 1
|
170
|
+
end
|
171
|
+
end
|
172
|
+
hwhen(4) do
|
173
|
+
mem_muln_right_in_writeP.write(val-24) do
|
174
|
+
cnt <= cnt + 1; val <= val + 1
|
175
|
+
end
|
176
|
+
end
|
177
|
+
hwhen(5) do
|
178
|
+
mem_macn1_left_in_writeP.write(val-32) do
|
179
|
+
cnt <= cnt + 1; val <= val + 1
|
180
|
+
end
|
181
|
+
end
|
182
|
+
hwhen(6) do
|
183
|
+
mem_macrn_left_in_writeP.write(val-48) do
|
184
|
+
cnt <= cnt + 1; val <= val + 1
|
185
|
+
end
|
186
|
+
end
|
187
|
+
hwhen(7) do
|
188
|
+
mem_macrn_right_in_writeP.write(val-48) do
|
189
|
+
cnt <= cnt + 1; val <= val + 1
|
190
|
+
end
|
191
|
+
end
|
192
|
+
# Computation steps.
|
193
|
+
helse do
|
194
|
+
hif(start) do
|
195
|
+
req <= 1
|
196
|
+
start <= 0
|
197
|
+
end
|
198
|
+
helse { req <= 0 }
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
# The test bench.
|
205
|
+
timed do
|
206
|
+
req <= 0
|
207
|
+
ack <= 0
|
208
|
+
clk <= 0
|
209
|
+
rst <= 0
|
210
|
+
cnt <= 0
|
211
|
+
idx <= 0
|
212
|
+
val <= 0
|
213
|
+
start <= 0
|
214
|
+
!10.ns
|
215
|
+
clk <= 1
|
216
|
+
!10.ns
|
217
|
+
# Reset
|
218
|
+
clk <= 0
|
219
|
+
rst <= 1
|
220
|
+
!10.ns
|
221
|
+
clk <= 1
|
222
|
+
!10.ns
|
223
|
+
clk <= 0
|
224
|
+
rst <= 0
|
225
|
+
start <= 1
|
226
|
+
!10.ns
|
227
|
+
# Run
|
228
|
+
128.times do
|
229
|
+
clk <= 1
|
230
|
+
!10.ns
|
231
|
+
clk <= 0
|
232
|
+
!10.ns
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -4,8 +4,8 @@ system :rom4_8 do
|
|
4
4
|
[2..0].input :addr
|
5
5
|
[7..0].output :data0,:data1,:data2
|
6
6
|
|
7
|
-
bit[7..0][0..7].constant content0: [1,2,3,4,5,6,7]
|
8
|
-
bit[7..0][-8].constant content1: [1,2,3,4,5,6,7]
|
7
|
+
bit[7..0][0..7].constant content0: [0,1,2,3,4,5,6,7]
|
8
|
+
bit[7..0][-8].constant content1: [0,1,2,3,4,5,6,7]
|
9
9
|
bit[7..0][-8].constant content2: (8).times.to_a
|
10
10
|
|
11
11
|
data0 <= content0[addr]
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'std/memory.rb'
|
2
|
+
require 'std/linear.rb'
|
3
|
+
# require 'std/timing.rb'
|
4
|
+
|
5
|
+
include HDLRuby::High::Std
|
6
|
+
|
7
|
+
|
8
|
+
system :fir do |typ,iChannel,oChannel,coefs|
|
9
|
+
input :clk, :rst, :req
|
10
|
+
output :ack
|
11
|
+
# Declare the input port.
|
12
|
+
iChannel.input :iPort
|
13
|
+
# Declare the output port.
|
14
|
+
oChannel.output :oPort
|
15
|
+
|
16
|
+
# Declares the data registers.
|
17
|
+
datas = coefs.map.with_index do |coef,id|
|
18
|
+
coef.type.inner :"data_#{id}"
|
19
|
+
end
|
20
|
+
|
21
|
+
inner :req2
|
22
|
+
|
23
|
+
|
24
|
+
# Generate the mac pipeline.
|
25
|
+
mac_np(typ,clk.posedge,req2,ack,
|
26
|
+
datas.map{|data| channel_port(data) },
|
27
|
+
coefs.map{|coef| channel_port(coef) }, oPort)
|
28
|
+
|
29
|
+
# Generate the data transfer through the pipeline.
|
30
|
+
par(clk.posedge) do
|
31
|
+
req2 <= 0
|
32
|
+
hif(rst) { datas.each { |d| d <= 0 } }
|
33
|
+
hif(req) do
|
34
|
+
iPort.read(datas[0]) do
|
35
|
+
# datas.each_cons(2) { |d0,d1| d1 <= d0 }
|
36
|
+
datas[1..-1] <= datas[0..-2]
|
37
|
+
end
|
38
|
+
req2 <= 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
system :work do
|
48
|
+
|
49
|
+
inner :clk,:rst,:req,:ack
|
50
|
+
|
51
|
+
# The input memory.
|
52
|
+
mem_rom([8],8,clk,rst,
|
53
|
+
[_00000001,_00000010,_00000011,_00000100,
|
54
|
+
_00000101,_00000110,_00000111,_00001000]).(:iMem)
|
55
|
+
# The output memory.
|
56
|
+
mem_dual([8],8,clk,rst).(:oMem)
|
57
|
+
# The coefficients.
|
58
|
+
coefs = [_11001100,_00110011,_10101010,_01010101,
|
59
|
+
_11110000,_00001111,_11100011,_00011100]
|
60
|
+
|
61
|
+
# The filter
|
62
|
+
fir([8],iMem.branch(:rinc),oMem.branch(:winc),coefs).(:my_fir).(clk,rst,req,ack)
|
63
|
+
|
64
|
+
# iMem.branch(:rinc).inner :port
|
65
|
+
# [8].inner :a
|
66
|
+
# par(clk.posedge) do
|
67
|
+
# hif(req) { port.read(a) }
|
68
|
+
# end
|
69
|
+
|
70
|
+
timed do
|
71
|
+
req <= 0
|
72
|
+
clk <= 0
|
73
|
+
rst <= 0
|
74
|
+
!10.ns
|
75
|
+
clk <= 1
|
76
|
+
!10.ns
|
77
|
+
clk <= 0
|
78
|
+
rst <= 1
|
79
|
+
!10.ns
|
80
|
+
clk <= 1
|
81
|
+
!10.ns
|
82
|
+
clk <= 0
|
83
|
+
rst <= 0
|
84
|
+
!10.ns
|
85
|
+
clk <= 1
|
86
|
+
!10.ns
|
87
|
+
req <= 1
|
88
|
+
clk <= 0
|
89
|
+
64.times do
|
90
|
+
!10.ns
|
91
|
+
clk <= 1
|
92
|
+
!10.ns
|
93
|
+
clk <= 0
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'std/memory.rb'
|
2
|
+
require 'std/linear.rb'
|
3
|
+
|
4
|
+
include HDLRuby::High::Std
|
5
|
+
|
6
|
+
# Tries for matrix-vector product.
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
# Testing.
|
13
|
+
system :testmat do
|
14
|
+
|
15
|
+
inner :clk,:rst, :req
|
16
|
+
|
17
|
+
# Input memories
|
18
|
+
# mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memL0)
|
19
|
+
# The first memory is 4-bank for testing purpose.
|
20
|
+
mem_bank([8],4,256/4,clk,rst, rinc: :rst,winc: :rst).(:memL0)
|
21
|
+
# The others are standard dual-edge memories.
|
22
|
+
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memL1)
|
23
|
+
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memR)
|
24
|
+
# Access ports.
|
25
|
+
memL0.branch(:rinc).inner :readL0
|
26
|
+
memL1.branch(:rinc).inner :readL1
|
27
|
+
memR.branch(:rinc).inner :readR
|
28
|
+
|
29
|
+
# Prepares the left and acc arrays.
|
30
|
+
lefts = [readL0, readL1]
|
31
|
+
|
32
|
+
# Accumulators memory.
|
33
|
+
mem_file([8],2,clk,rst,rinc: :rst).(:memAcc)
|
34
|
+
memAcc.branch(:anum).inner :accs
|
35
|
+
accs_out = [accs.wrap(0), accs.wrap(1)]
|
36
|
+
|
37
|
+
# Layer 0 ack.
|
38
|
+
inner :ack0
|
39
|
+
|
40
|
+
# Instantiate the matrix product.
|
41
|
+
mac_n1([8],clk,req,ack0,lefts,readR,accs_out)
|
42
|
+
|
43
|
+
# Translation.
|
44
|
+
# Translation memory.
|
45
|
+
mem_file([8],2,clk,rst,winc: :rst).(:memT)
|
46
|
+
# Tarnslation result
|
47
|
+
mem_file([8],2,clk,rst,rinc: :rst).(:memF)
|
48
|
+
# Access ports.
|
49
|
+
memT.branch(:anum).inner :readT
|
50
|
+
memF.branch(:anum).inner :writeF
|
51
|
+
regRs = [ readT.wrap(0), readT.wrap(1) ]
|
52
|
+
regLs = [ accs.wrap(0), accs.wrap(1) ]
|
53
|
+
regs = [ writeF.wrap(0), writeF.wrap(1) ]
|
54
|
+
|
55
|
+
# Translater ack.
|
56
|
+
inner :ackT
|
57
|
+
|
58
|
+
# Instantiate the translater.
|
59
|
+
add_n([8],clk,ack0,ackT,regLs,regRs,regs)
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
# Second layer.
|
64
|
+
# Input memories.
|
65
|
+
mem_dual([8],2,clk,rst, rinc: :rst,winc: :rst).(:mem2L0)
|
66
|
+
# Access ports.
|
67
|
+
mem2L0.branch(:rinc).inner :read2L0
|
68
|
+
# memAcc.branch(:rinc).inner :accsR
|
69
|
+
memF.branch(:rinc).inner :readF
|
70
|
+
|
71
|
+
# Second layer ack.
|
72
|
+
inner :ack1
|
73
|
+
|
74
|
+
# Result.
|
75
|
+
[8].inner :res
|
76
|
+
|
77
|
+
sub do
|
78
|
+
# Instantiate the second matrix product.
|
79
|
+
# mac([8],clk,req,read2L0,accsR,res)
|
80
|
+
mac([8],clk,ackT,ack1,read2L0,readF,channel_port(res))
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
# 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
|
91
|
+
inner :fill, :fill2
|
92
|
+
[8].inner :val
|
93
|
+
par(clk.posedge) do
|
94
|
+
hif(fill) do
|
95
|
+
writeL0.write(val)
|
96
|
+
writeL1.write(val+1)
|
97
|
+
writeR.write(val+1)
|
98
|
+
end
|
99
|
+
hif(fill2) do
|
100
|
+
write2L0.write(val+2)
|
101
|
+
writeT.write(val+2)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
timed do
|
106
|
+
req <= 0
|
107
|
+
clk <= 0
|
108
|
+
rst <= 0
|
109
|
+
fill <= 0
|
110
|
+
fill2 <= 0
|
111
|
+
val <= 0
|
112
|
+
!10.ns
|
113
|
+
# Reset the memories.
|
114
|
+
rst <= 1
|
115
|
+
!10.ns
|
116
|
+
clk <= 1
|
117
|
+
!10.ns
|
118
|
+
# Fill the memories.
|
119
|
+
# First layer
|
120
|
+
clk <= 0
|
121
|
+
rst <= 0
|
122
|
+
fill <= 1
|
123
|
+
!10.ns
|
124
|
+
256.times do |i|
|
125
|
+
clk <= 1
|
126
|
+
!10.ns
|
127
|
+
clk <= 0
|
128
|
+
val <= val + 1
|
129
|
+
!10.ns
|
130
|
+
end
|
131
|
+
fill <= 0
|
132
|
+
clk <= 1
|
133
|
+
!10.ns
|
134
|
+
# Second layer
|
135
|
+
clk <= 0
|
136
|
+
rst <= 0
|
137
|
+
fill2 <= 1
|
138
|
+
!10.ns
|
139
|
+
2.times do |i|
|
140
|
+
clk <= 1
|
141
|
+
!10.ns
|
142
|
+
clk <= 0
|
143
|
+
val <= val + 1
|
144
|
+
!10.ns
|
145
|
+
end
|
146
|
+
fill2 <= 0
|
147
|
+
clk <= 1
|
148
|
+
!10.ns
|
149
|
+
clk <= 0
|
150
|
+
!10.ns
|
151
|
+
clk <= 1
|
152
|
+
!10.ns
|
153
|
+
clk <= 0
|
154
|
+
!10.ns
|
155
|
+
# Launch the computation
|
156
|
+
clk <= 0
|
157
|
+
req <= 1
|
158
|
+
!10.ns
|
159
|
+
300.times do
|
160
|
+
clk <= 1
|
161
|
+
!10.ns
|
162
|
+
clk <= 0
|
163
|
+
!10.ns
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|