HDLRuby 2.2.13 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c52cf9ff8c35896992dd4e79059490544c3d41047235a31660badec7a5773ed
4
- data.tar.gz: 2ec8819e1dfa58be1e73ac35475de83973987627dc87b601820853c0926b8c3b
3
+ metadata.gz: '08a1cfdc289eddf8a849b47ba65bf9fa0516ce40119a0ee2d498f535a5132af7'
4
+ data.tar.gz: 81f0f9897e053b894be99b5ab0c7df634c9b16919d6b0ee7cb272fac039ef44b
5
5
  SHA512:
6
- metadata.gz: '0782e49ba89bacc5316f5bd1ab232b70740f33f51d9381ec82cbbd06fc8eaf4042202dbc9723576405594246786d1b0d7c69187f1918116d3af5eea20abea245'
7
- data.tar.gz: '000342564298bd2f46167c55f877deeab18e7b0c7282bce4e9a07b0485fde3fe3ea17beb5d0635d66c9ba47270ef3071dc222d58ced18e6f2d203adbe0d0dba1'
6
+ metadata.gz: 8083b7a99ce02118442cd4ed084ea391c9bafc34635810499edf51776ef73338335a9a85afa1a2eac3f8a4a7411bf1de8f27d871af0f025b008e25a0bf44d6d8
7
+ data.tar.gz: 28009e1a04aae15416c43e900a05a7dbb9cac0db946af08abfb7dfb5cfdc7cc2f9552cbea010ffb8db295e2bc6b329a339eb0d81da4ce1efc35b222a0b4b195e
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 relatively to the radix point. If the position of the starting bit
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
@@ -0,0 +1,272 @@
1
+ require 'std/memory.rb'
2
+
3
+ include HDLRuby::High::Std
4
+
5
+
6
+ # Sample code for testing the memory library.
7
+
8
+ system :memory_test do
9
+
10
+ # The test step counter.
11
+ [8].inner :step
12
+ # The success counter.
13
+ [4].inner :yay
14
+
15
+ # The clock and reset.
16
+ inner :clk, :rst
17
+
18
+ # The memory address.
19
+ [3].inner :address
20
+ # The value to write to memories.
21
+ [8].inner :value
22
+ # The general result register.
23
+ [8].inner :result
24
+ # The specific result registers.
25
+ [8].inner :res0, :res1, :res2, :res3, :res4, :res5, :res6, :res7
26
+
27
+ # Declares a one-ports synchronous memory.
28
+ mem_sync(1,[8],8,clk.negedge,rst,[:rst]).(:mem_sync_1I)
29
+ # And the corresponding access ports.
30
+ mem_sync_1I.branch(0).inner :mem_sync_1P
31
+
32
+ # Declares a dual-edge memory for address-based accesses.
33
+ mem_dual([8],8,clk,rst,raddr: :rst, waddr: :rst).(:mem_dual0I)
34
+ # And the corresponding access ports.
35
+ mem_dual0I.branch(:raddr).inner :mem_dual_raddrP
36
+ mem_dual0I.branch(:waddr).inner :mem_dual_waddrP
37
+
38
+ # Declares a second dual-edge memory for incremeted accesses.
39
+ mem_dual([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_dual1I)
40
+ # And the corresponding access ports.
41
+ mem_dual1I.branch(:rinc).inner :mem_dual_rincP
42
+ mem_dual1I.branch(:winc).inner :mem_dual_wincP
43
+
44
+ # Declares a thrid dual-edge memory for decremented accesses.
45
+ mem_dual([8],8,clk,rst, rdec: :rst, wdec: :rst).(:mem_dual2I)
46
+ # And the corresponding access ports.
47
+ mem_dual2I.branch(:rdec).inner :mem_dual_rdecP
48
+ mem_dual2I.branch(:wdec).inner :mem_dual_wdecP
49
+
50
+ # Declares a first register file for address-based accesses.
51
+ mem_file([8],8,clk,rst,raddr: :rst, waddr: :rst).(:mem_file0I)
52
+ # And the corresponding access ports.
53
+ mem_file0I.branch(:raddr).inner :mem_file_raddrP
54
+ mem_file0I.branch(:waddr).inner :mem_file_waddrP
55
+
56
+ # Declares a second register file for incremeted accesses.
57
+ mem_file([8],8,clk,rst, rinc: :rst, winc: :rst).(:mem_file1I)
58
+ # And the corresponding access ports.
59
+ mem_file1I.branch(:rinc).inner :mem_file_rincP
60
+ mem_file1I.branch(:winc).inner :mem_file_wincP
61
+
62
+ # Declares a third register file for decremeted accesses.
63
+ mem_file([8],8,clk,rst, rdec: :rst, wdec: :rst).(:mem_file2I)
64
+ # And the corresponding access ports.
65
+ mem_file2I.branch(:rdec).inner :mem_file_rdecP
66
+ mem_file2I.branch(:wdec).inner :mem_file_wdecP
67
+
68
+ # Declares a forth register file for num accesses.
69
+ mem_file([8],8,clk,rst, anum: :rst).(:mem_file3I)
70
+ # And the corresponding access port.
71
+ mem_file3I.branch(:anum).inner :mem_file_anumP
72
+
73
+ # Declares a fifth register file for num accesses.
74
+ mem_file([8],8,clk,rst, anum: :rst).(:mem_file4I)
75
+ # And the corresponding access port: individual accesses.
76
+ mem_file4I.branch(:anum).inner :mem_file_anum1P
77
+ mem_file_fixP = [ mem_file_anum1P.wrap(0), mem_file_anum1P.wrap(1),
78
+ mem_file_anum1P.wrap(2), mem_file_anum1P.wrap(3),
79
+ mem_file_anum1P.wrap(4), mem_file_anum1P.wrap(5),
80
+ mem_file_anum1P.wrap(6), mem_file_anum1P.wrap(7) ]
81
+
82
+
83
+ # Tests the accesses to the memories.
84
+ par(clk.posedge) do
85
+ # Initial address and value.
86
+ hif(rst) { address <= 0; value <= 0 }
87
+
88
+ # Handles the memory accesses.
89
+ hcase(step)
90
+ # Write to mem_sync_1
91
+ hwhen(1) do
92
+ mem_sync_1P.write(address,value) do
93
+ yay <= yay + 1
94
+ address <= address + 1
95
+ value <= value + 1
96
+ end
97
+ end
98
+ # Read from to mem_sync_1
99
+ hwhen(2) do
100
+ mem_sync_1P.read(address,result) do
101
+ yay <= yay + 1
102
+ address <= address + 1
103
+ end
104
+ end
105
+ # Write to mem_dual0 with address
106
+ hwhen(3) do
107
+ mem_dual_waddrP.write(address,value) do
108
+ yay <= yay + 1
109
+ address <= address + 1
110
+ value <= value + 1
111
+ end
112
+ end
113
+ # Read from mem_dual0 with address
114
+ hwhen(4) do
115
+ mem_dual_raddrP.read(address,result) do
116
+ yay <= yay + 1
117
+ address <= address + 1
118
+ end
119
+ end
120
+ # Write to mem_dual1 with increment
121
+ hwhen(5) do
122
+ mem_dual_wincP.write(value) do
123
+ yay <= yay + 1
124
+ value <= value + 1
125
+ end
126
+ end
127
+ # Read from mem_dual1 with increment
128
+ hwhen(6) do
129
+ mem_dual_rincP.read(result) do
130
+ yay <= yay + 1
131
+ end
132
+ end
133
+ # Write to mem_dual2 with decrement
134
+ hwhen(7) do
135
+ mem_dual_wdecP.write(value) do
136
+ yay <= yay + 1
137
+ value <= value + 1
138
+ end
139
+ end
140
+ # Read from mem_dual1 with decrement
141
+ hwhen(8) do
142
+ mem_dual_rdecP.read(result) do
143
+ yay <= yay + 1
144
+ end
145
+ end
146
+ # Write to mem_file0 with address
147
+ hwhen(9) do
148
+ mem_file_waddrP.write(address,value) do
149
+ yay <= yay + 1
150
+ address <= address + 1
151
+ value <= value + 1
152
+ end
153
+ end
154
+ # Read from mem_file0 with address
155
+ hwhen(10) do
156
+ mem_file_raddrP.read(address,result) do
157
+ yay <= yay + 1
158
+ address <= address + 1
159
+ end
160
+ end
161
+ # Write to mem_file1 with increment
162
+ hwhen(11) do
163
+ mem_file_wincP.write(value) do
164
+ yay <= yay + 1
165
+ value <= value + 1
166
+ end
167
+ end
168
+ # Read from mem_file1 with increment
169
+ hwhen(12) do
170
+ mem_file_rincP.read(result) do
171
+ yay <= yay + 1
172
+ end
173
+ end
174
+ # Write to mem_file2 with increment
175
+ hwhen(13) do
176
+ mem_file_wdecP.write(value) do
177
+ yay <= yay + 1
178
+ value <= value + 1
179
+ end
180
+ end
181
+ # Read from mem_file2 with increment
182
+ hwhen(14) do
183
+ mem_file_rdecP.read(result) do
184
+ yay <= yay + 1
185
+ end
186
+ end
187
+ # Write to mem_file3 with num access
188
+ hwhen(15) do
189
+ mem_file_anumP.write(0,0)
190
+ mem_file_anumP.write(1,1)
191
+ mem_file_anumP.write(2,2)
192
+ mem_file_anumP.write(3,3)
193
+ mem_file_anumP.write(4,4)
194
+ mem_file_anumP.write(5,5)
195
+ mem_file_anumP.write(6,6)
196
+ mem_file_anumP.write(7,7) do
197
+ yay <= 8
198
+ end
199
+ end
200
+ # Read from mem_file3 with num access
201
+ hwhen(16) do
202
+ mem_file_anumP.read(0,res0)
203
+ mem_file_anumP.read(1,res1)
204
+ mem_file_anumP.read(2,res2)
205
+ mem_file_anumP.read(3,res3)
206
+ mem_file_anumP.read(4,res4)
207
+ mem_file_anumP.read(5,res5)
208
+ mem_file_anumP.read(6,res6)
209
+ mem_file_anumP.read(7,res7) do
210
+ yay <= 8
211
+ end
212
+ end
213
+ # Write to mem_file3 with num access
214
+ hwhen(17) do
215
+ mem_file_fixP[0].write(1)
216
+ mem_file_fixP[1].write(2)
217
+ mem_file_fixP[2].write(4)
218
+ mem_file_fixP[3].write(8)
219
+ mem_file_fixP[4].write(16)
220
+ mem_file_fixP[5].write(32)
221
+ mem_file_fixP[6].write(64)
222
+ mem_file_fixP[7].write(128) do
223
+ yay <= 8
224
+ end
225
+ end
226
+ # Read from mem_file3 with num access
227
+ hwhen(18) do
228
+ mem_file_fixP[0].read(res0)
229
+ mem_file_fixP[1].read(res1)
230
+ mem_file_fixP[2].read(res2)
231
+ mem_file_fixP[3].read(res3)
232
+ mem_file_fixP[4].read(res4)
233
+ mem_file_fixP[5].read(res5)
234
+ mem_file_fixP[6].read(res6)
235
+ mem_file_fixP[7].read(res7) do
236
+ yay <= 8
237
+ end
238
+ end
239
+ end
240
+
241
+
242
+ timed do
243
+ # Initialize everything.
244
+ clk <= 0
245
+ rst <= 0
246
+ step <= 0
247
+ yay <= 0
248
+ !10.ns
249
+ clk <= 1
250
+ !10.ns
251
+ clk <= 0
252
+ rst <= 1
253
+ !10.ns
254
+ clk <= 1
255
+ !10.ns
256
+ clk <= 0
257
+ rst <= 0
258
+ step <= 1
259
+
260
+ # Testing the synchronous memories.
261
+ 256.times do
262
+ !10.ns
263
+ clk <= 1
264
+ !10.ns
265
+ hif(yay==8) do
266
+ step <= step + 1
267
+ yay <= 0
268
+ end
269
+ clk <= 0
270
+ end
271
+ end
272
+ end