HDLRuby 2.2.12 → 2.2.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 379a3c540c9b0c1aab1b9916fe561065493df7be752be02a31e8c1a291f0ba8a
4
- data.tar.gz: daede8ff516c0325bb6a68401c98825ecab0fa230f0e961f31ce4a287a7cfae6
3
+ metadata.gz: 4c52cf9ff8c35896992dd4e79059490544c3d41047235a31660badec7a5773ed
4
+ data.tar.gz: 2ec8819e1dfa58be1e73ac35475de83973987627dc87b601820853c0926b8c3b
5
5
  SHA512:
6
- metadata.gz: d49c92cfa44d5ca66e0b704f595dc0d33dc885b5b03025f6f345403f35af1226eda8dd5dc089e4c21d84466a8b64e954bcac25e0d988a01f09fd9291353d8534
7
- data.tar.gz: c0cd59f38afcf3401d3010cd1a28c9a3bde36ba4be3abf259ce1d988719a2ca7f453fca1e84fab110c35f08385bba3f03c31f522464e6c836e144c740d21d63f
6
+ metadata.gz: '0782e49ba89bacc5316f5bd1ab232b70740f33f51d9381ec82cbbd06fc8eaf4042202dbc9723576405594246786d1b0d7c69187f1918116d3af5eea20abea245'
7
+ data.tar.gz: '000342564298bd2f46167c55f877deeab18e7b0c7282bce4e9a07b0485fde3fe3ea17beb5d0635d66c9ba47270ef3071dc222d58ced18e6f2d203adbe0d0dba1'
data/README.md CHANGED
@@ -740,6 +740,8 @@ inner :w1
740
740
  [1..0].inner :w2
741
741
  ```
742
742
 
743
+ If the signal is not meant to be changed, in can be declared using the `constant` keyword instead of `inner`.
744
+
743
745
  A connection between signals is done using the arrow operator `<=` as follows:
744
746
 
745
747
  ```ruby
@@ -828,6 +830,28 @@ system :mem16_16 do
828
830
  end
829
831
  ```
830
832
 
833
+ ### Initialization of signals
834
+ <a name="initialization"></a>
835
+
836
+ Output, inner and constant signals of a system can be initial when declared using the following syntax in place of the usual name of the signal:
837
+
838
+ ```ruby
839
+ <signal name>: <intial value>
840
+ ```
841
+
842
+ For example a single bit inner signal named `sig` can be initialized to 0 as follows:
843
+
844
+ ```ruby
845
+ inner sig: 0
846
+ ```
847
+
848
+ As an other example, a 8-bit 8-word ROM could be declared and initialized as follows:
849
+
850
+ ```ruby
851
+ bit[8][-8] rom: [ 0,1,2,3,4,5,6,7 ]
852
+ ```
853
+
854
+
831
855
  ### Scope in a system
832
856
 
833
857
  #### General scopes
@@ -2757,6 +2781,26 @@ fsm(clk.posedge,rst,:sync) do
2757
2781
  end
2758
2782
  ```
2759
2783
 
2784
+
2785
+ ## Fixed-point (fixpoint)
2786
+ <a name="fixpoint"></a>
2787
+
2788
+ This library provides a new fixed point set of data types. These new data types can be bit vectors, unsigned or signed value and are declared respectively as follows:
2789
+
2790
+ ```ruby
2791
+ bit[<integer part range>,<fractional part range>]
2792
+ unsigned[<integer part range>,<fractional part range>]
2793
+ signed[<integer part range>,<fractional part range>]
2794
+ ```
2795
+
2796
+ For example a signed 4-bit integer part 4-bit fractional part fixed point inner signal named `sig` can be declared as follows:
2797
+
2798
+ ```ruby
2799
+ bit[4,4].inner :sig
2800
+ ```
2801
+
2802
+ When performing computation with fixed point types, HDLRuby ensures that the result's decimal point position is correct.
2803
+
2760
2804
  ## Channel
