HDLRuby 2.2.13 → 2.3.0

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 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