HDLRuby 2.1.2 → 2.1.5

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.
@@ -0,0 +1,328 @@
1
+ require 'std/channel.rb'
2
+
3
+
4
+
5
+ ##
6
+ # Standard HDLRuby::High library: memories encapsulated in channels.
7
+ #
8
+ ########################################################################
9
+
10
+
11
+ # Synchroneous +n+ ports memories including +size+ words of +typ+ data type,
12
+ # synchronized on +clk_e+ events and reset of +rst+ signal.
13
+ # +br_rsts+ are reset names on the branches, if not given, a reset input
14
+ # is added and connected to rst.
15
+ #
16
+ # NOTE:
17
+ #
18
+ # * such memories uses the following signals:
19
+ # - abus_xyz for address bus number xyz
20
+ # - dbus_xyz for data bus number xyz (bidirectional)
21
+ # - cs_xyz for selecting port number xyz
22
+ # - rwb_xyz for indicating whether port xyz is read (1) or written (0)
23
+ #
24
+ # * The read and write procedure are blocking and require a clock.
25
+ #
26
+ # * Read and write cannot be simultanous on a given port, and arbitration
27
+ # is assumed to be done outside the channel!
28
+ HDLRuby::High::Std.channel(:mem_sync) do |n,typ,size,clk_e,rst,br_rsts = []|
29
+ # Ensure n is an integer.
30
+ n = n.to_i
31
+ # Ensure typ is a type.
32
+ typ = typ.to_type
33
+ # Ensure size in an integer.
34
+ size = size.to_i
35
+ # Compute the address bus width from the size.
36
+ awidth = (size-1).width
37
+ # Ensure clk_e is an event, if not set it to a positive edge.
38
+ clk_e = clk_e.posedge unless clk_e.is_a?(Event)
39
+
40
+ # Declare the signals interfacing the memory.
41
+ n.times do |p|
42
+ # For port number +p+
43
+ # Main signals
44
+ [awidth].inner :"abus_#{p}" # The address bus
45
+ typ.inner :"dbus_#{p}" # The data bus
46
+ inner :"cs_#{p}" # Chip select
47
+ inner :"rwb_#{p}" # Read/!Write
48
+ end
49
+ # Declare the memory content.
50
+ typ[awidth].inner :mem
51
+
52
+ # Defines the ports of the memory as branchs of the channel.
53
+ n.times do |p|
54
+ brancher(p) do
55
+ accesser_inout :"abus_#{p}", :"cs_#{p}", :"rwb_#{p}"
56
+ accesser_inout :"dbus_#{p}"
57
+ if br_rsts[p] then
58
+ rst_name = br_rsts[p].to_sym
59
+ else
60
+ rst_name = rst.name
61
+ accesser_input rst.name
62
+ end
63
+
64
+ # Defines the read procedure to port +p+ at address +addr+
65
+ # using +target+ as target of access result.
66
+ reader do |blk,addr,target|
67
+ # Get the interface.
68
+ abus = send(:"abus_#{p}")
69
+ dbus = send(:"dbus_#{p}")
70
+ cs = send(:"cs_#{p}")
71
+ rwb = send(:"rwb_#{p}")
72
+ rst = send(rst_name)
73
+ # Use it to make the access.
74
+ hif (rst) do
75
+ # Reset case
76
+ cs <= 0
77
+ abus <= 0
78
+ rwb <= 0
79
+ end
80
+ helsif (cs == 0) do
81
+ # Start the access.
82
+ cs <= 1
83
+ rwb <= 1
84
+ abus <= addr
85
+ end; helse do
86
+ # End the access.
87
+ target <= dbus
88
+ cs <= 0
89
+ # Execute the blk.
90
+ blk.call if blk
91
+ end
92
+ end
93
+
94
+ # Defines the write procedure to port +p+ at address +addr+
95
+ # using +target+ as target of access result.
96
+ writer do |blk,addr,target|
97
+ # Get the interface.
98
+ abus = send(:"abus_#{p}")
99
+ dbus = send(:"dbus_#{p}")
100
+ cs = send(:"cs_#{p}")
101
+ rwb = send(:"rwb_#{p}")
102
+ rst = send(rst_name)
103
+ # Use it to make the access.
104
+ hif (rst) do
105
+ # Reset case
106
+ cs <= 0
107
+ abus <= 0
108
+ rwb <= 0
109
+ end
110
+ helsif (cs == 0) do
111
+ # Start the access.
112
+ cs <= 1
113
+ rwb <= 0
114
+ abus <= addr
115
+ dbus <= target
116
+ end; helse do
117
+ # End the access.
118
+ abus <= 0
119
+ cs <= 0
120
+ rwb <= 0
121
+ dbus <= "z" * typ.width
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ # Manage the accesses
128
+ par(clk_e) do
129
+ # For each port individually: read or no access
130
+ n.times do |p|
131
+ # Get the interface.
132
+ abus = send(:"abus_#{p}")
133
+ dbus = send(:"dbus_#{p}")
134
+ cs = send(:"cs_#{p}")
135
+ rwb = send(:"rwb_#{p}")
136
+ # The read accesses
137
+ # Use to manage the memory port.
138
+ hif (cs & rwb) do
139
+ dbus <= mem[abus]
140
+ end
141
+ # The no accesses
142
+ helse { dbus <= "z" * typ.width }
143
+ end
144
+ # For all ports together: write.
145
+ # Priority to the lowest port number.
146
+ n.times do |p|
147
+ # Get the interface.
148
+ abus = send(:"abus_#{p}")
149
+ dbus = send(:"dbus_#{p}")
150
+ cs = send(:"cs_#{p}")
151
+ rwb = send(:"rwb_#{p}")
152
+ # The write access.
153
+ if (p == 0) then
154
+ hif(cs & ~rwb) do
155
+ mem[abus] <= dbus
156
+ end
157
+ else
158
+ helsif(cs & ~rwb) do
159
+ mem[abus] <= dbus
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+
167
+
168
+
169
+
170
+ # Flexible dual-edge memory with distinct read and write ports of +size+
171
+ # elements of +typ+ typ, syncrhonized on +clk+ (positive and negative edges)
172
+ # and reset on +rst+.
173
+ # At each rising edge of +clk+ a read and a write is guaranteed to be
174
+ # completed provided they are triggered.
175
+ # +br_rsts+ are reset names on the branches, if not given, a reset input
176
+ # is added and connected to rst.
177
+ #
178
+ # NOTE:
179
+ #
180
+ # * such memories uses the following ports:
181
+ # - trig_r: read access trigger (output)
182
+ # - trig_w: write access trigger (output)
183
+ # - dbus_r: read data bus (input)
184
+ # - dbus_w: write data bus (output)
185
+ #
186
+ # * The following branches are possible (only one read and one write can
187
+ # be used per channel)
188
+ # - raddr: read by address, this channel adds the following port:
189
+ # abus_r: read address bus (output)
190
+ # - waddr: read by address, this channel adds the following port:
191
+ # abus_w: write address bus (output)
192
+ # - rinc: read by automatically incremented address.
193
+ # - winc: write by automatically incremented address.
194
+ # - rdec: read by automatically decremented address.
195
+ # - wdec: write by automatically decremented address.
196
+ # - rque: read in queue mode: automatically incremented address ensuring
197
+ # the read address is always different from the write address.
198
+ # - wque: write in queue mode: automatically incremented address ensuring
199
+ # the write address is always differnet from the read address.
200
+ #
201
+ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
202
+ # Ensure typ is a type.
203
+ typ = typ.to_type
204
+ # Ensure size in an integer.
205
+ size = size.to_i
206
+ # Compute the address bus width from the size.
207
+ awidth = (size-1).width
208
+ # Process the table of reset mapping for the branches.
209
+ # puts "first br_rsts=#{br_rsts}"
210
+ if br_rsts.is_a?(Array) then
211
+ # It is a list, convert it to a hash with the following order:
212
+ # raddr, waddr, rinc, winc, rdec, wdec, rque, wque
213
+ # If there is only two entries they will be duplicated and mapped
214
+ # as follows:
215
+ # [raddr,waddr], [rinc,winc], [rdec,wdec], [rque,wque]
216
+ # If there is only one entry it will be duplicated and mapped as
217
+ # follows:
218
+ # raddr, rinc, rdec, rque
219
+ if br_rsts.size == 2 then
220
+ br_rsts = br_rsts * 4
221
+ elsif br_rsts.size == 1 then
222
+ br_rsts = br_rsts * 8
223
+ end
224
+ br_rsts = { raddr: br_rsts[0], waddr: br_rsts[1],
225
+ rinc: br_rsts[2], winc: br_rsts[3],
226
+ rdec: br_rsts[4], wdec: br_rsts[5],
227
+ rque: br_rsts[6], wque: br_rsts[6] }
228
+ end
229
+ unless br_rsts.respond_to?(:[])
230
+ raise "Invalid reset mapping description: #{br_rsts}"
231
+ end
232
+
233
+ # Declare the control signals.
234
+ # Access triggers.
235
+ inner :trig_r, :trig_w
236
+ # Data buses
237
+ typ.inner :dbus_r, :dbus_w
238
+ # Address buses (or simply registers)
239
+ [awidth].inner :abus_r, :abus_w
240
+ # Address buffers
241
+ [awidth].inner :abus_r_reg
242
+
243
+ # Declare the memory content.
244
+ typ[awidth].inner :mem
245
+
246
+ # Processes handling the memory access.
247
+ par(clk.posedge) do
248
+ # Output memory value for reading at each cycle.
249
+ dbus_r <= mem[abus_r_reg]
250
+ # Manage the write to the memory.
251
+ hif(trig_w) { mem[abus_w] <= dbus_w }
252
+ end
253
+ par(clk.negedge) { abus_r_reg <= abus_r }
254
+
255
+ # The address branches.
256
+ # Read with address
257
+ brancher(:raddr) do
258
+ reader_output :trig_r, :abus_r
259
+ reader_input :dbus_r
260
+ if br_rsts[:raddr] then
261
+ rst_name = br_rsts[:raddr].to_sym
262
+ else
263
+ rst_name = rst.name
264
+ reader_input rst_name
265
+ end
266
+
267
+ # Defines the read procedure at address +addr+
268
+ # using +target+ as target of access result.
269
+ reader do |blk,addr,target|
270
+ # By default the read trigger is 0.
271
+ top_block.unshift { trig_r <= 0 }
272
+ # The read procedure.
273
+ rst = send(rst_name)
274
+ par do
275
+ hif(rst == 0) do
276
+ # No reset, so can perform the read.
277
+ hif(trig_r == 1) do
278
+ # The trigger was previously set, read ok.
279
+ target <= dbus_r
280
+ blk.call
281
+ end
282
+ # Prepare the read.
283
+ abus_r <= addr
284
+ trig_r <= 1
285
+ end
286
+ end
287
+ end
288
+ end
289
+
290
+ # Write with address
291
+ brancher(:waddr) do
292
+ writer_output :trig_w, :abus_w, :dbus_w
293
+ if br_rsts[:waddr] then
294
+ rst_name = br_rsts[:waddr].to_sym
295
+ else
296
+ rst_name = rst.name
297
+ writer_input rst_name
298
+ end
299
+ # puts "br_rsts=#{br_rsts}"
300
+ # puts "rst_name=#{rst_name}"
301
+
302
+ # Defines the read procedure at address +addr+
303
+ # using +target+ as target of access result.
304
+ writer do |blk,addr,target|
305
+ # By default the read trigger is 0.
306
+ top_block.unshift { trig_w <= 0 }
307
+ # The write procedure.
308
+ rst = send(rst_name)
309
+ par do
310
+ hif(rst == 0) do
311
+ # No reset, so can perform the write.
312
+ hif(trig_w == 1) do
313
+ # The trigger was previously set, write ok.
314
+ blk.call
315
+ end
316
+ # Prepare the write.
317
+ abus_w <= addr
318
+ trig_w <= 1
319
+ dbus_w <= target
320
+ end
321
+ end
322
+ end
323
+ end
324
+
325
+ end
326
+
327
+
328
+
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "2.1.2"
2
+ VERSION = "2.1.5"
3
3
  end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: HDLRuby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.5
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-02-22 00:00:00.000000000 Z
11
+ date: 2020-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 2.0.1
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.0.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  description: HDLRuby is a library for describing and simulating digital electronic
@@ -115,6 +115,7 @@ files:
115
115
  - lib/HDLRuby/hdr_samples/with_class.rb