2761
2805
  <a name="channel"></a>
2762
2806
 
@@ -0,0 +1,25 @@
1
+ require "std/fixpoint.rb"
2
+
3
+ include HDLRuby::High::Std
4
+
5
+
6
+
7
+ # System for testing the fixed point library.
8
+ system :fix_test do
9
+
10
+ # Declare three 4-bit integer part 4-bit fractional part
11
+ bit[3..0,3..0].inner :x,:y,:z
12
+
13
+ # Performs calculation between then
14
+ timed do
15
+ x <= _00110011
16
+ y <= _01000000
17
+ !10.ns
18
+ z <= x + y
19
+ !10.ns
20
+ z <= x * y
21
+ !10.ns
22
+ z <= z / x
23
+ !10.ns
24
+ end
25
+ end
@@ -519,8 +519,10 @@ module HDLRuby::Low
519
519
  # Generates the C text of the equivalent HDLRuby::High code.
520
520
  # +level+ is the hierachical level of the object.
521
521
  def to_c(level = 0)
522
- # Simply use the name of the type.
523
- return Low2C.type_name(self.name) + "()"
522
+ # # Simply use the name of the type.
523
+ # return Low2C.type_name(self.name) + "()"
524
+ # Simply return the defined type.
525
+ return self.def.to_c(level)
524
526
  end
525
527
  end
526
528
 
@@ -150,6 +150,13 @@ extern Value sub_value(Value src0, Value src1, Value dst);
150
150
  * @return dst */
151
151
  extern Value mul_value(Value src0, Value src1, Value dst);
152
152
 
153
+ /** Computes the division of two general values.
154
+ * @param src0 the first source value of the addition
155
+ * @param src1 the second source value of the addition
156
+ * @param dst the destination value
157
+ * @return dst */
158
+ extern Value div_value(Value src0, Value src1, Value dst);
159
+
153
160
  /** Computes the not of a value.
154
161
  * @param src the source value of the not
155
162
  * @param dst the destination value
@@ -601,6 +601,22 @@ static Value mul_value_defined_bitstring(Value src0, Value src1, Value dst) {
601
601
  }
602
602
 
603
603
 
604
+ /** Computes the division of two defined bitstring values.
605
+ * @param src0 the first source value of the addition
606
+ * @param src1 the second source value of the addition
607
+ * @param dst the destination value
608
+ * @return dst */
609
+ static Value div_value_defined_bitstring(Value src0, Value src1, Value dst) {
610
+ /* Sets state of the destination using the first source. */
611
+ dst->type = src0->type;
612
+ dst->numeric = 1;
613
+
614
+ /* Perform the addition. */
615
+ dst->data_int = value2integer(src0) / value2integer(src1);
616
+ return dst;
617
+ }
618
+
619
+
604
620
  /** Computes the NOT of a bitstring value.
605
621
  * @param src the source value of the not
606
622
  * @param dst the destination value
@@ -1412,6 +1428,22 @@ static Value mul_value_numeric(Value src0, Value src1, Value dst) {
1412
1428
  }
1413
1429
 
1414
1430
 
1431
+ /** Computes the division of two numeric values.
1432
+ * @param src0 the first source value of the addition
1433
+ * @param src1 the second source value of the addition
1434
+ * @param dst the destination value
1435
+ * @return dst */
1436
+ static Value div_value_numeric(Value src0, Value src1, Value dst) {
1437
+ /* Sets state of the destination using the first source. */
1438
+ dst->type = src0->type;
1439
+ dst->numeric = 1;
1440
+
1441
+ /* Perform the addition. */
1442
+ dst->data_int = src0->data_int / src1->data_int;
1443
+ return dst;
1444
+ }
1445
+
1446
+
1415
1447
  /** Computes the NOT of a numeric value.
1416
1448
  * @param src the source value of the not
1417
1449
  * @param dst the destination value
@@ -1833,6 +1865,33 @@ Value mul_value(Value src0, Value src1, Value dst) {
1833
1865
  }
1834
1866
 
1835
1867
 
1868
+ /** Computes the division of two general values.
1869
+ * @param src0 the first source value of the addition
1870
+ * @param src1 the second source value of the addition
1871
+ * @param dst the destination value
1872
+ * @return dst */
1873
+ Value div_value(Value src0, Value src1, Value dst) {
1874
+ /* Might allocate a new value so save the current pool state. */
1875
+ unsigned int pos = get_value_pos();
1876
+ /* Do a numeric computation if possible, otherwise fallback to bitstring
1877
+ * computation. */
1878
+ if (src0->numeric && src1->numeric) {
1879
+ /* Both sources are numeric. */
1880
+ return div_value_numeric(src0,src1,dst);
1881
+ } else if (is_defined_value(src0) && is_defined_value(src1)) {
1882
+ /* Both sources can be converted to numeric values. */
1883
+ return div_value_defined_bitstring(src0,src1,dst);
1884
+ } else {
1885
+ /* Cannot compute (for now), simply undefines the destination. */
1886
+ /* First ensure dst has the right shape. */
1887
+ copy_value(src0,dst);
1888
+ /* Then make it undefined. */
1889
+ set_undefined_bitstring(dst);
1890
+ }
1891
+ return dst;
1892
+ }
1893
+
1894
+
1836
1895
  /** Computes the NOT of a general value.
1837
1896
  * @param src the source value of the not
1838
1897
  * @param dst the destination value
@@ -91,9 +91,10 @@ void register_signal(SignalI signal) {
91
91
  all_signals = calloc(sizeof(SignalI),cap_all_signals);
92
92
  } else {
93
93
  /* Need to increase the capacity. */
