HDLRuby 2.1.2 → 2.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.