HDLRuby 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,34 +16,34 @@ system :my_seqencer do
16
16
  [8].inner :res0, :res1
17
17
 
18
18
  sequencer(clk.posedge,rst) do
19
- hprint("#0\n")
19
+ # hprint("#0\n")
20
20
  res0 <= 0
21
21
  res1 <= 0
22
22
  res0 <= vals.ssum
23
23
  res1 <= res0.ssum(_h00)
24
- hprint("#1 res0=",res0," res1=",res1,"\n")
24
+ # hprint("#1 res0=",res0," res1=",res1,"\n")
25
25
  end
26
26
 
27
27
  [8].inner :res2, :res3
28
28
 
29
29
  sequencer(clk.posedge,rst) do
30
- hprint("$0\n")
30
+ # hprint("$0\n")
31
31
  res2 <= 0
32
32
  res3 <= 0
33
- res2 <= (1..5).sum
33
+ res2 <= (1..5).ssum(_h00)
34
34
  res3 <= (res3..res2).ssum
35
- hprint("$1 res2=",res2," res3=",res3,"\n")
35
+ # hprint("$1 res2=",res2," res3=",res3,"\n")
36
36
  end
37
37
 
38
38
  [8].inner :res4, :res5
39
39
 
40
40
  sequencer(clk.posedge,rst) do
41
- hprint("!0\n")
41
+ # hprint("!0\n")
42
42
  res4 <= 0
43
43
  res5 <= 0
44
44
  res4 <= [_h01,_h02,_h03,_h04].ssum
45
- res5 <= [1,2,3,4,5].ssum
46
- hprint("!1 res4=",res4," res5=",res5,"\n")
45
+ res5 <= [1,2,3,4,5].ssum(_h00)
46
+ # hprint("!1 res4=",res4," res5=",res5,"\n")
47
47
  end
48
48
 
49
49
  bit[8][-8].inner mem: [ _h01, _h02, _h03, _h04, _h30, _h30, _h30, _h30 ]
@@ -59,10 +59,10 @@ system :my_seqencer do
59
59
  end
60
60
 
61
61
  sequencer(clk.posedge,rst) do
62
- hprint("~0\n")
62
+ # hprint("~0\n")
63
63
  res6 <= 0
64
64
  res6 <= mem_enum.ssum
65
- hprint("~1 res6=",res6,"\n")
65
+ # hprint("~1 res6=",res6,"\n")
66
66
  end
67
67
 
68
68
 
@@ -0,0 +1,63 @@
1
+ require 'std/sequencer_func.rb'
2
+
3
+ include HDLRuby::High::Std
4
+
5
+
6
+ # A factorial with default stack depth.
7
+ sdef(:fact) do |n|
8
+ hprint("n=",n,"\n")
9
+ sif(n > 1) { sreturn(n*fact(n-1,20)) } #Recurse setting the stack depth to 20
10
+ selse { sreturn(1) }
11
+ end
12
+
13
+ # A factiorial with very low stack depth for checking overflow.
14
+ sdef(:fact_over,2,proc { stack_overflow_error <= 1 }) do |n|
15
+ hprint("n2=",n,"\n")
16
+ sif(n > 1) { sreturn(n*fact_over(n-1)) }
17
+ selse { sreturn(1) }
18
+ end
19
+
20
+ # Checking the usage of sequencers functions.
21
+ system :my_seqencer do
22
+
23
+ inner :clk,:rst
24
+
25
+ [16].inner :val
26
+ [16].inner :res
27
+
28
+ inner stack_overflow_error: 0
29
+
30
+ sequencer(clk.posedge,rst) do
31
+ 5.stimes do |i|
32
+ val <= i
33
+ res <= fact(val)
34
+ end
35
+ hprint("Going to overflow...\n")
36
+ 4.stimes do |i|
37
+ val <= i
38
+ res <= fact_over(val)
39
+ end
40
+ hprint("stack_overflow_error=",stack_overflow_error,"\n")
41
+ end
42
+
43
+ timed do
44
+ clk <= 0
45
+ rst <= 0
46
+ !10.ns
47
+ clk <= 1
48
+ !10.ns
49
+ clk <= 0
50
+ rst <= 1
51
+ !10.ns
52
+ clk <= 1
53
+ !10.ns
54
+ clk <= 0
55
+ rst <= 0
56
+ !10.ns
57
+ clk <= 1
58
+ repeat(500) do
59
+ !10.ns
60
+ clk <= ~clk
61
+ end
62
+ end
63
+ end
data/lib/HDLRuby/hdrcc.rb CHANGED
@@ -821,7 +821,7 @@ elsif $options[:verilog] then
821
821
  $top_system.each_systemT_deep do |systemT|
