HDLRuby 2.4.18 → 2.4.25
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/lib/HDLRuby/hdr_samples/rom.rb +4 -2
- data/lib/HDLRuby/hdr_samples/with_connector.rb +10 -1
- data/lib/HDLRuby/hdr_samples/with_connector_memory.rb +102 -0
- data/lib/HDLRuby/hdr_samples/with_fixpoint.rb +1 -0
- data/lib/HDLRuby/hdrcc.rb +2 -0
- data/lib/HDLRuby/hruby_low.rb +11 -1
- data/lib/HDLRuby/hruby_low_casts_without_expression.rb +326 -0
- data/lib/HDLRuby/hruby_verilog.rb +49 -12
- data/lib/HDLRuby/std/connector.rb +27 -6
- data/lib/HDLRuby/std/memory.rb +126 -3
- 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: 4d049304b2681a96575ee9e398827724e0262404e973b8c73f830176ec94dffa
|
4
|
+
data.tar.gz: '0472118ef46e7bff7df577fb19dd66396da8a65bc5f9f442967346f4b640ed80'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 291dd1ed58fd73a420fc9681a6a64e3cb96ff6667164a98d85bb164723b83e3e5d285ff65a495f3f5f6705423b7ae879f0577386227483b0bd9b5254782774c6
|
7
|
+
data.tar.gz: a9f88a800878ed07c5e3a56bd0a70e3bd7c329a39e5576a36c044c14535d6104f7906444467d4c1f3a27c518da9fc14364ba5c6e02bdd437c5b0dba12fac4268
|
@@ -1,12 +1,14 @@
|
|
1
1
|
|
2
|
+
signed[7..0].typedef(:typ)
|
3
|
+
|
2
4
|
# Describes an 8-bit data 4-bit address ROM.
|
3
5
|
system :rom4_8 do
|
4
6
|
[2..0].input :addr
|
5
7
|
[7..0].output :data0,:data1,:data2
|
6
8
|
|
7
9
|
bit[7..0][0..7].constant content0: [0,1,2,3,4,5,6,7]
|
8
|
-
|
9
|
-
|
10
|
+
signed[7..0][-8].constant content1: [0,1,2,3,4,5,6,7]
|
11
|
+
typ[-8].constant content2: (8).times.to_a
|
10
12
|
|
11
13
|
data0 <= content0[addr]
|
12
14
|
data1 <= content1[addr]
|
@@ -130,6 +130,7 @@ system :with_connectors do
|
|
130
130
|
[4].inner :counter
|
131
131
|
[4*4].inner :res
|
132
132
|
inner :ack_in, :ack_out
|
133
|
+
inner :dup_req, :dup_ack
|
133
134
|
|
134
135
|
# The input queue.
|
135
136
|
queue(bit[4],4,clk,rst).(:in_qu)
|
@@ -143,7 +144,7 @@ system :with_connectors do
|
|
143
144
|
queue(bit[4*4],4,clk,rst).(:out_qu)
|
144
145
|
|
145
146
|
# Connect the input queue to the middle queues.
|
146
|
-
duplicator(bit[4],clk.negedge,in_qu,mid_qus)
|
147
|
+
duplicator(bit[4],clk.negedge,in_qu,mid_qus,dup_req,dup_ack)
|
147
148
|
|
148
149
|
# Connect the middle queues to the output queue.
|
149
150
|
merger([bit[4]]*4,clk.negedge,mid_qus,out_qu)
|
@@ -221,6 +222,7 @@ system :with_connectors do
|
|
221
222
|
timed do
|
222
223
|
clk <= 0
|
223
224
|
rst <= 0
|
225
|
+
dup_req <= 0
|
224
226
|
!10.ns
|
225
227
|
clk <= 1
|
226
228
|
!10.ns
|
@@ -235,6 +237,13 @@ system :with_connectors do
|
|
235
237
|
!10.ns
|
236
238
|
clk <= 0
|
237
239
|
rst <= 0
|
240
|
+
4.times do
|
241
|
+
!10.ns
|
242
|
+
clk <= 1
|
243
|
+
!10.ns
|
244
|
+
clk <= 0
|
245
|
+
end
|
246
|
+
dup_req <= 1
|
238
247
|
16.times do
|
239
248
|
!10.ns
|
240
249
|
clk <= 1
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'std/memory.rb'
|
2
|
+
require "std/fixpoint.rb"
|
3
|
+
require 'std/channel.rb'
|
4
|
+
require 'std/connector.rb'
|
5
|
+
|
6
|
+
include HDLRuby::High::Std
|
7
|
+
|
8
|
+
system :channel_connector do
|
9
|
+
# データ型の宣言
|
10
|
+
integer_width = 4 # 整数部のビット幅
|
11
|
+
decimal_width = 4 # 実数部のビット幅
|
12
|
+
address_width = 4 # lutのアドレスのビット幅
|
13
|
+
typ = signed[integer_width + decimal_width] # データ型
|
14
|
+
|
15
|
+
inputs_x = _00010011
|
16
|
+
inputs_h = _10100001
|
17
|
+
columns = [2, 2, 1]
|
18
|
+
|
19
|
+
inner :clk, # clock
|
20
|
+
:rst, # reset
|
21
|
+
:req, # request
|
22
|
+
:fill # 入力値のメモリへの書き込み
|
23
|
+
|
24
|
+
# inputs_x = quantize(inputs_x, typ, decimal_width)
|
25
|
+
# inputs_h = quantize(inputs_h, typ, decimal_width)
|
26
|
+
|
27
|
+
mem_rom(typ, columns[0], clk, rst, inputs_x, rinc: :rst, winc: :rst).(:rom_inputs_x) # 入力値を格納するrom(x)
|
28
|
+
|
29
|
+
mem_rom(typ, columns[0], clk, rst, inputs_h, rinc: :rst, winc: :rst).(:rom_inputs_h) # 入力値を格納するrom(h)
|
30
|
+
|
31
|
+
mem_dual(typ, columns[0], clk, rst, rinc: :rst, winc: :rst).(:ram_inputs_serializer) #
|
32
|
+
|
33
|
+
mem_dual(typ, columns[0]*2, clk, rst, rinc: :rst, winc: :rst).(:ram_inputs_merger) #
|
34
|
+
|
35
|
+
reader_inputs_x = rom_inputs_x.branch(:rinc) #入力値xの読みだし用branch
|
36
|
+
reader_inputs_h = rom_inputs_h.branch(:rinc) #入力値hの読みだし用branch
|
37
|
+
writer_inputs_serializer = ram_inputs_serializer.branch(:winc) #入力値を合成した値の書き込み用branch
|
38
|
+
writer_inputs_meger = ram_inputs_merger.branch(:winc) #入力値を合成した値の書き込み用branch
|
39
|
+
|
40
|
+
|
41
|
+
serializer(typ,clk.negedge,[reader_inputs_x,reader_inputs_h],writer_inputs_serializer)
|
42
|
+
|
43
|
+
mem_rom(typ, columns[0], clk, rst, inputs_x, rinc: :rst, winc: :rst).(:rom_inputs_r) # 入力値を格納するrom(x)
|
44
|
+
mem_dual(typ, columns[0], clk, rst, rinc: :rst, winc: :rst).(:ram_duplicator0) #
|
45
|
+
mem_dual(typ, columns[0], clk, rst, rinc: :rst, winc: :rst).(:ram_duplicator1) #
|
46
|
+
reader_inputs_r = rom_inputs_r.branch(:rinc)
|
47
|
+
writer_duplicator0 = ram_duplicator0.branch(:winc)
|
48
|
+
writer_duplicator1 = ram_duplicator1.branch(:winc)
|
49
|
+
|
50
|
+
duplicator(typ,clk.posedge,reader_inputs_r,[writer_duplicator0, writer_duplicator1])
|
51
|
+
|
52
|
+
timed do
|
53
|
+
# リセット
|
54
|
+
clk <= 0
|
55
|
+
rst <= 0
|
56
|
+
req <= 0
|
57
|
+
fill <= 0
|
58
|
+
!10.ps
|
59
|
+
|
60
|
+
# メモリ読み出し位置の初期化
|
61
|
+
rst <= 1
|
62
|
+
!10.ps
|
63
|
+
clk <= 1
|
64
|
+
!10.ps
|
65
|
+
clk <= 0
|
66
|
+
!10.ps
|
67
|
+
clk <= 1
|
68
|
+
!10.ps
|
69
|
+
|
70
|
+
# パラメータのメモリへの書き込み
|
71
|
+
clk <= 0
|
72
|
+
rst <= 0
|
73
|
+
fill <= 1
|
74
|
+
|
75
|
+
!10.ps
|
76
|
+
10.times do |i|
|
77
|
+
clk <= 1
|
78
|
+
!10.ps
|
79
|
+
clk <= 0
|
80
|
+
!10.ps
|
81
|
+
end
|
82
|
+
|
83
|
+
fill <= 0
|
84
|
+
clk <= 1
|
85
|
+
!10.ps
|
86
|
+
|
87
|
+
# 計算の実行
|
88
|
+
clk <= 0
|
89
|
+
req <= 1
|
90
|
+
!10.ps
|
91
|
+
clk <= 1
|
92
|
+
!10.ps
|
93
|
+
clk <= 0
|
94
|
+
!10.ps
|
95
|
+
30.times do
|
96
|
+
clk <= 1
|
97
|
+
!10.ps
|
98
|
+
clk <= 0
|
99
|
+
!10.ps
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/HDLRuby/hdrcc.rb
CHANGED
@@ -19,6 +19,7 @@ require 'HDLRuby/hruby_low_with_port'
|
|
19
19
|
require 'HDLRuby/hruby_low_with_var'
|
20
20
|
require 'HDLRuby/hruby_low_without_concat'
|
21
21
|
require 'HDLRuby/hruby_low_without_connection'
|
22
|
+
require 'HDLRuby/hruby_low_casts_without_expression'
|
22
23
|
require 'HDLRuby/hruby_low_cleanup'
|
23
24
|
|
24
25
|
require 'HDLRuby/hruby_verilog.rb'
|
@@ -577,6 +578,7 @@ elsif $options[:verilog] then
|
|
577
578
|
# top_system = $top_system
|
578
579
|
# Make description compatible with verilog generation.
|
579
580
|
$top_system.each_systemT_deep do |systemT|
|
581
|
+
systemT.casts_without_expression!
|
580
582
|
systemT.to_upper_space!
|
581
583
|
systemT.to_global_systemTs!
|
582
584
|
# systemT.break_types!
|
data/lib/HDLRuby/hruby_low.rb
CHANGED
@@ -1183,6 +1183,11 @@ module HDLRuby::Low
|
|
1183
1183
|
return false
|
1184
1184
|
end
|
1185
1185
|
|
1186
|
+
# Tells if the type of of vector kind.
|
1187
|
+
def vector?
|
1188
|
+
return false
|
1189
|
+
end
|
1190
|
+
|
1186
1191
|
# Gets the bitwidth of the type, by default 0.
|
1187
1192
|
# Bit, signed, unsigned and Float base have a width of 1.
|
1188
1193
|
def width
|
@@ -1410,7 +1415,7 @@ module HDLRuby::Low
|
|
1410
1415
|
|
1411
1416
|
# Sets the delegations
|
1412
1417
|
self.extend Forwardable
|
1413
|
-
[ :signed?, :unsigned?, :fixed?, :float?, :leaf?,
|
1418
|
+
[ :signed?, :unsigned?, :fixed?, :float?, :leaf?, :vector?,
|
1414
1419
|
:width, :range?, :range, :base?, :base, :types?,
|
1415
1420
|
:get_all_types, :get_type, :each, :each_type,
|
1416
1421
|
:regular?,
|
@@ -1466,6 +1471,11 @@ module HDLRuby::Low
|
|
1466
1471
|
# The base type of the vector
|
1467
1472
|
attr_reader :base
|
1468
1473
|
|
1474
|
+
# Tells if the type of of vector kind.
|
1475
|
+
def vector?
|
1476
|
+
return true
|
1477
|
+
end
|
1478
|
+
|
1469
1479
|
# Tells if the type has a base.
|
1470
1480
|
def base?
|
1471
1481
|
return true
|
@@ -0,0 +1,326 @@
|
|
1
|
+
require 'HDLRuby'
|
2
|
+
require 'HDLRuby/hruby_tools'
|
3
|
+
require 'HDLRuby/hruby_low_mutable'
|
4
|
+
require 'HDLRuby/hruby_low_with_bool'
|
5
|
+
|
6
|
+
|
7
|
+
module HDLRuby::Low
|
8
|
+
|
9
|
+
|
10
|
+
##
|
11
|
+
# Replace expressions in cast operators with variables.
|
12
|
+
# Use for generating Verilog code generation since bit extension cannot
|
13
|
+
# be performed on expression but only on signals.
|
14
|
+
#
|
15
|
+
########################################################################
|
16
|
+
|
17
|
+
|
18
|
+
## Extends the SystemT class with functionality for extracting
|
19
|
+
# expressions from cast.
|
20
|
+
class SystemT
|
21
|
+
|
22
|
+
# Extracts the expressions from the casts.
|
23
|
+
def casts_without_expression!
|
24
|
+
self.scope.casts_without_expression!
|
25
|
+
return self
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
## Extends the Scope class with functionality for extracting
|
32
|
+
# expressions from cast.
|
33
|
+
class Scope
|
34
|
+
|
35
|
+
# Extracts the expressions from the casts.
|
36
|
+
def casts_without_expression!
|
37
|
+
# Recurse on the sub scopes.
|
38
|
+
self.each_scope(&:casts_without_expression!)
|
39
|
+
|
40
|
+
# Apply on the connections.
|
41
|
+
self.each_connection(&:casts_without_expression!)
|
42
|
+
|
43
|
+
# Apply on the behaviors.
|
44
|
+
self.each_behavior do |behavior|
|
45
|
+
behavior.block.casts_without_expression!
|
46
|
+
end
|
47
|
+
return self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
## Extends the Transmit class with functionality for extracting
|
53
|
+
# expressions from cast.
|
54
|
+
class Transmit
|
55
|
+
|
56
|
+
# Extracts the expressions from the casts.
|
57
|
+
def casts_without_expression!
|
58
|
+
# Apply on the left value.
|
59
|
+
self.set_left!(self.left.casts_without_expression)
|
60
|
+
# Apply on the right value.
|
61
|
+
self.set_right!(self.right.casts_without_expression)
|
62
|
+
return self
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
## Extends the If class with functionality for extracting
|
67
|
+
# expressions from cast.
|
68
|
+
class If
|
69
|
+
|
70
|
+
# Extracts the expressions from the casts.
|
71
|
+
def casts_without_expression!
|
72
|
+
# Apply on the condition.
|
73
|
+
self.set_condition!(self.condition.casts_without_expression)
|
74
|
+
# Apply on the yes.
|
75
|
+
self.yes.casts_without_expression!
|
76
|
+
# Apply on the noifs.
|
77
|
+
@noifs.map! do |cond,stmnt|
|
78
|
+
[cond.casts_without_expression,stmnt.casts_without_expression!]
|
79
|
+
end
|
80
|
+
# Apply on the no if any.
|
81
|
+
self.no.casts_without_expression! if self.no
|
82
|
+
return self
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
## Extends the When class with functionality for extracting
|
87
|
+
# expressions from cast.
|
88
|
+
class When
|
89
|
+
|
90
|
+
# Extracts the expressions from the casts.
|
91
|
+
def casts_without_expression!
|
92
|
+
# Apply on the match.
|
93
|
+
self.set_match!(self.match.casts_without_expression)
|
94
|
+
# Apply on the statement.
|
95
|
+
self.statement.casts_without_expression!
|
96
|
+
return self
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
## Extends the Case class with functionality for extracting
|
102
|
+
# expressions from cast.
|
103
|
+
class Case
|
104
|
+
|
105
|
+
# Extracts the expressions from the casts.
|
106
|
+
def casts_without_expression!
|
107
|
+
# No need to apply on the value!
|
108
|
+
# Apply on the value.
|
109
|
+
self.set_value!(self.value.casts_without_expression)
|
110
|
+
# Apply on the whens.
|
111
|
+
self.each_when(&:casts_without_expression!)
|
112
|
+
# Apply on the default if any.
|
113
|
+
self.default.casts_without_expression! if self.default
|
114
|
+
return self
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
## Extends the TimeWait class with functionality for extracting
|
120
|
+
# expressions from cast.
|
121
|
+
class TimeWait
|
122
|
+
# Extracts the expressions from the casts.
|
123
|
+
def casts_without_expression!
|
124
|
+
# Nothing to do.
|
125
|
+
return self
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
## Extends the TimeRepeat class with functionality for extracting
|
130
|
+
# expressions from cast.
|
131
|
+
class TimeRepeat
|
132
|
+
# Extracts the expressions from the casts.
|
133
|
+
def casts_without_expression!
|
134
|
+
# Simply recurse on the stamtement.
|
135
|
+
self.statement.casts_without_expression!
|
136
|
+
return self
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
## Extends the Block class with functionality for extracting
|
142
|
+
# expressions from cast.
|
143
|
+
class Block
|
144
|
+
|
145
|
+
# Extracts the expressions from the casts.
|
146
|
+
def casts_without_expression!
|
147
|
+
# Apply on each statement.
|
148
|
+
self.each_statement(&:casts_without_expression!)
|
149
|
+
return self
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
## Extends the Value class with functionality for extracting
|
155
|
+
# expressions from cast.
|
156
|
+
class Value
|
157
|
+
# Extracts the expressions from the casts.
|
158
|
+
def casts_without_expression
|
159
|
+
# Simple clones.
|
160
|
+
return self.clone
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
## Extends the Cast class with functionality for extracting
|
166
|
+
# expressions from cast.
|
167
|
+
class Cast
|
168
|
+
# Extracts the expressions from the casts.
|
169
|
+
def casts_without_expression
|
170
|
+
# Recurse on the child.
|
171
|
+
nchild = self.child.casts_without_expression
|
172
|
+
# Process the cast.
|
173
|
+
unless (nchild.is_a?(Ref)) then
|
174
|
+
# Need to extract the child.
|
175
|
+
# Create signal holding the child.
|
176
|
+
stmnt = self.statement
|
177
|
+
if (stmnt.is_a?(Connection)) then
|
178
|
+
# Specific case of connections: need to build
|
179
|
+
# a new block.
|
180
|
+
scop = stmnt.parent
|
181
|
+
scop.delete_connection!(stmnt)
|
182
|
+
stmnt = Transmit.new(stmnt.left.clone, stmnt.right.clone)
|
183
|
+
blk = Block.new(:seq)
|
184
|
+
scop.add_behavior(Behavior.new(blk))
|
185
|
+
blk.add_statement(stmnt)
|
186
|
+
else
|
187
|
+
blk = stmnt.block
|
188
|
+
end
|
189
|
+
name = HDLRuby.uniq_name
|
190
|
+
typ = nchild.type
|
191
|
+
sig = blk.add_inner(SignalI.new(name,typ))
|
192
|
+
# Add a statement assigning the child to the new signal.
|
193
|
+
nref = RefName.new(typ,RefThis.new,name)
|
194
|
+
nstmnt = Transmit.new(nref,nchild)
|
195
|
+
idx = blk.each_statement.find_index(stmnt)
|
196
|
+
blk.insert_statement!(idx,nstmnt)
|
197
|
+
# Replace the child by a reference to the created
|
198
|
+
# signal.
|
199
|
+
nchild = nref.clone
|
200
|
+
end
|
201
|
+
return Cast.new(self.type,nchild)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
## Extends the Unary class with functionality for extracting
|
206
|
+
# expressions from cast.
|
207
|
+
class Unary
|
208
|
+
|
209
|
+
# Extracts the expressions from the casts.
|
210
|
+
def casts_without_expression
|
211
|
+
# Recurse on the sub node.
|
212
|
+
return Unary.new(self.type,self.operator,
|
213
|
+
self.child.casts_without_expression)
|
214
|
+
return self
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
## Extends the Binary class with functionality for extracting
|
220
|
+
# expressions from cast.
|
221
|
+
class Binary
|
222
|
+
|
223
|
+
# Extracts the expressions from the casts.
|
224
|
+
def casts_without_expression
|
225
|
+
# Recurse on the sub nodes.
|
226
|
+
return Binary.new(self.type,self.operator,
|
227
|
+
self.left.casts_without_expression,
|
228
|
+
self.right.casts_without_expression)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
|
233
|
+
|
234
|
+
## Extends the Select class with functionality for extracting
|
235
|
+
# expressions from cast.
|
236
|
+
class Select
|
237
|
+
|
238
|
+
# Extracts the expressions from the casts.
|
239
|
+
def casts_without_expression
|
240
|
+
# Recurse on the sub node.
|
241
|
+
return Select.new(self.type,"?",
|
242
|
+
self.select.casts_without_expression,
|
243
|
+
*self.each_choice.map do |choice|
|
244
|
+
choice.casts_without_expression
|
245
|
+
end )
|
246
|
+
return self
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
## Extends the Concat class with functionality for converting booleans
|
252
|
+
# in assignments to select operators.
|
253
|
+
class Concat
|
254
|
+
# Extracts the expressions from the casts.
|
255
|
+
def casts_without_expression
|
256
|
+
# Recurse on the sub expressions.
|
257
|
+
return Concat.new(self.type,self.each_expression.map do |expr|
|
258
|
+
expr.casts_without_expression
|
259
|
+
end )
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
|
264
|
+
## Extends the RefConcat class with functionality for converting booleans
|
265
|
+
# in assignments to select operators.
|
266
|
+
class RefConcat
|
267
|
+
# Extracts the expressions from the casts.
|
268
|
+
def casts_without_expression
|
269
|
+
# Recurse on the sub references.
|
270
|
+
return RefConcat.new(self.type,self.each_expression.map do |expr|
|
271
|
+
expr.casts_without_expression
|
272
|
+
end )
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
## Extends the RefIndex class with functionality for converting booleans
|
278
|
+
# in assignments to select operators.
|
279
|
+
class RefIndex
|
280
|
+
# Extracts the expressions from the casts.
|
281
|
+
def casts_without_expression
|
282
|
+
# Recurse on the sub references.
|
283
|
+
return RefIndex.new(self.type,
|
284
|
+
self.ref.casts_without_expression,
|
285
|
+
self.index.casts_without_expression)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
## Extends the RefRange class with functionality for converting booleans
|
291
|
+
# in assignments to select operators.
|
292
|
+
class RefRange
|
293
|
+
# Extracts the expressions from the casts.
|
294
|
+
def casts_without_expression
|
295
|
+
# Recurse on the sub references.
|
296
|
+
return RefRange.new(self.type,
|
297
|
+
self.ref.casts_without_expression,
|
298
|
+
self.range.first.casts_without_expression ..
|
299
|
+
self.range.last.casts_without_expression)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
## Extends the RefName class with functionality for converting booleans
|
305
|
+
# in assignments to select operators.
|
306
|
+
class RefName
|
307
|
+
# Extracts the expressions from the casts.
|
308
|
+
def casts_without_expression
|
309
|
+
# Recurse on the sub references.
|
310
|
+
return RefName.new(self.type,
|
311
|
+
self.ref.casts_without_expression,
|
312
|
+
self.name)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
|
317
|
+
## Extends the RefThis class with functionality for converting booleans
|
318
|
+
# in assignments to select operators.
|
319
|
+
class RefThis
|
320
|
+
# Extracts the expressions from the casts.
|
321
|
+
def casts_without_expression
|
322
|
+
# Simply clone.
|
323
|
+
return self.clone
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
@@ -11,6 +11,10 @@ include HDLRuby::Verilog
|
|
11
11
|
module HDLRuby::Low
|
12
12
|
|
13
13
|
|
14
|
+
# The list of base types used both in verilog and HDLRuby
|
15
|
+
VERILOG_BASE_TYPES = ["signed"]
|
16
|
+
|
17
|
+
|
14
18
|
# Sample of very handy for programming.
|
15
19
|
# puts "class=#{self.yes.class}" # Confirm class of self.yes.
|
16
20
|
# puts "methods=#{self.right.methods}" # Confirm method of self.right.
|
@@ -456,7 +460,10 @@ class Block
|
|
456
460
|
$fm.fm_par["#{tmt.left.to_verilog}"] = tmt.right
|
457
461
|
end
|
458
462
|
new_block.add_statement(tmt.clone)
|
459
|
-
end
|
463
|
+
end
|
464
|
+
else
|
465
|
+
# Other statements are simply added as is.
|
466
|
+
new_block.add_statement(statement.clone)
|
460
467
|
end
|
461
468
|
end
|
462
469
|
|
@@ -1349,7 +1356,8 @@ end
|
|
1349
1356
|
class TypeVector
|
1350
1357
|
# Converts the system to Verilog code.
|
1351
1358
|
def to_verilog
|
1352
|
-
if self.base.name.to_s != "bit"
|
1359
|
+
# if self.base.name.to_s != "bit"
|
1360
|
+
if VERILOG_BASE_TYPES.include?(self.base.name.to_s)
|
1353
1361
|
return " #{self.base.name.to_s}[#{self.range.first}:#{self.range.last}]"
|
1354
1362
|
end
|
1355
1363
|
return " [#{self.range.first}:#{self.range.last}]"
|
@@ -1598,7 +1606,7 @@ end
|
|
1598
1606
|
class Unary
|
1599
1607
|
# Converts the system to Verilog code.
|
1600
1608
|
def to_verilog
|
1601
|
-
return "#{self.operator}#{self.child.to_verilog}"
|
1609
|
+
return "#{self.operator[0]}#{self.child.to_verilog}"
|
1602
1610
|
end
|
1603
1611
|
end
|
1604
1612
|
|
@@ -1609,10 +1617,37 @@ class Cast
|
|
1609
1617
|
# by traditional verilog.
|
1610
1618
|
def to_verilog
|
1611
1619
|
# return "#{self.type.to_verilog}'(#{self.child.to_verilog})"
|
1620
|
+
if self.child.is_a?(Value) then
|
1621
|
+
return self.child.to_verilog
|
1622
|
+
end
|
1623
|
+
# Get the type widths, used for computing extensions or truncations.
|
1624
|
+
cw = self.child.type.width
|
1625
|
+
sw = self.type.width
|
1612
1626
|
if self.type.signed? then
|
1613
|
-
return "$signed(#{self.child.to_verilog})"
|
1627
|
+
# return "$signed(#{self.child.to_verilog})"
|
1628
|
+
if (sw>cw) then
|
1629
|
+
# Need to sign extend.
|
1630
|
+
return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," +
|
1631
|
+
"#{self.child.to_verilog}})"
|
1632
|
+
elsif (sw<cw) then
|
1633
|
+
# Need to truncate
|
1634
|
+
return "$signed(#{self.child.to_verilog}[#{sw-1}:0])"
|
1635
|
+
else
|
1636
|
+
# Only enforce signed.
|
1637
|
+
return "$signed(#{self.child.to_verilog})"
|
1638
|
+
end
|
1614
1639
|
else
|
1615
|
-
return "$unsigned(#{self.child.to_verilog})"
|
1640
|
+
# return "$unsigned(#{self.child.to_verilog})"
|
1641
|
+
if (sw>cw) then
|
1642
|
+
# Need to extend.
|
1643
|
+
return "$unsigned({{#{sw-cw}{1'b0}},#{self.child.to_verilog}})"
|
1644
|
+
elsif (sw<cw) then
|
1645
|
+
# Need to truncate
|
1646
|
+
return "$unsigned(#{self.child.to_verilog}[#{sw-1}:0])"
|
1647
|
+
else
|
1648
|
+
# Only enforce signed.
|
1649
|
+
return "$unsigned(#{self.child.to_verilog})"
|
1650
|
+
end
|
1616
1651
|
end
|
1617
1652
|
end
|
1618
1653
|
end
|
@@ -1670,15 +1705,15 @@ class Delay
|
|
1670
1705
|
def to_verilog
|
1671
1706
|
time = self.value.to_s
|
1672
1707
|
if(self.unit.to_s == "ps") then
|
1673
|
-
return "##{time}"
|
1708
|
+
return "##{time};"
|
1674
1709
|
elsif(self.unit.to_s == "ns")
|
1675
|
-
return "##{time}000"
|
1710
|
+
return "##{time}000;"
|
1676
1711
|
elsif(self.unit.to_s == "us")
|
1677
|
-
return "##{time}000000"
|
1712
|
+
return "##{time}000000;"
|
1678
1713
|
elsif(self.unit.to_s == "ms")
|
1679
|
-
return "##{time}000000000"
|
1714
|
+
return "##{time}000000000;"
|
1680
1715
|
elsif(self.unit.to_s == "s")
|
1681
|
-
return "##{time}000000000000"
|
1716
|
+
return "##{time}000000000000;"
|
1682
1717
|
end
|
1683
1718
|
end
|
1684
1719
|
end
|
@@ -1750,10 +1785,12 @@ class SystemT
|
|
1750
1785
|
end
|
1751
1786
|
# And the array types signals.
|
1752
1787
|
self.each_signal do |sig|
|
1753
|
-
regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1788
|
+
# regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1789
|
+
regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1754
1790
|
end
|
1755
1791
|
self.each_inner do |sig|
|
1756
|
-
regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1792
|
+
# regs << sig.to_verilog if sig.type.is_a?(TypeVector) && sig.type.base.is_a?(TypeVector)
|
1793
|
+
regs << sig.to_verilog if sig.type.vector? && sig.type.base.vector?
|
1757
1794
|
end
|
1758
1795
|
|
1759
1796
|
# Code generation
|
@@ -9,13 +9,28 @@ module HDLRuby::High::Std
|
|
9
9
|
# channel +in_ch+ and connect it to channels +out_chs+ with data of
|
10
10
|
# +typ+.
|
11
11
|
# The duplication is done according to event +ev+.
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# The optional req and ack arguments are the signals for controlling the
|
13
|
+
# duplicator using a handshake protocol. If set to nil, the duplicator
|
14
|
+
# runs automatically.
|
15
|
+
function :duplicator do |typ, ev, in_ch, out_chs, req = nil, ack = nil|
|
16
|
+
ev = ev.posedge unless ev.is_a?(Event)
|
17
|
+
inner :in_ack
|
18
|
+
inner :in_req
|
15
19
|
out_acks = out_chs.size.times.map { |i| inner(:"out_ack#{i}") }
|
16
20
|
typ.inner :data
|
17
21
|
par(ev) do
|
18
|
-
|
22
|
+
if (ack) then
|
23
|
+
# Output ack mode.
|
24
|
+
ack <= 0
|
25
|
+
end
|
26
|
+
if (req) then
|
27
|
+
# Input request mode.
|
28
|
+
in_req <= 0
|
29
|
+
hif(req) { in_req <= 1 }
|
30
|
+
else
|
31
|
+
# Automatic mode.
|
32
|
+
in_req <= 1
|
33
|
+
end
|
19
34
|
out_acks.each { |ack| ack <= 0 }
|
20
35
|
out_acks.each do |ack|
|
21
36
|
hif(ack == 1) { in_req <= 0 }
|
@@ -30,6 +45,10 @@ module HDLRuby::High::Std
|
|
30
45
|
end
|
31
46
|
hif (out_acks.reduce(_1) { |sum,ack| ack & sum }) do
|
32
47
|
out_acks.each { |ack| ack <= 0 }
|
48
|
+
if (ack) then
|
49
|
+
# Output ack mode.
|
50
|
+
ack <= 1
|
51
|
+
end
|
33
52
|
end
|
34
53
|
end
|
35
54
|
end
|
@@ -82,7 +101,7 @@ module HDLRuby::High::Std
|
|
82
101
|
idx <= 0
|
83
102
|
reading <= 0
|
84
103
|
out_ack <= 0
|
85
|
-
|
104
|
+
hif(idx == size-1) { in_acks.each { |ack| ack <= 0 } }
|
86
105
|
# hif((idx == 0) & (in_reqs.reduce(_1) { |sum,req| req & sum })) do
|
87
106
|
hif(idx == 0) do
|
88
107
|
hif(~reading) do
|
@@ -90,7 +109,9 @@ module HDLRuby::High::Std
|
|
90
109
|
end
|
91
110
|
reading <= 1
|
92
111
|
in_chs.each_with_index do |ch,i|
|
93
|
-
|
112
|
+
hif(~in_acks[i]) do
|
113
|
+
ch.read(datas[i]) { in_acks[i] <= 1 }
|
114
|
+
end
|
94
115
|
end
|
95
116
|
end
|
96
117
|
hif(in_acks.reduce(_1) { |sum,req| req & sum }) do
|
data/lib/HDLRuby/std/memory.rb
CHANGED
@@ -289,9 +289,10 @@ HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
|
|
289
289
|
rst = send(rst_name)
|
290
290
|
top_block.unshift do
|
291
291
|
# Initialize the address so that the next access is at address 0.
|
292
|
-
hif(rst==1) { abus_r <= -1 }
|
293
|
-
# Reset so switch of the access trigger.
|
294
|
-
trig_r <= 0
|
292
|
+
# hif(rst==1) { abus_r <= -1 }
|
293
|
+
# # Reset so switch of the access trigger.
|
294
|
+
# trig_r <= 0
|
295
|
+
hif(rst==1) { abus_r <= -1; trig_r <= 0 }
|
295
296
|
end
|
296
297
|
# The read procedure.
|
297
298
|
# par do
|
@@ -317,6 +318,7 @@ HDLRuby::High::Std.channel(:mem_rom) do |typ,size,clk,rst,content,
|
|
317
318
|
# blk.call if blk
|
318
319
|
seq do
|
319
320
|
# abus_r <= abus_r + 1
|
321
|
+
trig_r <= 0
|
320
322
|
target <= dbus_r
|
321
323
|
blk.call if blk
|
322
324
|
end
|
@@ -1704,6 +1706,127 @@ HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
|
|
1704
1706
|
|
1705
1707
|
end
|
1706
1708
|
|
1709
|
+
|
1710
|
+
# Queue memory of +size+ elements of +typ+ typ, syncrhonized on +clk+
|
1711
|
+
# (positive and negative edges) and reset on +rst+.
|
1712
|
+
# At each rising edge of +clk+ a read and a write is guaranteed to be
|
1713
|
+
# completed provided they are triggered.
|
1714
|
+
#
|
1715
|
+
# NOTE: this channel does not have any branch.
|
1716
|
+
HDLRuby::High::Std.channel(:mem_queue) do |typ,size,clk,rst|
|
1717
|
+
# The inner buffer of the queue.
|
1718
|
+
typ[-size].inner :buffer
|
1719
|
+
# The read and write pointers.
|
1720
|
+
[size.width].inner :rptr, :wptr
|
1721
|
+
# The read and write command signals.
|
1722
|
+
inner :rreq, :wreq
|
1723
|
+
# The read and write ack signals.
|
1724
|
+
inner :rack, :wack
|
1725
|
+
# The read/write data registers.
|
1726
|
+
typ.inner :rdata, :wdata
|
1727
|
+
|
1728
|
+
# The flags telling of the channel is synchronized
|
1729
|
+
inner :rsync, :wsync
|
1730
|
+
|
1731
|
+
# The process handling the decoupled access to the buffer.
|
1732
|
+
par(clk.posedge) do
|
1733
|
+
hif(rst) { rptr <= 0; wptr <= 0 }
|
1734
|
+
helse do
|
1735
|
+
hif(~rsync) do
|
1736
|
+
hif (~rreq) { rack <= 0 }
|
1737
|
+
hif(rreq & (~rack) & (rptr != wptr)) do
|
1738
|
+
rdata <= buffer[rptr]
|
1739
|
+
rptr <= (rptr + 1) % depth
|
1740
|
+
rack <= 1
|
1741
|
+
end
|
1742
|
+
end
|
1743
|
+
|
1744
|
+
hif(~wsync) do
|
1745
|
+
hif (~wreq) { wack <= 0 }
|
1746
|
+
hif(wreq & (~wack) & (((wptr+1) % size) != rptr)) do
|
1747
|
+
buffer[wptr] <= wdata
|
1748
|
+
wptr <= (wptr + 1) % size
|
1749
|
+
wack <= 1
|
1750
|
+
end
|
1751
|
+
end
|
1752
|
+
end
|
1753
|
+
end
|
1754
|
+
|
1755
|
+
reader_output :rreq, :rptr, :rsync
|
1756
|
+
reader_input :rdata, :rack, :wptr, :buffer
|
1757
|
+
|
1758
|
+
# The read primitive.
|
1759
|
+
reader do |blk,target|
|
1760
|
+
if (cur_behavior.on_event?(clk.posedge,clk.negedge)) then
|
1761
|
+
# Same clk event, synchrone case: perform a direct access.
|
1762
|
+
# Now perform the access.
|
1763
|
+
top_block.unshift do
|
1764
|
+
rsync <= 1
|
1765
|
+
rreq <= 0
|
1766
|
+
end
|
1767
|
+
seq do
|
1768
|
+
hif(rptr != wptr) do
|
1769
|
+
# target <= rdata
|
1770
|
+
target <= buffer[rptr]
|
1771
|
+
rptr <= (rptr + 1) % size
|
1772
|
+
blk.call if blk
|
1773
|
+
end
|
1774
|
+
end
|
1775
|
+
else
|
1776
|
+
# Different clk event, perform a decoupled access.
|
1777
|
+
top_block.unshift do
|
1778
|
+
rsync <= 0
|
1779
|
+
rreq <= 0
|
1780
|
+
end
|
1781
|
+
par do
|
1782
|
+
hif (~rack) { rreq <= 1 }
|
1783
|
+
helsif(rreq) do
|
1784
|
+
rreq <= 0
|
1785
|
+
target <= rdata
|
1786
|
+
blk.call if blk
|
1787
|
+
end
|
1788
|
+
end
|
1789
|
+
end
|
1790
|
+
end
|
1791
|
+
|
1792
|
+
writer_output :wreq, :wdata, :wptr, :wsync, :buffer
|
1793
|
+
writer_input :wack, :rptr
|
1794
|
+
|
1795
|
+
# The write primitive.
|
1796
|
+
writer do |blk,target|
|
1797
|
+
if (cur_behavior.on_event?(clk.negedge,clk.posedge)) then
|
1798
|
+
# Same clk event, synchrone case: perform a direct access.
|
1799
|
+
top_block.unshift do
|
1800
|
+
wsync <= 1
|
1801
|
+
wreq <= 0
|
1802
|
+
end
|
1803
|
+
hif(((wptr+1) % size) != rptr) do
|
1804
|
+
buffer[wptr] <= target
|
1805
|
+
wptr <= (wptr + 1) % size
|
1806
|
+
blk.call if blk
|
1807
|
+
end
|
1808
|
+
else
|
1809
|
+
# Different clk event, asynchrone case: perform a decoupled access.
|
1810
|
+
top_block.unshift do
|
1811
|
+
wsync <= 0
|
1812
|
+
wreq <= 0
|
1813
|
+
end
|
1814
|
+
seq do
|
1815
|
+
hif (~wack) do
|
1816
|
+
wreq <= 1
|
1817
|
+
wdata <= target
|
1818
|
+
end
|
1819
|
+
helsif(wreq) do
|
1820
|
+
wreq <= 0
|
1821
|
+
blk.call if blk
|
1822
|
+
end
|
1823
|
+
end
|
1824
|
+
end
|
1825
|
+
end
|
1826
|
+
end
|
1827
|
+
|
1828
|
+
|
1829
|
+
|
1707
1830
|
# HDLRuby::High::Std.channel(:mem_bank) do |typ,nbanks,size,clk,rst,br_rsts = {}|
|
1708
1831
|
# # Ensure typ is a type.
|
1709
1832
|
# typ = typ.to_type
|
data/lib/HDLRuby/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: HDLRuby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lovic Gauthier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/HDLRuby/hdr_samples/with_channel.rb
|
127
127
|
- lib/HDLRuby/hdr_samples/with_class.rb
|
128
128
|
- lib/HDLRuby/hdr_samples/with_connector.rb
|
129
|
+
- lib/HDLRuby/hdr_samples/with_connector_memory.rb
|
129
130
|
- lib/HDLRuby/hdr_samples/with_decoder.rb
|
130
131
|
- lib/HDLRuby/hdr_samples/with_fixpoint.rb
|
131
132
|
- lib/HDLRuby/hdr_samples/with_fsm.rb
|
@@ -206,6 +207,7 @@ files:
|
|
206
207
|
- lib/HDLRuby/hruby_low2sym.rb
|
207
208
|
- lib/HDLRuby/hruby_low2vhd.rb
|
208
209
|
- lib/HDLRuby/hruby_low_bool2select.rb
|
210
|
+
- lib/HDLRuby/hruby_low_casts_without_expression.rb
|
209
211
|
- lib/HDLRuby/hruby_low_cleanup.rb
|
210
212
|
- lib/HDLRuby/hruby_low_fix_types.rb
|
211
213
|
- lib/HDLRuby/hruby_low_mutable.rb
|