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.
- checksums.yaml +5 -5
- data/HDLRuby.gemspec +4 -2
- data/README.md +84 -25
- data/lib/HDLRuby/hdr_samples/mei8.rb +2 -2
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/with_channel.rb +11 -13
- data/lib/HDLRuby/hdr_samples/with_memory.rb +123 -0
- data/lib/HDLRuby/hdrcc.rb +62 -55
- data/lib/HDLRuby/high_samples/with_top_unshift.rb +29 -0
- data/lib/HDLRuby/high_samples/with_unshift.rb +25 -0
- data/lib/HDLRuby/hruby_high.rb +120 -10
- data/lib/HDLRuby/hruby_low.rb +32 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +5 -1
- data/lib/HDLRuby/hruby_verilog.rb +1 -1
- data/lib/HDLRuby/std/channel.rb +488 -111
- data/lib/HDLRuby/std/memory.rb +328 -0
- data/lib/HDLRuby/version.rb +1 -1
- metadata +11 -8
@@ -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
|
+
|
data/lib/HDLRuby/version.rb
CHANGED
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.
|
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-
|
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
|
-
|
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.
|