822
822
  HDLRuby.show? "signal2subs step..."
823
823
  # Ensure there is not implicit assign to sub signals.
824
- systemT.signal2subs!
824
+ systemT.signal2subs!(true)
825
825
  # HDLRuby.show "casts_without_expression! step..."
826
826
  # systemT.casts_without_expression!
827
827
  # HDLRuby.show Time.now
@@ -2198,29 +2198,48 @@ module HDLRuby::High
2198
2198
  #
2199
2199
  # NOTE: a function is a short-cut for a method that creates a scope.
2200
2200
  def function(name, &ruby_block)
2201
+ warn("Construct 'function' is deprecated, use 'hdef' instead.")
2201
2202
  # Ensure there is a block.
2202
2203
  ruby_block = proc {} unless block_given?
2203
2204
  if HDLRuby::High.in_system? then
2204
2205
  define_singleton_method(name.to_sym) do |*args,&other_block|
2205
- # sub do
2206
2206
  sub(HDLRuby.uniq_name(name)) do
2207
2207
  HDLRuby::High.top_user.instance_exec(*args,*other_block,
2208
2208
  &ruby_block)
2209
- # ruby_block.call(*args)
2210
2209
  end
2211
2210
  end
2212
2211
  else
2213
2212
  define_method(name.to_sym) do |*args,&other_block|
2214
- # sub do
2215
2213
  sub(HDLRuby.uniq_name(name)) do
2216
2214
  HDLRuby::High.top_user.instance_exec(*args,*other_block,
2217
2215
  &ruby_block)
2218
- # ruby_block.call(*args,*other_block)
2219
2216
  end
2220
2217
  end
2221
2218
  end
2222
2219
  end
2223
2220
 
2221
+ # Declares a function named +name+ using +ruby_block+ as body.
2222
+ #
2223
+ # NOTE: a function is a short-cut for a method that creates a scope.
2224
+ def hdef(name, &ruby_block)
2225
+ # Ensure there is a block.
2226
+ ruby_block = proc {} unless block_given?
2227
+ if HDLRuby::High.in_system? then
2228
+ define_singleton_method(name.to_sym) do |*args,&other_block|
2229
+ sub(HDLRuby.uniq_name(name)) do
2230
+ HDLRuby::High.top_user.instance_exec(*args,*other_block,
2231
+ &ruby_block)
2232
+ end
2233
+ end
2234
+ else
2235
+ define_method(name.to_sym) do |*args,&other_block|
2236
+ sub(HDLRuby.uniq_name(name)) do
2237
+ HDLRuby::High.top_user.instance_exec(*args,*other_block,
2238
+ &ruby_block)
2239
+ end
2240
+ end
2241
+ end
2242
+ end
2224
2243
 
2225
2244
 
2226
2245
 
@@ -3134,7 +3153,6 @@ module HDLRuby::High
3134
3153
 
3135
3154
  # Converts the unary expression to HDLRuby::Low.
3136
3155
  def to_low
3137
- # return HDLRuby::Low::Cast.new(self.type.to_low,self.child.to_low)
3138
3156
  castL =HDLRuby::Low::Cast.new(self.type.to_low,self.child.to_low)
3139
3157
  # # For debugging: set the source high object
3140
3158
  # castL.properties[:low2high] = self.hdr_id
@@ -18,10 +18,24 @@ module HDLRuby::Low
18
18
  ## Extends the SystemT class with functionality for decomposing the
19
19
  # hierachical signals in the statements.
20
20
 
21
+ # # Decompose the hierarchical signals in the statements.
22
+ # def signal2subs!
23
+ # self.scope.signal2subs!
24
+ # end
25
+
21
26
  # Decompose the hierarchical signals in the statements.
