HDLRuby 2.3.4 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|