116
116
  - lib/HDLRuby/hdr_samples/with_decoder.rb
117
117
  - lib/HDLRuby/hdr_samples/with_fsm.rb
118
+ - lib/HDLRuby/hdr_samples/with_memory.rb
118
119
  - lib/HDLRuby/hdr_samples/with_reconf.rb
119
120
  - lib/HDLRuby/hdrcc.rb
120
121
  - lib/HDLRuby/high_samples/_adder_fault.rb
@@ -173,6 +174,8 @@ files:
173
174
  - lib/HDLRuby/high_samples/with_fsm.rb
174
175
  - lib/HDLRuby/high_samples/with_pipe.rb
175
176
  - lib/HDLRuby/high_samples/with_seq.rb
177
+ - lib/HDLRuby/high_samples/with_top_unshift.rb
178
+ - lib/HDLRuby/high_samples/with_unshift.rb
176
179
  - lib/HDLRuby/hruby_bstr.rb
177
180
  - lib/HDLRuby/hruby_check.rb
178
181
  - lib/HDLRuby/hruby_db.rb
@@ -259,6 +262,7 @@ files:
259
262
  - lib/HDLRuby/std/counters.rb
260
263
  - lib/HDLRuby/std/decoder.rb
261
264
  - lib/HDLRuby/std/fsm.rb
265
+ - lib/HDLRuby/std/memory.rb
262
266
  - lib/HDLRuby/std/pipeline.rb
263
267
  - lib/HDLRuby/std/reconf.rb
264
268
  - lib/HDLRuby/test_hruby_bstr.rb
@@ -292,8 +296,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
292
296
  - !ruby/object:Gem::Version
293
297
  version: '0'
294
298
  requirements: []
295
- rubyforge_project:
296
- rubygems_version: 2.5.2.3
299
+ rubygems_version: 3.0.8
297
300
  signing_key:
298
301
  specification_version: 4
299
302
  summary: HDLRuby is a library for describing and simulating digital electronic systems.