22
- def signal2subs!
27
+ # If +decompose_vec2d+ is true then also decompose 2 dimension vectors
28
+ # (e.g., for Verilog HDL that does not support handling such signals
29
+ # as usual expressions).
30
+ def signal2subs!(decompose_vec2d = false)
31
+ @@decompose_vec2d = decompose_vec2d == true
23
32
  self.scope.signal2subs!
24
33
  end
34
+
35
+ ## Tell if 2d vector signals must be decomposed too.
36
+ def self.decompose_vec2d?
37
+ @@decompose_vec2d
38
+ end
25
39
  end
26
40
 
27
41
 
@@ -230,16 +244,41 @@ module HDLRuby::Low
230
244
  # from signal +sig+ and add to result to +subrefs+
231
245
  def flatten_to(sig,subrefs)
232
246
  # puts "flatten_to with sig name=#{sig.name}"
233
- # Work on the sub signals if any.
234
- sig.each_signal do |sub|
235
- # Create a reference for the sub.
236
- subref = RefName.new(sub.type,self.clone,sub.name)
237
- # Recruse on it.
238
- subref.flatten_to(sub,subrefs)
239
- # Was it a leaf?
240
- unless sub.each_signal.any? then
241
- # Yes, add its new ref to the list of subs.
242
- subrefs << subref
247
+ # Shall we decompose 2d vectors, and is the current signal
248
+ # for one of them?
249
+ if SystemT.decompose_vec2d? and sig.type.is_a?(TypeVector) and
250
+ sig.type.base.is_a?(TypeVector) then
251
+ # Is the reference used other than for a memory access?
252
+ unless self.parent.is_a?(RefIndex) then
253
+ # Yes, do the decomposition.
254
+ # Selects the direction.
255
+ rng = sig.type.range
256
+ if rng.first > rng.last then
257
+ itr = (rng.last..rng.first).each
258
+ else
259
+ itr = rng.reverse_each
260
+ end
261
+ # Iterate on each element.
262
+ itr.each do |i|
263
+ # Create a reference fo the sub.
264
+ subref = RefIndex.new(sig.type.base,self.clone,
265
+ Value.new(TypeUnsigned.new(:""),i))
266
+ # Add it.
267
+ subrefs << subref
268
+ end
269
+ end
270
+ else
271
+ # Work on the sub signals if any.
272
+ sig.each_signal do |sub|
273
+ # Create a reference for the sub.
274
+ subref = RefName.new(sub.type,self.clone,sub.name)
275
+ # Recurse on it.
276
+ subref.flatten_to(sub,subrefs)
277
+ # Was it a leaf?
278
+ unless sub.each_signal.any? then
279
+ # Yes, add its new ref to the list of subs.
280
+ subrefs << subref
281
+ end
243
282
  end
244
283
  end
245
284
  end
@@ -42,13 +42,13 @@ module HDLRuby
42
42
  elsif type.float? then
43
43
  return type
44
44
  elsif self.signed? then
45
- return self
45
+ if type.signed? then
46
+ return self.width >= type.width ? self : type
47
+ else
48
+ return self
49
+ end
46
50
  elsif type.signed? then
47
51
  return type
48
- elsif self.unsigned? then
49
- return self
50
- elsif type.unsigned? then
51
- return type
52
52
  elsif self.width >= type.width then
53
53
  return self
54
54
  else
@@ -253,6 +253,7 @@ module HDLRuby
253
253
  # Cast to +type+.
254
254
  # NOTE: nodir tells if the direction is to be ignored.
255
255
  def cast(type,nodir = false)
256
+ # puts "cast with content=#{self.content} type.signed=#{type.signed?} type.width=#{type.width}"
256
257
  # Handle the direction.
257
258
  if !nodir && type.direction != self.type.direction then
258
259
  if self.content.is_a?(Numeric) then
@@ -281,19 +282,18 @@ module HDLRuby
281
282
  res_content.positive!
282
283
  end
283
284
  end
284
- if type.signed && res_content.is_a?(Numeric) && res_content >= (1 << (type.width-1)) then
285
+ if type.signed? && res_content.is_a?(Numeric) && res_content >= (1 << (type.width-1)) then
285
286
  res_content = (-1 << type.width) + res_content
