HDLRuby 2.3.4 → 2.4.1
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 +4 -4
- data/README.md +1 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +9 -0
- data/lib/HDLRuby/hdr_samples/with_linear.rb +3 -15
- data/lib/HDLRuby/hdr_samples/with_multi_channels.rb +290 -0
- data/lib/HDLRuby/hdrcc.rb +10 -1
- data/lib/HDLRuby/hruby_high.rb +14 -3
- data/lib/HDLRuby/hruby_low.rb +107 -8
- data/lib/HDLRuby/hruby_low2c.rb +10 -5
- data/lib/HDLRuby/hruby_low_mutable.rb +90 -2
- data/lib/HDLRuby/hruby_low_resolve.rb +1 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +14 -0
- data/lib/HDLRuby/hruby_tools.rb +2 -2
- data/lib/HDLRuby/sim/hruby_sim.h +75 -37
- data/lib/HDLRuby/sim/hruby_sim_calc.c +69 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +29 -6
- data/lib/HDLRuby/sim/hruby_sim_vcd.c +215 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +51 -12
- data/lib/HDLRuby/std/channel.rb +311 -63
- data/lib/HDLRuby/std/linear.rb +16 -8
- data/lib/HDLRuby/std/memory.rb +1 -1
- data/lib/HDLRuby/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65ef28718e6de9e9d1358073d2d7ae8bd914a3f942b48d6cd45c8f28f545a906
|
4
|
+
data.tar.gz: 0d469d886d79f65ebfc69a4c4f95d2d8f50c0ada6f4fdbf0349d3c9650fa4581
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d458fe640fd29e1e31470b1f395333c3fd344703903c0c7d126e780d9e6f93c419f18a4e4cbaadc91461d19ed0087388a249fe3ccd87b2ed29d731733ecbc5b
|
7
|
+
data.tar.gz: 1ff098b2ca9bff7758bff7a5bb5e20df7272f53f103944037f9575b55444e6179781129e5d87e301a4e29b885bee5cc82794918ad85ac8236894603759d66212
|
data/README.md
CHANGED
@@ -50,6 +50,7 @@ Where:
|
|
50
50
|
| `-s, --syntax` | Output the Ruby syntax tree |
|
51
51
|
| `-C, --clang` | Output the C code of the simulator |
|
52
52
|
| `-S, --sim` | Output the executable simulator and execute it |
|
53
|
+
| `--vcd` | Make the simulator generate a vcd file |
|
53
54
|
| `-d, --directory` | Specify the base directory for loading the HDLRuby files |
|
54
55
|
| `-D, --debug` | Set the HDLRuby debug mode |
|
55
56
|
| `-t, --top system`| Specify the top system describing the circuit to compile |
|
@@ -9,6 +9,8 @@ system :fix_test do
|
|
9
9
|
|
10
10
|
# Declare three 4-bit integer part 4-bit fractional part
|
11
11
|
bit[3..0,3..0].inner :x,:y,:z
|
12
|
+
# Declare three 8-bit integer part 8-bit fractional part
|
13
|
+
signed[3..0,3..0].inner :a,:b,:c,:d
|
12
14
|
|
13
15
|
# Performs calculation between then
|
14
16
|
timed do
|
@@ -22,5 +24,12 @@ system :fix_test do
|
|
22
24
|
!10.ns
|
23
25
|
z <= z / x
|
24
26
|
!10.ns
|
27
|
+
a <= _00010000
|
28
|
+
b <= _00001111
|
29
|
+
!10.ns
|
30
|
+
c <= a * b
|
31
|
+
d <= 0
|
32
|
+
!10.ns
|
33
|
+
d <= d + c
|
25
34
|
end
|
26
35
|
end
|
@@ -22,9 +22,6 @@ system :testmat do
|
|
22
22
|
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memL1)
|
23
23
|
mem_dual([8],256,clk,rst, rinc: :rst,winc: :rst).(:memR)
|
24
24
|
# Access ports.
|
25
|
-
# # memL0.branch(:rinc).inner :readL0
|
26
|
-
# # memL1.branch(:rinc).inner :readL1
|
27
|
-
# # memR.branch(:rinc).inner :readR
|
28
25
|
# memL0.branch(:rinc).input :readL0
|
29
26
|
# memL1.branch(:rinc).input :readL1
|
30
27
|
# memR.branch(:rinc).input :readR
|
@@ -35,9 +32,9 @@ system :testmat do
|
|
35
32
|
|
36
33
|
# Accumulators memory.
|
37
34
|
mem_file([8],2,clk,rst,rinc: :rst).(:memAcc)
|
38
|
-
#
|
39
|
-
|
40
|
-
accs_out = [
|
35
|
+
# memAcc.branch(:anum).inout :accs
|
36
|
+
# accs_out = [accs.wrap(0), accs.wrap(1)]
|
37
|
+
accs_out = [memAcc.branch(:anum).wrap(0), memAcc.branch(:anum).wrap(1)]
|
41
38
|
|
42
39
|
# Layer 0 ack.
|
43
40
|
inner :ack0
|
@@ -52,8 +49,6 @@ system :testmat do
|
|
52
49
|
# Tarnslation result
|
53
50
|
mem_file([8],2,clk,rst,rinc: :rst).(:memF)
|
54
51
|
# Access ports.
|
55
|
-
# # memT.branch(:anum).inner :readT
|
56
|
-
# # memF.branch(:anum).inner :writeF
|
57
52
|
memT.branch(:anum).input :readT
|
58
53
|
memF.branch(:anum).output :writeF
|
59
54
|
regRs = [ readT.wrap(0), readT.wrap(1) ]
|
@@ -72,8 +67,6 @@ system :testmat do
|
|
72
67
|
# Input memories.
|
73
68
|
mem_dual([8],2,clk,rst, rinc: :rst,winc: :rst).(:mem2L0)
|
74
69
|
# Access ports.
|
75
|
-
# # mem2L0.branch(:rinc).inner :read2L0
|
76
|
-
# # memF.branch(:rinc).inner :readF
|
77
70
|
# mem2L0.branch(:rinc).input :read2L0
|
78
71
|
# memF.branch(:rinc).input :readF
|
79
72
|
|
@@ -93,11 +86,6 @@ system :testmat do
|
|
93
86
|
|
94
87
|
|
95
88
|
# The memory initializer.
|
96
|
-
# # memL0.branch(:winc).inner :writeL0
|
97
|
-
# # memL1.branch(:winc).inner :writeL1
|
98
|
-
# # memR.branch(:winc).inner :writeR
|
99
|
-
# # memT.branch(:winc).inner :writeT
|
100
|
-
# # mem2L0.branch(:winc).inner :write2L0
|
101
89
|
# memL0.branch(:winc).output :writeL0
|
102
90
|
# memL1.branch(:winc).output :writeL1
|
103
91
|
# memR.branch(:winc).output :writeR
|
@@ -0,0 +1,290 @@
|
|
1
|
+
require "std/channel.rb"
|
2
|
+
|
3
|
+
include HDLRuby::High::Std
|
4
|
+
|
5
|
+
# Channel describing a buffered queue storing data of +typ+ type of +depth+,
|
6
|
+
# synchronized through clk and reset on +rst+.
|
7
|
+
channel(:queue) do |typ,depth,clk,rst|
|
8
|
+
# The inner buffer of the queue.
|
9
|
+
typ[-depth].inner :buffer
|
10
|
+
# The read and write pointers.
|
11
|
+
[depth.width].inner :rptr, :wptr
|
12
|
+
# The read and write command signals.
|
13
|
+
inner :rcmd, :wcmd
|
14
|
+
# The read and write ack signals.
|
15
|
+
inner :rack, :wack
|
16
|
+
# The ack check deactivator (for synchron accesses).
|
17
|
+
inner :hrack, :hwack
|
18
|
+
# The read/write data registers.
|
19
|
+
typ.inner :rdata, :wdata
|
20
|
+
|
21
|
+
# The process handling the decoupled access to the buffer.
|
22
|
+
par(clk.posedge) do
|
23
|
+
# rack <= 0
|
24
|
+
# wack <= 0
|
25
|
+
hif (~rcmd) { rack <= 0 }
|
26
|
+
hif (~wcmd) { wack <= 0 }
|
27
|
+
hif(rst) { rptr <= 0; wptr <= 0 }
|
28
|
+
hif(rcmd & (hrack|~rack) & (rptr != wptr)) do
|
29
|
+
rptr <= (rptr + 1) % depth
|
30
|
+
rack <= 1
|
31
|
+
end
|
32
|
+
hif(wcmd & (hwack|~wack) & (((wptr+1) % depth) != rptr)) do
|
33
|
+
buffer[wptr] <= wdata
|
34
|
+
# buffer[1] <= wdata
|
35
|
+
wptr <= (wptr + 1) % depth
|
36
|
+
wack <= 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
par { rdata <= buffer[rptr] }
|
40
|
+
|
41
|
+
reader_output :rcmd, :rptr, :hrack
|
42
|
+
reader_input :rdata, :rack
|
43
|
+
|
44
|
+
# The read primitive.
|
45
|
+
reader do |blk,target|
|
46
|
+
if (cur_behavior.on_event?(clk.posedge,clk.negedge)) then
|
47
|
+
# Same clk event, synchrone case: perform a direct access.
|
48
|
+
# Now perform the access.
|
49
|
+
top_block.unshift do
|
50
|
+
rcmd <= 0
|
51
|
+
hrack <= 1
|
52
|
+
end
|
53
|
+
seq do
|
54
|
+
rptr <= (rptr + 1) % depth
|
55
|
+
target <= rdata
|
56
|
+
blk.call if blk
|
57
|
+
end
|
58
|
+
else
|
59
|
+
# Different clk event, perform a decoupled access.
|
60
|
+
top_block.unshift do
|
61
|
+
rcmd <= 0
|
62
|
+
hrack <= 0
|
63
|
+
end
|
64
|
+
seq do
|
65
|
+
hif(rack) do
|
66
|
+
blk.call if blk
|
67
|
+
end
|
68
|
+
helse do
|
69
|
+
rcmd <= 1
|
70
|
+
target <= rdata
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
writer_output :wcmd, :wdata, :hwack
|
77
|
+
writer_input :wack
|
78
|
+
|
79
|
+
# The write primitive.
|
80
|
+
writer do |blk,target|
|
81
|
+
if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
|
82
|
+
# Same clk event, synchrone case: perform a direct access.
|
83
|
+
top_block.unshift do
|
84
|
+
wcmd <= 0
|
85
|
+
hwack <= 1
|
86
|
+
end
|
87
|
+
wcmd <= 1
|
88
|
+
wdata <= target
|
89
|
+
blk.call if blk
|
90
|
+
else
|
91
|
+
# Different clk event, asynchrone case: perform a decoupled access.
|
92
|
+
top_block.unshift do
|
93
|
+
wcmd <= 0
|
94
|
+
hwack <= 0
|
95
|
+
end
|
96
|
+
seq do
|
97
|
+
hif(wack) do
|
98
|
+
blk.call if blk
|
99
|
+
end
|
100
|
+
helse { wcmd <= 1 }
|
101
|
+
wdata <= target
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
# Channel describing a register of +typ+ type.
|
109
|
+
channel(:register) do |typ|
|
110
|
+
# The register.
|
111
|
+
typ.inner :buffer
|
112
|
+
|
113
|
+
reader_input :buffer
|
114
|
+
|
115
|
+
# The read primitive.
|
116
|
+
reader do |blk,target|
|
117
|
+
target <= buffer
|
118
|
+
blk.call if blk
|
119
|
+
end
|
120
|
+
|
121
|
+
writer_output :buffer
|
122
|
+
|
123
|
+
# The read primitive.
|
124
|
+
writer do |blk,target|
|
125
|
+
buffer <= target
|
126
|
+
blk.call if blk
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
# Channel describing a handshake for transmitting data of +typ+ type, reset
|
133
|
+
# by +rst+
|
134
|
+
channel(:handshake) do |typ|
|
135
|
+
# The data signal.
|
136
|
+
typ.inner :data
|
137
|
+
# The request and acknowledge.
|
138
|
+
typ.inner :req, :ack
|
139
|
+
|
140
|
+
reader_input :ack, :data
|
141
|
+
reader_output :req
|
142
|
+
|
143
|
+
# The read primitive.
|
144
|
+
reader do |blk,target|
|
145
|
+
top_block.unshift do
|
146
|
+
req <= 0
|
147
|
+
end
|
148
|
+
hif(ack == 0) do
|
149
|
+
req <= 1
|
150
|
+
end
|
151
|
+
helsif(req) do
|
152
|
+
target <= data
|
153
|
+
req <= 0
|
154
|
+
blk.call if blk
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
writer_input :req
|
159
|
+
writer_output :ack, :data
|
160
|
+
|
161
|
+
# The read primitive.
|
162
|
+
writer do |blk,target|
|
163
|
+
top_block.unshift do
|
164
|
+
ack <= 0
|
165
|
+
end
|
166
|
+
hif(req) do
|
167
|
+
hif(~ack) do
|
168
|
+
data <= target
|
169
|
+
blk.call if blk
|
170
|
+
end
|
171
|
+
ack <= 1
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
$mode = :prodcons
|
178
|
+
# $mode = :sync
|
179
|
+
# $mode = :nsync
|
180
|
+
# $mode = :async
|
181
|
+
# $channel = :register
|
182
|
+
# $channel = :handshake
|
183
|
+
$channel = :queue
|
184
|
+
|
185
|
+
# Testing the queue channel.
|
186
|
+
system :test_queue do
|
187
|
+
inner :clk, :rst, :clk2, :clk3
|
188
|
+
[8].inner :idata, :odata
|
189
|
+
[4].inner :counter
|
190
|
+
|
191
|
+
if $channel == :register then
|
192
|
+
register(bit[8]).(:my_ch)
|
193
|
+
elsif $channel == :handshake then
|
194
|
+
handshake(bit[8],rst).(:my_ch)
|
195
|
+
elsif $channel == :queue then
|
196
|
+
queue(bit[8],5,clk,rst).(:my_ch)
|
197
|
+
end
|
198
|
+
|
199
|
+
ev = $mode == :sync ? clk.posedge :
|
200
|
+
$mode == :nsync ? clk.negedge : clk2.posedge
|
201
|
+
|
202
|
+
if $mode != :prodcons then
|
203
|
+
# Sync/Neg sync and async tests mode
|
204
|
+
par(ev) do
|
205
|
+
hif(rst) do
|
206
|
+
counter <= 0
|
207
|
+
idata <= 0
|
208
|
+
odata <= 0
|
209
|
+
end
|
210
|
+
helse do
|
211
|
+
hif (counter < 4) do
|
212
|
+
my_ch.write(idata) do
|
213
|
+
idata <= idata + 1
|
214
|
+
counter <= counter + 1
|
215
|
+
end
|
216
|
+
end
|
217
|
+
helsif ((counter > 10) & (counter < 15)) do
|
218
|
+
my_ch.read(odata) do
|
219
|
+
idata <= idata - odata
|
220
|
+
counter <= counter + 1
|
221
|
+
end
|
222
|
+
end
|
223
|
+
helse do
|
224
|
+
counter <= counter + 1
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
else
|
229
|
+
# Producter/consumer mode
|
230
|
+
# Producer
|
231
|
+
par(clk2.posedge) do
|
232
|
+
hif(rst) do
|
233
|
+
idata <= 0
|
234
|
+
end
|
235
|
+
helse do
|
236
|
+
my_ch.write(idata) do
|
237
|
+
idata <= idata + 1
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
# Consumer
|
242
|
+
par(clk3.posedge) do
|
243
|
+
hif(rst) do
|
244
|
+
counter <= 0
|
245
|
+
end
|
246
|
+
helse do
|
247
|
+
my_ch.read(odata) do
|
248
|
+
counter <= counter + 1
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
timed do
|
255
|
+
clk <= 0
|
256
|
+
clk2 <= 0
|
257
|
+
clk3 <= 0
|
258
|
+
rst <= 0
|
259
|
+
!10.ns
|
260
|
+
clk <= 1
|
261
|
+
!10.ns
|
262
|
+
clk <= 0
|
263
|
+
rst <= 1
|
264
|
+
!3.ns
|
265
|
+
clk2 <= 1
|
266
|
+
!1.ns
|
267
|
+
clk3 <= 1
|
268
|
+
!6.ns
|
269
|
+
clk <= 1
|
270
|
+
!10.ns
|
271
|
+
clk <= 0
|
272
|
+
rst <= 0
|
273
|
+
!3.ns
|
274
|
+
clk2 <= 0
|
275
|
+
!1.ns
|
276
|
+
clk3 <= 1
|
277
|
+
!6.ns
|
278
|
+
64.times do
|
279
|
+
clk <= 1
|
280
|
+
!10.ns
|
281
|
+
clk <= 0
|
282
|
+
!3.ns
|
283
|
+
clk2 <= ~clk2
|
284
|
+
!1.ns
|
285
|
+
hif (clk2 == 0) { clk3 <= ~ clk3 }
|
286
|
+
!6.ns
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
data/lib/HDLRuby/hdrcc.rb
CHANGED
@@ -269,6 +269,9 @@ $optparse = OptionParser.new do |opts|
|
|
269
269
|
$options[:multiple] = v
|
270
270
|
$options[:sim] = v
|
271
271
|
end
|
272
|
+
opts.on("--vcd", "The simulator will generate a vcd file") do |v|
|
273
|
+
$options[:vcd] = v
|
274
|
+
end
|
272
275
|
opts.on("-v", "--verilog","Output in Verlog HDL format") do |v|
|
273
276
|
$options[:verilog] = v
|
274
277
|
$options[:multiple] = v
|
@@ -515,9 +518,15 @@ elsif $options[:clang] then
|
|
515
518
|
# Generate the code for it.
|
516
519
|
$main = File.open($name,"w")
|
517
520
|
|
521
|
+
# Select the vizualizer depending on the options.
|
522
|
+
init_visualizer = $options[:vcd] ? "init_vcd_visualizer" :
|
523
|
+
"init_default_visualizer"
|
524
|
+
|
518
525
|
# Generate the code of the main function.
|
519
526
|
# HDLRuby start code
|
520
|
-
$main << HDLRuby::Low::Low2C.main(
|
527
|
+
$main << HDLRuby::Low::Low2C.main("hruby_simulator",
|
528
|
+
init_visualizer,
|
529
|
+
$top_system,
|
521
530
|
$top_system.each_systemT_deep.to_a.reverse,$hnames)
|
522
531
|
$main.close
|
523
532
|
|
data/lib/HDLRuby/hruby_high.rb
CHANGED
@@ -1263,7 +1263,8 @@ module HDLRuby::High
|
|
1263
1263
|
# Converts the scope to HDLRuby::Low.
|
1264
1264
|
def to_low()
|
1265
1265
|
# Create the resulting low scope.
|
1266
|
-
scopeLow = HDLRuby::Low::Scope.new()
|
1266
|
+
# scopeLow = HDLRuby::Low::Scope.new()
|
1267
|
+
scopeLow = HDLRuby::Low::Scope.new(self.name)
|
1267
1268
|
# Push the private namespace for the low generation.
|
1268
1269
|
High.space_push(@namespace)
|
1269
1270
|
# Pushes on the name stack for converting the internals of
|
@@ -1858,7 +1859,8 @@ module HDLRuby::High
|
|
1858
1859
|
def function(name, &ruby_block)
|
1859
1860
|
if HDLRuby::High.in_system? then
|
1860
1861
|
define_singleton_method(name.to_sym) do |*args,&other_block|
|
1861
|
-
sub do
|
1862
|
+
# sub do
|
1863
|
+
sub(HDLRuby.uniq_name(name)) do
|
1862
1864
|
HDLRuby::High.top_user.instance_exec(*args,*other_block,
|
1863
1865
|
&ruby_block)
|
1864
1866
|
# ruby_block.call(*args)
|
@@ -1866,7 +1868,8 @@ module HDLRuby::High
|
|
1866
1868
|
end
|
1867
1869
|
else
|
1868
1870
|
define_method(name.to_sym) do |*args,&other_block|
|
1869
|
-
sub do
|
1871
|
+
# sub do
|
1872
|
+
sub(HDLRuby.uniq_name(name)) do
|
1870
1873
|
HDLRuby::High.top_user.instance_exec(*args,*other_block,
|
1871
1874
|
&ruby_block)
|
1872
1875
|
end
|
@@ -2788,6 +2791,14 @@ module HDLRuby::High
|
|
2788
2791
|
return RefObject.new(@base,@object)
|
2789
2792
|
end
|
2790
2793
|
|
2794
|
+
# Comparison for hash: structural comparison.
|
2795
|
+
def eql?(obj)
|
2796
|
+
return false unless obj.is_a?(RefObject)
|
2797
|
+
return false unless @base.eql?(obj.base)
|
2798
|
+
return false unless @object.eql?(obj.object)
|
2799
|
+
return true
|
2800
|
+
end
|
2801
|
+
|
2791
2802
|
# Converts the name reference to a HDLRuby::Low::RefName.
|
2792
2803
|
def to_low
|
2793
2804
|
# return HDLRuby::Low::RefName.new(@base.to_ref.to_low,@object.name)
|