94
- Behavior* behaviors = calloc(sizeof(Behavior),cap_all_signals*2);
95
- memcpy(all_signals,behaviors,sizeof(Behavior)*cap_all_signals);
94
+ SignalI* new_signals = calloc(sizeof(SignalI),cap_all_signals*2);
95
+ memcpy(new_signals,all_signals,sizeof(SignalI)*cap_all_signals);
96
96
  cap_all_signals *= 2;
97
+ all_signals=new_signals;
97
98
  }
98
99
  }
99
100
  /* Add the behavior. */
@@ -70,7 +70,8 @@ module HDLRuby::High::Std
70
70
  ## Creates directly an instance of channel named +name+ using
71
71
  # +ruby_block+ built with +args+.
72
72
  def self.channel_instance(name,*args,&ruby_block)
73
- return ChannelT.new(:"",&ruby_block).instantiate(name,*args)
73
+ # return ChannelT.new(:"",&ruby_block).instantiate(name,*args)
74
+ return self.channel(:"",&ruby_block).instantiate(name,*args)
74
75
  end
75
76
 
76
77
  ## Creates directly an instance of channel named +name+ using
@@ -80,9 +81,20 @@ module HDLRuby::High::Std
80
81
  end
81
82
 
82
83
 
84
+ ##
85
+ # Module for boxing channel ports.
86
+ module ChannelPortBoxing
87
+ # Box with +args+ arguments.
88
+ def box(*args)
89
+ return ChannelPortB.new(self,*args)
90
+ end
91
+ end
92
+
93
+
83
94
  ##
84
95
  # Describes a read port to a channel.
85
96
  class ChannelPortR
97
+ include ChannelPortBoxing
86
98
 
87
99
  # Creates a new channel reader running in +namespace+ and
88
100
  # reading using +reader_proc+ and reseting using +reseter_proc+.
@@ -126,6 +138,7 @@ module HDLRuby::High::Std
126
138
  ##
127
139
  # Describes a writer port to a channel.
128
140
  class ChannelPortW
141
+ include ChannelPortBoxing
129
142
 
130
143
  # Creates a new channel writer running in +namespace+ and
131
144
  # writing using +writer_proc+ and reseting using +reseter_proc+.