286
287
  end
287
- # # truncs to the right size if necessary.
288
- # if res_content.is_a?(BitString) then
289
- # res_content.trunc!(type.width)
290
- # else
291
- # res_content = self.trunc(res_content,type.width)
292
- # end
293
288
  # Generate the resulting value.
289
+ # puts "res_content=#{res_content}"
294
290
  return self.class.new(type,res_content)
295
291
  end
296
292
 
293
+ def as(typ)
294
+ return self.cast(typ)
295
+ end
296
+
297
297
  # Concat the content of +vals+.
298
298
  def self.concat(*vals)
299
299
  # Compute the resulting type.
@@ -89,10 +89,10 @@ module HDLRuby::Low
89
89
  # Convert the ranges to arrays.
90
90
  rngI,rngS = self.r2a(rngI), self.r2a(rngS)
91
91
  # Generate the name.
92
- return "trunc_#{rngI[0]}_#{rngI[1]}_#{rngS[0]}_#{rngS[1]}"
92
+ return "truncer_#{rngI[0]}_#{rngI[1]}_#{rngS[0]}_#{rngS[1]}"
93
93
  end
94
94
 
95
- # Generate the truncating functionds.
95
+ # Generate the truncating functions.
96
96
  def dump
97
97
  # Ensure there is only one truncating function per range.
98
98
  @truncers.sort!.uniq!
@@ -117,6 +117,53 @@ module HDLRuby::Low
117
117
  TruncersI = Truncers.new
118
118
 
119
119
 
120
+ # Class for generating the truncating functions in verilog.
121
+ # Such function are necessary as expression cannot be truncated directly.
122
+ class Indexers
123
+ def initialize
124
+ @indexers = []
125
+ end
126
+
127
+ # Add an indexer to of expression of verilog type +typI+ returning
128
+ # verilog type +typR+.
129
+ def add(typI,typR)
130
+ # Add them
131
+ @indexers << [typI,typR]
132
+ end
133
+ alias_method :<<, :add
134
+
135
+
136
+ # Generate an indexer function name for expression of verilog type
137
+ # +typI+ returning verilog type +typR+.
138
+ def indexer_name(typI,typR)
139
+ # Generate the name.
140
+ return "indexer_#{name_to_verilog(typI)}_#{name_to_verilog(typR)}"
141
+ end
142
+
143
+ # Generate the indexing functions.
144
+ def dump
145
+ # Ensure there is only one indexing function per range.
146
+ @indexers.sort!.uniq!
147
+ # Generate the resulting code.
148
+ codeT = ""
149
+ @indexers.each do |(typI,typR)|
150
+ codeT << " function #{typR} "
151
+ codeT << self.indexer_name(typI,typR)
152
+ codeT << "(input #{typI} val, input integer idx);\n"
153
+ codeT << " " << self.indexer_name(typI,typR) << " = "
154
+ codeT << "val[idx];\n"
155
+ codeT << " endfunction\n\n"
156
+ end
157
+ # Clears the indexers.
158
+ @indexers = []
159
+ return codeT
160
+ end
161
+ end
162
+
163
+ # Declaration of the truncating function generator.
164
+ IndexersI = Indexers.new
165
+
166
+
120
167
  class Binary
121
168
  ## Enhances Binary with verilog generation.
122
169
 
@@ -1479,7 +1526,16 @@ module HDLRuby::Low
1479
1526
 
1480
1527
  # Converts the system to Verilog code.
1481
1528
  def to_verilog
1482
- return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
1529
+ # return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
1530
+ if self.ref.is_a?(RefName) then
1531
+ return "#{self.ref.to_verilog}[#{self.index.to_verilog}]"
1532
+ else
1533
+ # No a pure signal, need to use a function for accessing.
1534
+ at = self.ref.type.to_verilog
1535
+ rt = self.type.to_verilog
1536
+ IndexersI.add(at,rt)
1537
+ return "#{IndexersI.indexer_name(at,rt)}(#{self.ref.to_verilog},#{self.index.to_verilog})"
1538
+ end
1483
1539
  end
1484
1540
  end
1485
1541
 
@@ -1505,7 +1561,15 @@ module HDLRuby::Low
1505
1561
 
1506
1562
  # Converts the system to Verilog code.
1507
1563
  def to_verilog(unknown = false)
1508
- return "#{self.ref.to_verilog}[#{self.range.first.to_getrange}:#{self.range.last.to_getrange}]"
1564
+ if self.ref.is_a?(RefName) then
1565
+ return "#{self.ref.to_verilog}[#{self.range.first.to_getrange}:#{self.range.last.to_getrange}]"
1566
+ else
1567
+ # No a pure signal, need to use a function for accessing.
1568
+ sr = self.range.first.to_i..self.range.last.to_i
1569
+ cr = (self.type.width-1)..0
1570
+ TruncersI.add(cr,sr)
1571
+ return "#{TruncersI.truncer_name(cr,sr)}(#{self.ref.to_verilog})"
1572
+ end
1509
1573
  end
1510
1574
  end
1511
1575
 
@@ -1576,20 +1640,28 @@ module HDLRuby::Low
1576
1640
  # end
1577
1641
  # return "#{self.type.range.first + 1}'b#{self.content.to_verilog}"
1578
1642
  if self.content.is_a?(Numeric) then
1579
- if self.content < 0 then
1580
- # str = (2**self.type.width + self.content).to_s(2)
1581
- str = self.content.to_s(2)
1582
- str = "0" * (self.type.width-str.length+1) + str[1..-1]
1583
- return "-#{self.type.width}'b#{str}"
1643
+ if self.type.signed? then
1644
+ if self.content < 0 then
1645
+ # str = (2**self.type.width + self.content).to_s(2)
1646
+ str = self.content.to_s(2)
1647
+ str = "0" * (self.type.width-str.length+1) + str[1..-1]
1648
+ return "-#{self.type.width}'sb#{str}"
1649
+ else
1650
+ str = self.content.to_s(2)
1651
+ str = "0" * (self.type.width-str.length) + str
1652
+ return "#{self.type.width}'sb#{str}"
1653
+ end
1584
1654
  else
1585
- str = self.content.to_s(2)
1586
- str = "0" * (self.type.width-str.length) + str
1587
- return "#{self.type.width}'b#{str}"
1655
+ return "#{self.type.width}'b#{self.content.to_s(2)}"
1588
1656
  end
1589
1657
  # return "#{self.type.width}'b#{str}"
1590
1658
  else
1591
1659
  str = self.content.to_verilog
1592
- return "#{str.length}'b#{str}"
1660
+ if self.content.negative? then
1661
+ return "#{str.length}'sb#{str}"
1662
+ else
1663
+ return "#{str.length}'b#{str}"
1664
+ end
1593
1665
  end
1594
1666
  end
1595
1667
  # How to use when simply obtaining the width
@@ -1770,10 +1842,20 @@ module HDLRuby::Low
1770
1842
  cw = self.child.type.width
1771
1843
  sw = self.type.width
1772
1844
  if self.type.signed? then
1773
- if (sw>cw) then
1774
- # Need to sign extend.
1775
- return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," +
1776
- "#{self.child.to_verilog}})"
1845
+ # Need to sign extend.
1846
+ if cw == 1 then
1847
+ return "$signed({#{sw}{#{self.child.to_verilog}}})"
1848
+ elsif (sw>cw) then
1849
+ # return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," + "#{self.child.to_verilog}})"
1850
+ if self.child.is_a?(RefName) then
1851
+ return "$signed({{#{sw-cw}{#{self.child.to_verilog}[#{cw-1}]}}," + "#{self.child.to_verilog}})"
1852
+ else
1853
+ # No a pure signal, need to use a function for accessing.
1854
+ at = self.child.type.to_verilog
1855
+ rt = bit.to_verilog
1856
+ IndexersI.add(at,rt)
1857
+ return "$signed({{#{sw-cw}{#{IndexersI.indexer_name(at,rt)}(#{self.child.to_verilog},#{cw-1})}}," + "#{self.child.to_verilog}})"
1858
+ end
1777
1859
  elsif (sw<cw) then
1778
1860
  # Need to truncate
1779
1861
  # return "$signed(#{self.child.to_verilog}[#{sw-1}:0])"
@@ -2288,6 +2370,8 @@ module HDLRuby::Low
2288
2370
 