@@ -166,10 +179,10 @@ module HDLRuby::High::Std
166
179
  end
167
180
 
168
181
 
169
-
170
182
  ##
171
183
  # Describes an access port to a channel.
172
184
  class ChannelPortA
185
+ include ChannelPortBoxing
173
186
 
174
187
  # Creates a new channel accesser running in +namespace+
175
188
  # and reading using +reader_proc+, writing using +writer_proc+,
@@ -228,6 +241,44 @@ module HDLRuby::High::Std
228
241
  end
229
242
 
230
243
 
244
+ ##
245
+ # Describes port box (wrapper) for fixing arugments.
246
+ class ChannelPortB
247
+ include ChannelPortBoxing
248
+
249
+ # Creates a new channel box over channel port +port+ fixing +args+
250
+ # as arguments.
251
+ def initialize(port,*args)
252
+ # Ensure port is a channel port.
253
+ unless port.is_a?(ChannelPortR) || port.is_a?(ChannelPortW) ||
254
+ port.is_a?(ChannelPortA)
255
+ raise "Invalid class for a channel port: #{port.class}"
256
+ end
257
+ @port = port
258
+ @args = args
259
+ end
260
+
261
+ ## Performs a read on the channel using +args+ and +ruby_block+
262
+ # as arguments.
263
+ def read(*args,&ruby_block)
264
+ @port.read(*@args,*args)
265
+ end
266
+
267
+ ## Performs a write on the channel using +args+ and +ruby_block+
268
+ # as arguments.
269
+ def write(*args,&ruby_block)
270
+ @port.write(*@args,*args)
271
+ end
272
+
273
+ ## Performs a reset on the channel using +args+ and +ruby_block+
274
+ # as arguments.
275
+ def reset(*args,&ruby_block)
276
+ @port.reset(*@args,*args)
277
+ end
278
+ end
279
+
280
+
281
+
231
282
  ##
232
283
  # Describes a high-level channel instance.
233
284
  class ChannelI
@@ -520,12 +571,12 @@ module HDLRuby::High::Std
520
571
 
521
572
  # Defines a branch in the channel named +name+ built executing
522
573
  # +ruby_block+.
523
- def brancher(name,*args,&ruby_block)
574
+ def brancher(name,&ruby_block)
524
575
  # Ensure name is a symbol.
525
576
  name = name.to_s unless name.respond_to?(:to_sym)
526
577
  name = name.to_sym
527
578
  # Create the branch.
528
- channelI = HDLRuby::High.channel_instance(name,*args,&ruby_block)
579
+ channelI = HDLRuby::High.channel_instance(name, &ruby_block)
529
580
  @branches[name] = channelI
530
581
  end
531
582
 
@@ -534,7 +585,7 @@ module HDLRuby::High::Std
534
585
 
535
586
  # Gets branch channel +name+.
536
587
  # NOTE: +name+ can be of any type on purpose.
537
- def branch(name)
588
+ def branch(name,*args)
538
589
  # Ensure name is a symbol.
539
590
  name = name.to_s unless name.respond_to?(:to_sym)
540
591
  name = name.to_sym
@@ -0,0 +1,67 @@
1
+ module HDLRuby::High::Std
2
+
3
+ ##
4
+ # Standard HDLRuby::High library: fixed point types.
5
+ #
6
+ ########################################################################
7
+
8
+ # Save the former included.
9
+ class << self
10
+ alias_method :_included_fixpoint, :included
11
+ end
12
+
13
+ # Redefines the include to add fixed point generation through the Type
14
+ # class.
15
+ def self.included(base)
16
+ # Performs the previous included
17
+ res = self.send(:_included_fixpoint,base)
18
+ # Now modify the Type class
19
+ ::HDLRuby::High::Type.class_eval do
20
+ # Saves the former type generation method.
21
+ alias_method :"_[]_fixpoint", :[]
22
+
23
+ # Redefine the type generation method for supporting fixed point
24
+ # type generation.
25
+ def [](*args)
26
+ if args.size == 1 then
27
+ return self.send(:"_[]_fixpoint",*args)
28
+ else
29
+ # Handle the arguments.
30
+ arg0,arg1 = *args
31
+ if arg0.respond_to?(:to_i) then
32
+ arg0 = (arg0.to_i.abs-1)..0
33
+ end
34
+ if arg1.respond_to?(:to_i) then
35
+ arg1 = (arg1.to_i.abs-1)..0
36
+ end
37
+ # Compute the fix point sizes.
38
+ isize = (arg0.first-arg0.last).abs+1
39
+ fsize = (arg1.first-arg1.last).abs+1
40
+ # Build the type.
41
+ case(self.name)
42
+ when :bit
43
+ typ = bit[isize+fsize].typedef(::HDLRuby.uniq_name)
44
+ when :unsigned
45
+ typ = unsigned[isize+fsize].typedef(::HDLRuby.uniq_name)
46
+ when :signed
47
+ typ = signed[isize+fsize].typedef(::HDLRuby.uniq_name)
48
+ else
49
+ raise "Invalid type for generating a fixed point type: #{self.name}"
50
+ end
51
+ # Redefine the multiplication and division for fixed point.
52
+ typ.define_operator(:*) do |left,right|
53
+ (left.as([isize+fsize*2])*right) >> fsize
54
+ end
55
+ typ.define_operator(:/) do |left,right|
56
+ (left.as([isize+fsize*2]) << fsize) / right
57
+ end
58
+ typ
59
+ end
60
+ end
61
+ return res
62
+ end
63
+ end
64
+
65
+
66
+
67
+ end
@@ -71,13 +71,15 @@ HDLRuby::High::Std.channel(:mem_sync) do |n,typ,size,clk_e,rst,br_rsts = []|
71
71
  rwb = send(:"rwb_#{p}")
72
72
  rst = send(rst_name)
73
73
  # Use it to make the access.
74
- hif (rst) do
75
- # Reset case
76
- cs <= 0
77
- abus <= 0
78
- rwb <= 0
74
+ top_block.unshift do
75
+ hif (rst) do
76
+ # Reset case
77
+ cs <= 0
78
+ abus <= 0
79
+ rwb <= 0
80
+ end
79
81
  end
80
- helsif (cs == 0) do
82
+ hif(cs == 0) do
81
83
  # Start the access.
82
84
  cs <= 1
83
85
  rwb <= 1
@@ -101,13 +103,15 @@ HDLRuby::High::Std.channel(:mem_sync) do |n,typ,size,clk_e,rst,br_rsts = []|
101
103
  rwb = send(:"rwb_#{p}")
102
104
  rst = send(rst_name)
103
105
  # Use it to make the access.
104
- hif (rst) do
105
- # Reset case
106
- cs <= 0
107
- abus <= 0
108
- rwb <= 0
106
+ top_block.unshift do
107
+ hif (rst) do
108
+ # Reset case
109
+ cs <= 0
110
+ abus <= 0
111
+ rwb <= 0
112
+ end
109
113
  end
110
- helsif (cs == 0) do
114
+ hif(cs == 0) do
111
115
  # Start the access.
112
116
  cs <= 1
113
117
  rwb <= 0
@@ -119,6 +123,8 @@ HDLRuby::High::Std.channel(:mem_sync) do |n,typ,size,clk_e,rst,br_rsts = []|
119
123
  cs <= 0
120
124
  rwb <= 0
121
125
  dbus <= "z" * typ.width
126
+ # Execute the blk.
127
+ blk.call if blk
122
128
  end
123
129
  end
124
130
  end
@@ -237,20 +243,24 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
237
243
  typ.inner :dbus_r, :dbus_w
238
244
  # Address buses (or simply registers)
239
245
  [awidth].inner :abus_r, :abus_w
240
- # Address buffers
241
- [awidth].inner :abus_r_reg
246
+ # # Address buffers
247
+ # [awidth].inner :abus_r_reg
242
248
 