2289
2371
  # Adds the truncing functions.
2290
2372
  code << TruncersI.dump
2373
+ # Adds the indexing functions.
2374
+ code << IndexersI.dump
2291
2375
  # Adds the content code.
2292
2376
  code << codeC
2293
2377
  return code
@@ -1,42 +1,49 @@
1
- # Program with inverse conversion
2
- # last update 2019 01 29
3
-
4
- module HDLRuby::Verilog
5
-
6
- # This is sample.
7
- # n = "abc_ABC_いろは"
8
- # puts n
9
- # name = n.split("")
10
-
11
- @@hdr2verilog = {}
12
-
13
- # Since it is possible to use $ and numbers other than the beginning of the character string, it is divided.
14
- def name_to_verilog(name)
15
- # name = name.to_s
16
- # # Convert special characters.
17
- # name = name.each_char.map do |c|
18
- # if c=~ /[a-z0-9]/ then
19
- # c
20
- # elsif c == "_" then
21
- # "__"
22
- # else
23
- # "_" + c.ord.to_s
24
- # end
25
- # end.join
26
- # # First character: only letter is possible.
27
- # unless name[0] =~ /[a-z_]/ then
28
- # name = "_" + name
29
- # end
30
- # return name
31
- name = name.to_s
32
- vname = @@hdr2verilog[name]
33
- unless vname then
34
- vname = "_v#{@@hdr2verilog.size}_#{name.split(/[^a-zA-Z_0-9]/)[-1]}"
35
- @@hdr2verilog[name] = vname
36
- end
37
- return vname
38
- end
39
-
40
- #puts ref
41
-
42
- end
1
+ # Program with inverse conversion
2
+ # last update 2019 01 29
3
+
4
+ module HDLRuby::Verilog
5
+
6
+ # This is sample.
7
+ # n = "abc_ABC_いろは"
8
+ # puts n
9
+ # name = n.split("")
10
+
11
+ @@hdr2verilog = {}
12
+
13
+ # Since it is possible to use $ and numbers other than the beginning of the character string, it is divided.
14
+ def name_to_verilog(name)
15
+ # name = name.to_s
16
+ # # Convert special characters.
17
+ # name = name.each_char.map do |c|
18
+ # if c=~ /[a-z0-9]/ then
19
+ # c
20
+ # elsif c == "_" then
21
+ # "__"
22
+ # else
23
+ # "_" + c.ord.to_s
24
+ # end
25
+ # end.join
26
+ # # First character: only letter is possible.
27
+ # unless name[0] =~ /[a-z_]/ then
28
+ # name = "_" + name
29
+ # end
30
+ # return name
31
+ name = name.to_s
32
+ vname = @@hdr2verilog[name]
33
+ unless vname then
34
+ # Shall we change the string?
35
+ if name.match?(/^[_a-zA-Z][_a-zA-Z0-9]*$/) then
36
+ # No, just clone
37
+ vname = name.clone
38
+ else
39
+ # Yes, ensure it is a verilog-compatible name.
40
+ vname = "_v#{@@hdr2verilog.size}_#{name.split(/[^a-zA-Z_0-9]/)[-1]}"
41
+ end
42
+ @@hdr2verilog[name] = vname
43
+ end
44
+ return vname
45
+ end
46
+
47
+ #puts ref
48
+
49
+ end
@@ -219,7 +219,11 @@ module HDLRuby::High::Std
219
219
  # The default code.
220
220
  default_codes.each(&:call)
221
221
  # Depending on the state.
222
- hcase(this.cur_state_sig)
222
+ if (type == :sync) then
223
+ hcase(this.next_state_sig)
224
+ else
225
+ hcase(this.cur_state_sig)
226
+ end
223
227
  states.each do |st|
224
228
  # Register the working state (for the gotos)
225
229
  this.work_state = st
@@ -345,6 +349,11 @@ module HDLRuby::High::Std
345
349
 
346
350
 
347
351
  ## The interface for building the fsm
352
+
353
+ # Gets the current number of states.
354
+ def size
355
+ @states.size
356
+ end
348
357
 
349
358
  # Sets the event synchronizing the fsm.
350
359
  def for_event(event = nil,&ruby_block)