243
249
  # Declare the memory content.
244
250
  typ[-size].inner :mem
245
251
 
246
- # Processes handling the memory access.
252
+ # # Processes handling the memory access.
247
253
  par(clk.posedge) do
248
- # Output memory value for reading at each cycle.
249
- dbus_r <= mem[abus_r_reg]
254
+ # # # Output memory value for reading at each cycle.
255
+ # # dbus_r <= mem[abus_r_reg]
250
256
  # Manage the write to the memory.
251
257
  hif(trig_w) { mem[abus_w] <= dbus_w }
252
258
  end
253
- par(clk.negedge) { abus_r_reg <= abus_r }
259
+ # par(clk.negedge) { abus_r_reg <= abus_r }
260
+ par(clk.negedge) do
261
+ dbus_r <= mem[abus_r]
262
+ # hif(trig_w) { mem[abus_w] <= dbus_w }
263
+ end
254
264
 
255
265
  # The address branches.
256
266
  # Read with address
@@ -277,11 +287,14 @@ HDLRuby::High::Std.channel(:mem_dual) do |typ,size,clk,rst,br_rsts = {}|
277
287
  hif(trig_r == 1) do
278
288
  # The trigger was previously set, read ok.
279
289
  target <= dbus_r
290
+ trig_r <= 0
280
291
  blk.call if blk
281
292
  end
282
- # Prepare the read.
283
- abus_r <= addr
284
- trig_r <= 1
293
+ helse do
294
+ # Prepare the read.
295
+ abus_r <= addr
296
+ trig_r <= 1
297
+ end
285
298
  end
286
299
  end
287
300
  end
@@ -499,6 +512,23 @@ HDLRuby::High::Std.channel(:mem_file) do |typ,size,clk,rst,br_rsts = {}|
499
512
  blk.call if blk
500
513
  end
501
514
  end
515
+
516
+ # Defines a conversion to array as list of fixed inner accessers.
517
+ define_singleton_method(:inners) do |name|
518
+ # The resulting array.
519
+ chbs = []
520
+ # Declare the fixed inners with uniq names, box them and
521
+ # add the result to the resulting array.
522
+ size.times do |i|
523
+ port = inner HDLRuby.uniq_name
524
+ chbs << port.box(i)
525
+ end
526
+ # Register the array as name.
527
+ HDLRuby::High.space_reg(name) { chbs }
528
+ # Return it.
529
+ return chbs
530
+ end
531
+
502
532
  end
503
533
 
504
534
 
@@ -1,3 +1,3 @@
1
1
  module HDLRuby
2
- VERSION = "2.2.12"
2
+ VERSION = "2.2.13"
3
3
  end
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.2.12
4
+ version: 2.2.13
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-03-20 00:00:00.000000000 Z
11
+ date: 2020-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -115,6 +115,7 @@ files:
115
115
  - lib/HDLRuby/hdr_samples/with_channel.rb
116
116
  - lib/HDLRuby/hdr_samples/with_class.rb
117
117
  - lib/HDLRuby/hdr_samples/with_decoder.rb
118
+ - lib/HDLRuby/hdr_samples/with_fixpoint.rb
118
119
  - lib/HDLRuby/hdr_samples/with_fsm.rb
119
120
  - lib/HDLRuby/hdr_samples/with_memory.rb
120
121
  - lib/HDLRuby/hdr_samples/with_reconf.rb
@@ -262,6 +263,7 @@ files:
262
263
  - lib/HDLRuby/std/clocks.rb
263
264
  - lib/HDLRuby/std/counters.rb
264
265
  - lib/HDLRuby/std/decoder.rb
266
+ - lib/HDLRuby/std/fixpoint.rb
265
267
  - lib/HDLRuby/std/fsm.rb
266
268
  - lib/HDLRuby/std/memory.rb
267
269
  - lib/HDLRuby/std/pipeline.rb